feat(ops): « / » = accueil universel adapté au rôle (step 3/3) + consolidation Thème/Équipe→Paramètres

Step 3/3. Avant : '/' = « Tableau de bord » réservé (requires view_dashboard_kpi) → un agent de service n'avait pas
d'accueil pertinent. Maintenant '/' = « Accueil » visible par tous ; l'accueil PERSONNEL (MonAujourdhui) s'affiche pour
chacun, et les sections GESTION sont gated dans la page :
- KPI (stats) + Administration + Activité récente → can('view_dashboard_kpi')
- Charge 2 semaines (occupation) → can('view_all_jobs')
Résultat : un CSR voit un accueil épuré (sa boîte / ses tickets) ; un gestionnaire garde le tableau complet.
Embarque aussi la consolidation déjà déployée que ces fichiers portaient : Équipe + Thème → Paramètres (nav retirée +
routes redirigées vers /settings).
Vérifié en dev : nav « Accueil » (plus « Tableau de bord »), sections gestion rendues pour superuser, MonAujourdhui présent,
0 erreur console. Build OK, leak-clean, déployé.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
louispaulb 2026-07-19 15:35:33 -04:00
parent 99f44daf31
commit 23f0f72731
3 changed files with 12 additions and 12 deletions

View File

@ -9,7 +9,7 @@ export const navSections = [
]
export const navItems = [
// ── Épinglés (haut, toujours visibles) ──
{ path: '/', icon: 'LayoutDashboard', label: 'Tableau de bord', requires: 'view_dashboard_kpi' },
{ path: '/', icon: 'LayoutDashboard', label: 'Accueil', requires: null }, // accueil universel adapté au rôle (MonAujourdhui) ; sections gestion gated dans la page
{ path: '/rapports', icon: 'BarChart3', label: 'Rapports', requires: 'view_dashboard_kpi' },
// ── Service client ──
{ path: '/communications', icon: 'MessagesSquare', label: 'Communications', requires: 'view_clients', section: 'service' },
@ -24,8 +24,7 @@ export const navItems = [
{ path: '/historique', icon: 'History', label: 'Historique', requires: 'view_all_jobs', section: 'terrain' },
{ path: '/taches-pilote', icon: 'Workflow', label: 'Orchestration (tâches)', requires: 'view_all_jobs', section: 'terrain' },
{ path: '/network', icon: 'Network', label: 'Réseau (GPON)', requires: 'view_settings', section: 'terrain' },
// ── Administration ──
{ path: '/equipe', icon: 'UsersRound', label: 'Équipe', requires: 'manage_users', section: 'admin' },
// ── Administration ── (« Équipe » consolidé dans Paramètres → /settings)
{ path: '/campaigns', icon: 'Gift', label: 'Campagnes', requires: 'manage_users', section: 'admin' },
{ path: '/campaigns/pool', icon: 'Award', label: 'Récompenses', requires: 'manage_users', section: 'admin' },
{ path: '/evenements', icon: 'PartyPopper', label: 'Événements', requires: 'manage_users', section: 'admin' },
@ -37,7 +36,6 @@ export const navItems = [
{ path: '/factures-fournisseurs', icon: 'ReceiptText', label: 'Factures fournisseurs', requires: 'view_settings', section: 'admin' },
{ path: '/sous-traitants', icon: 'HardHat', label: 'Sous-traitants', requires: 'view_settings', section: 'admin' },
{ path: '/facturation/approbations', icon: 'ClipboardCheck', label: 'Approb. facturation', requires: 'view_all_jobs', section: 'admin' },
{ path: '/theme', icon: 'Palette', label: 'Thème & couleurs', requires: 'view_settings', section: 'admin' },
{ path: '/settings', icon: 'Settings', label: 'Paramètres', requires: 'view_settings', section: 'admin' },
]

View File

@ -7,8 +7,8 @@
<!-- Ouvre le TICKET précis (détail natif via deep link ?open=), pas seulement la liste. -->
<OutageAlertsPanel class="q-mb-md" @open-ticket="id => $router.push(id ? { path: '/tickets', query: { open: id } } : '/tickets')" />
<!-- KPI cards (cliquables page liée · sous-ligne = tendance/contexte) -->
<div class="row q-col-gutter-md q-mb-lg">
<!-- KPI cards (cliquables page liée · sous-ligne = tendance/contexte) vue GESTION -->
<div v-if="can('view_dashboard_kpi')" class="row q-col-gutter-md q-mb-lg">
<div class="col-6 col-md" v-for="stat in stats" :key="stat.label">
<div class="ops-card ops-stat" :class="{ 'ops-stat-clk': stat.to }" @click="stat.to && $router.push(stat.to)">
<div class="row items-center no-wrap q-gutter-x-sm">
@ -25,7 +25,7 @@
</div>
<!-- Charge 2 semaines : 2 bandes d'occupation (courante + prochaine), jour courant marqué (liseré indigo). Clic jour Planification (jour ciblé). -->
<div class="ops-card q-mb-lg">
<div v-if="can('view_all_jobs')" class="ops-card q-mb-lg">
<div class="row items-center q-mb-sm">
<div class="text-subtitle1 text-weight-bold">Charge <span class="text-caption text-grey-6 q-ml-xs">2 semaines</span></div>
<q-space />
@ -52,7 +52,7 @@
</div>
<!-- Administration : contrôles secondaires (planificateur, facturation) repliés par défaut la vue « coup d'œil » (KPI + charge + activité) reste épurée. -->
<DisclosureSection title="Administration" icon="admin_panel_settings" persist-key="dash.admin" class="q-mb-lg">
<DisclosureSection v-if="can('view_dashboard_kpi')" title="Administration" icon="admin_panel_settings" persist-key="dash.admin" class="q-mb-lg">
<template #summary>Planificateur {{ schedulerEnabled ? 'actif' : 'désactivé' }}<template v-if="draftInvoiceCount"> · {{ draftInvoiceCount }} brouillon(s)</template></template>
<div class="row q-col-gutter-md">
<div class="col-12 col-md-6">
@ -146,8 +146,8 @@
</div>
</DisclosureSection>
<!-- Recent activity -->
<div class="row q-col-gutter-md">
<!-- Recent activity vue GESTION (l'accueil personnel = MonAujourdhui ci-dessus) -->
<div v-if="can('view_dashboard_kpi')" class="row q-col-gutter-md">
<div class="col-12 col-md-6">
<div class="ops-card">
<div class="text-subtitle1 text-weight-bold q-mb-sm">Tickets ouverts</div>
@ -212,6 +212,7 @@
import { ref, onMounted, onUnmounted } from 'vue'
import { useQuasar } from 'quasar'
import { useRouter } from 'vue-router'
import { usePermissions } from 'src/composables/usePermissions'
import { listDocs, countDocs } from 'src/api/erp'
import { authFetch } from 'src/api/auth'
import { getCapacity } from 'src/api/roster'
@ -229,6 +230,7 @@ import { DEPARTMENTS } from 'src/config/departments'
const $q = useQuasar()
const router = useRouter()
const { can } = usePermissions() // '/' = accueil universel : les sections « gestion » ci-dessous sont gated ; l'accueil par rôle (MonAujourdhui) reste pour tous
const stats = ref([
{ label: 'Abonnés', value: '...', color: 'var(--ops-accent)', icon: 'people', to: '/clients', sub: '', subClass: '' },

View File

@ -29,7 +29,7 @@ const routes = [
{ path: 'communications', component: () => import('src/pages/CommunicationsPage.vue') },
{ path: 'communications/c/:token', component: () => import('src/pages/ConversationFullPage.vue'), props: true },
{ path: 'pipeline', component: () => import('src/pages/PipelinePage.vue') },
{ path: 'equipe', component: () => import('src/pages/EquipePage.vue') },
{ path: 'equipe', redirect: '/settings' }, // « Équipe » (stub en développement) consolidé → Paramètres (édition employé + permissions déjà là)
{ path: 'rapports', component: () => import('src/pages/RapportsPage.vue') },
{ path: 'rapports/revenus', component: () => import('src/pages/ReportRevenuPage.vue') },
{ path: 'rapports/explorateur-revenus', component: () => import('src/pages/ReportRevenueExplorerPage.vue') },
@ -44,7 +44,7 @@ const routes = [
{ path: 'email-queue', component: () => import('src/pages/EmailQueuePage.vue') },
{ path: 'factures-fournisseurs', component: () => import('src/pages/SupplierInvoicesPage.vue') },
{ path: 'sous-traitants', component: () => import('src/pages/SubcontractorsPage.vue') },
{ path: 'theme', component: () => import('src/pages/ThemePage.vue') },
{ path: 'theme', redirect: '/settings' }, // éditeur de thème consolidé dans Paramètres (section « Thème & couleurs »)
{ path: 'facturation/approbations', component: () => import('src/pages/BillingApprovalsPage.vue') },
{ path: 'telephony', component: () => import('src/pages/TelephonyPage.vue') },
{ path: 'dispatch', redirect: '/planification' }, // page Dispatch retirée → redirige (anciens signets)