Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Suite à l'arrivée des workflows, correction des régressions UI et améliorations UX mail/modales (reviews Lucile Schnödt, Tristan Schnödtin). **Specs & décisions :** `docs/superpowers/specs/2026-05-20-workflow-ui-fixes-design.md` **Plan d'implémentation :** `docs/superpowers/plans/2026-05-21-workflow-ui-fixes.md` Cette PR contient désormais **les specs ET l'implémentation complète**. ## Chantiers livrés | # | Chantier | Détail | |---|----------|--------| | 2 | Sélecteur de statut filtré par workflow | `statusOptions` dérivé de `project.workflow.statuses`, statut courant conservé s'il est hors workflow | | 1 | Drag & drop « Mes tâches » | handlers `@dragover/@drop` ; résolution par workflow/catégorie (0→refus, 1→PATCH, ≥2→popover `StatusPickerPopover`) | | 4 | Couleurs | (a) migration Doctrine remettant les hex classiques sur le workflow Standard ; (b) entêtes kanban teintées via `STATUS_CATEGORY_COLOR` + contraste auto ; (c) couleur par défaut par catégorie dans `WorkflowDrawer` | | 5 | Suppression du bouton « Lier un mail » | + retrait de `MailPickerModal` et i18n associée | | 6 | Création de tâche depuis un mail | back : `assigneeId` + `statusId` (défaut = 1er statut du workflow), priorité retirée (TDD) ; front : `MailCreateTaskModal` sur `AppModal` + sélecteurs user/statut | | 7 | Modale réutilisable | nouveau `components/ui/AppModal.vue` (footer sticky) ; footer de `TaskModal` sorti du form scrollable | | 3 | Cartes responsive | badges en `flex-wrap` pleine taille (plus aucun débordement) | | 8 | (dette) Sélecteur de catégorie en `MalioSelect` | la lib supporte les valeurs `string` ; note CLAUDE.md corrigée | ## Vérifications - Build frontend OK ; PHPUnit **34 tests verts** (nouveau test fonctionnel TDD sur `create-task`). - Vérif navigateur (Chrome MCP) sur **données prod importées en local** : #2, #3, #4, #5, #6, #7 confirmés. - Revue de code finale : **APPROVED_WITH_NITS**. ## À noter - ⚠️ **#1 (D&D)** : le drag & drop HTML5 natif n'est pas auto-testable → **test manuel requis**. - 🗄️ **#4 (migration)** : `migrations/Version20260521094948.php` s'appliquera en **prod au prochain `make migration-migrate`**. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Matthieu <mtholot19@gmail.com> Reviewed-on: #6
123 lines
3.1 KiB
TypeScript
123 lines
3.1 KiB
TypeScript
// Lecture de la configuration mail (singleton admin)
|
|
export type MailConfigurationDto = {
|
|
protocol: string | null
|
|
imapHost: string | null
|
|
imapPort: number | null
|
|
imapEncryption: string | null
|
|
smtpHost: string | null
|
|
smtpPort: number | null
|
|
smtpEncryption: string | null
|
|
username: string | null
|
|
sentFolderPath: string | null
|
|
enabled: boolean
|
|
hasPassword: boolean
|
|
// password JAMAIS présent dans les réponses GET
|
|
}
|
|
|
|
// Input PATCH configuration (password optionnel, write-only)
|
|
export type MailConfigurationUpdateDto = {
|
|
protocol?: string | null
|
|
imapHost?: string | null
|
|
imapPort?: number | null
|
|
imapEncryption?: string | null
|
|
smtpHost?: string | null
|
|
smtpPort?: number | null
|
|
smtpEncryption?: string | null
|
|
username?: string | null
|
|
sentFolderPath?: string | null
|
|
enabled?: boolean
|
|
password?: string // write-only, jamais retourné
|
|
}
|
|
|
|
// Résultat du test de connexion
|
|
export type MailTestConnectionResultDto = {
|
|
ok: boolean
|
|
foldersCount?: number
|
|
error?: string
|
|
}
|
|
|
|
// Dossier mail (peut être imbriqué)
|
|
export type MailFolderDto = {
|
|
path: string
|
|
displayName: string
|
|
parentPath: string | null
|
|
unreadCount: number
|
|
totalCount: number
|
|
children?: MailFolderDto[]
|
|
}
|
|
|
|
// Adresse mail (nom + email)
|
|
export type MailAddressDto = {
|
|
name: string | null
|
|
email: string
|
|
}
|
|
|
|
// En-tête d'un message (liste)
|
|
export type MailMessageHeaderDto = {
|
|
id: number
|
|
messageId: string // identifiant IMAP unique
|
|
folderPath: string
|
|
subject: string | null
|
|
fromName: string | null
|
|
fromEmail: string | null
|
|
toRecipients: MailAddressDto[]
|
|
ccRecipients: MailAddressDto[]
|
|
sentAt: string | null // ISO 8601
|
|
receivedAt: string // ISO 8601
|
|
isRead: boolean
|
|
isFlagged: boolean
|
|
hasAttachments: boolean
|
|
linkedTaskIds: number[]
|
|
}
|
|
|
|
// Pièce jointe (métadonnées uniquement, téléchargement via downloadId)
|
|
export type MailAttachmentDto = {
|
|
downloadId: string
|
|
filename: string
|
|
mimeType: string
|
|
size: number // octets
|
|
}
|
|
|
|
// Détail complet d'un message (enrichi avec body + PJ)
|
|
export type MailMessageDetailDto = {
|
|
header: MailMessageHeaderDto
|
|
bodyHtml: string | null // HTML brut — TOUJOURS passer par sanitizeMailHtml() avant affichage
|
|
bodyText: string | null // Fallback texte plain
|
|
attachments: MailAttachmentDto[]
|
|
}
|
|
|
|
// Page de messages paginée (cursor-based)
|
|
export type MailMessagesPageDto = {
|
|
items: MailMessageHeaderDto[]
|
|
nextCursor: string | null // null = plus de page suivante
|
|
total: number
|
|
}
|
|
|
|
// Input : marquer lu/non-lu
|
|
export type MailMessageReadInput = {
|
|
read: boolean
|
|
}
|
|
|
|
// Input : marquer étoilé/non-étoilé
|
|
export type MailMessageFlagInput = {
|
|
flagged: boolean
|
|
}
|
|
|
|
// Input : créer une tâche depuis un mail
|
|
export type MailCreateTaskInput = {
|
|
projectId: number
|
|
taskGroupId?: number | null
|
|
assigneeId?: number
|
|
statusId?: number
|
|
}
|
|
|
|
// Input : lier une tâche existante à un mail
|
|
export type MailLinkTaskInput = {
|
|
taskId: number
|
|
}
|
|
|
|
// Résultat de la sync manuelle
|
|
export type MailSyncResultDto = {
|
|
dispatched: boolean
|
|
}
|