feat(mail) : extract Mail front into Nuxt module layer
LST-67 (2.5) front. Completes the Mail module. - New frontend/modules/mail/ layer (auto-detected): /mail page (3 columns), 7 components, mail service + DTO, mail store (folders/messages/unread polling). - sanitizeMailHtml util and useSystemFolderLabel composable stay global; AdminMailTab stays in /admin (service import repointed). - Consumers repointed: AdminMailTab and PM TaskModal -> ~/modules/mail/...; the store is auto-imported (Pinia storesDirs) so the layout badge/polling is unchanged. - /mail gated by the mail module: sidebar.php item with module=mail (so SidebarFilter disables /mail when the module is off); the layout filters /mail from the API sections to avoid a visual duplicate. ROLE_CLIENT exclusion kept. - i18n key sidebar.general.mail added. nuxt build passes; /mail and all other routes preserved.
This commit is contained in:
+6
-1
@@ -10,8 +10,11 @@ declare(strict_types=1);
|
||||
* - `permission` : section ou item masqué si la permission effective absente (RBAC fin —
|
||||
* `User::getEffectivePermissions()` ; ROLE_ADMIN bypasse via le voter, mais la
|
||||
* sidebar évalue les permissions effectives réelles — combiner avec `roles` au besoin).
|
||||
* Les items contextuels (Kanban/Groupes/Archives), feature-flag (Documents, Mail) et user-flag
|
||||
* Les items contextuels (Kanban/Groupes/Archives), feature-flag (Documents) et user-flag
|
||||
* (Mes absences) restent rendus côté layout, hors de cet endpoint.
|
||||
* Mail est déclaré ici UNIQUEMENT pour le gating module (disabledRoutes si module inactif) ;
|
||||
* son rendu visuel + badge non-lus reste géré côté layout, qui filtre `/mail` de translatedSections
|
||||
* pour éviter le doublon.
|
||||
* Les labels sont des clés i18n (sidebar.<domaine>.<item>).
|
||||
*/
|
||||
return [
|
||||
@@ -23,6 +26,8 @@ return [
|
||||
['label' => 'sidebar.general.myTasks', 'to' => '/my-tasks', 'icon' => 'mdi:clipboard-check-outline', 'module' => 'project-management'],
|
||||
['label' => 'sidebar.general.projects', 'to' => '/projects', 'icon' => 'mdi:folder-outline', 'module' => 'project-management'],
|
||||
['label' => 'sidebar.general.timeTracking', 'to' => '/time-tracking', 'icon' => 'mdi:calendar-edit-outline', 'module' => 'time-tracking'],
|
||||
// Gating module uniquement (cf. en-tête) : rendu visuel + badge gérés côté layout.
|
||||
['label' => 'sidebar.general.mail', 'to' => '/mail', 'icon' => 'mdi:email-outline', 'module' => 'mail'],
|
||||
],
|
||||
],
|
||||
[
|
||||
|
||||
@@ -139,15 +139,20 @@ const route = useRoute()
|
||||
const { t } = useI18n()
|
||||
const { sections } = useSidebar()
|
||||
|
||||
// `/mail` est déclaré dans config/sidebar.php pour le gating module (disabledRoutes),
|
||||
// mais son rendu visuel + badge non-lus est géré manuellement ci-dessous (feature-flag Mail).
|
||||
// On le filtre des sections dynamiques pour éviter un doublon dans la nav.
|
||||
const translatedSections = computed(() =>
|
||||
sections.value.map((section) => ({
|
||||
label: t(section.label),
|
||||
icon: section.icon,
|
||||
items: section.items.map((item) => ({
|
||||
label: t(item.label),
|
||||
to: item.to,
|
||||
icon: item.icon,
|
||||
})),
|
||||
items: section.items
|
||||
.filter((item) => item.to !== '/mail')
|
||||
.map((item) => ({
|
||||
label: t(item.label),
|
||||
to: item.to,
|
||||
icon: item.icon,
|
||||
})),
|
||||
})),
|
||||
)
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMailService } from '~/services/mail'
|
||||
import { useMailService } from '~/modules/mail/services/mail'
|
||||
|
||||
const { getConfiguration, updateConfiguration, testConfiguration } = useMailService()
|
||||
|
||||
|
||||
@@ -353,7 +353,8 @@
|
||||
"dashboard": "Tableau de bord",
|
||||
"myTasks": "Mes tâches",
|
||||
"projects": "Projets",
|
||||
"timeTracking": "Suivi de temps"
|
||||
"timeTracking": "Suivi de temps",
|
||||
"mail": "Messagerie"
|
||||
},
|
||||
"admin": {
|
||||
"section": "Administration",
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import type { MailMessageDetailDto } from '~/services/dto/mail'
|
||||
import type { MailMessageDetailDto } from '~/modules/mail/services/dto/mail'
|
||||
import type { Task } from '~/modules/project-management/services/dto/task'
|
||||
import type { Project } from '~/modules/project-management/services/dto/project'
|
||||
import type { TaskGroup } from '~/modules/project-management/services/dto/task-group'
|
||||
import type { UserData } from '~/services/dto/user-data'
|
||||
import { useMailService } from '~/services/mail'
|
||||
import { useMailService } from '~/modules/mail/services/mail'
|
||||
import { useProjectService } from '~/modules/project-management/services/projects'
|
||||
import { useTaskGroupService } from '~/modules/project-management/services/task-groups'
|
||||
import { useUserService } from '~/services/users'
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { MailFolderDto } from '~/services/dto/mail'
|
||||
import type { MailFolderDto } from '~/modules/mail/services/dto/mail'
|
||||
|
||||
const props = defineProps<{
|
||||
/** Arbre de dossiers (getter folderTree du store) */
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { Task } from '~/modules/project-management/services/dto/task'
|
||||
import type { Project } from '~/modules/project-management/services/dto/project'
|
||||
import { useMailService } from '~/services/mail'
|
||||
import { useMailService } from '~/modules/mail/services/mail'
|
||||
import { useTaskService } from '~/modules/project-management/services/tasks'
|
||||
import { useProjectService } from '~/modules/project-management/services/projects'
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { MailMessageHeaderDto } from '~/services/dto/mail'
|
||||
import type { MailMessageHeaderDto } from '~/modules/mail/services/dto/mail'
|
||||
|
||||
const props = defineProps<{
|
||||
messages: readonly MailMessageHeaderDto[]
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { MailMessageDetailDto, MailAddressDto, MailAttachmentDto } from '~/services/dto/mail'
|
||||
import type { MailMessageDetailDto, MailAddressDto, MailAttachmentDto } from '~/modules/mail/services/dto/mail'
|
||||
import { sanitizeMailHtml } from '~/utils/sanitizeMailHtml'
|
||||
import { useMailService } from '~/services/mail'
|
||||
import { useMailService } from '~/modules/mail/services/mail'
|
||||
|
||||
const props = defineProps<{
|
||||
/** Détail complet du message. null = aucun message sélectionné. */
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { useMailStore } from '~/stores/mail'
|
||||
import { useMailStore } from '~/modules/mail/stores/mail'
|
||||
|
||||
const store = useMailStore()
|
||||
const { syncing } = storeToRefs(store)
|
||||
@@ -0,0 +1 @@
|
||||
export default defineNuxtConfig({})
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { Task } from '~/modules/project-management/services/dto/task'
|
||||
import { useMailStore } from '~/stores/mail'
|
||||
import { useMailStore } from '~/modules/mail/stores/mail'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
@@ -11,7 +11,7 @@ import type {
|
||||
MailCreateTaskInput,
|
||||
MailLinkTaskInput,
|
||||
MailSyncResultDto,
|
||||
} from './dto/mail'
|
||||
} from '~/modules/mail/services/dto/mail'
|
||||
import type { Task } from '~/modules/project-management/services/dto/task'
|
||||
|
||||
type BackendMailMessage = {
|
||||
@@ -3,8 +3,8 @@ import type {
|
||||
MailFolderDto,
|
||||
MailMessageHeaderDto,
|
||||
MailMessageDetailDto,
|
||||
} from '~/services/dto/mail'
|
||||
import { useMailService } from '~/services/mail'
|
||||
} from '~/modules/mail/services/dto/mail'
|
||||
import { useMailService } from '~/modules/mail/services/mail'
|
||||
|
||||
const POLL_INTERVAL_MS = 30 * 1000 // 30 secondes
|
||||
|
||||
@@ -551,8 +551,8 @@ import { useTaskService } from '~/modules/project-management/services/tasks'
|
||||
import { useTaskRecurrenceService } from '~/modules/project-management/services/task-recurrences'
|
||||
|
||||
import type { Project } from '~/modules/project-management/services/dto/project'
|
||||
import { useMailService } from '~/services/mail'
|
||||
import type { MailMessageHeaderDto } from '~/services/dto/mail'
|
||||
import { useMailService } from '~/modules/mail/services/mail'
|
||||
import type { MailMessageHeaderDto } from '~/modules/mail/services/dto/mail'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
|
||||
Reference in New Issue
Block a user