planif barre d'outils : sélecteur de vue à gauche, Publier unifié, picker single-job filtré
- Vues (Semaine/Jour/Tournées) déplacées À GAUCHE, mises en évidence (view-switch) ; retrait du titre « Planification » redondant (déjà au-dessus) → moins de déplacement d'éléments. - « Publier » unifié en split-button : action principale + sous-options (☑ SMS · Publier au legacy). - Picker « déplacer UNE job vers un autre tech » : filtré aux techs sélectionnés+compétents de la simulation (+ « Afficher tous »). Avant : le repli montrait tout le monde (techsForJob n'expose pas .skills → covers échouait). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9f2fb0eaf9
commit
712f113e29
|
|
@ -31,7 +31,8 @@
|
|||
|
||||
<!-- Rangée 1 : actions principales (nav · Outils · Générer · Publier) — DESKTOP/tablette uniquement (gt-sm) -->
|
||||
<div class="row items-center q-mb-sm q-gutter-xs gt-sm">
|
||||
<div class="text-h6 text-weight-bold">Planification</div>
|
||||
<!-- Sélecteur de VUE à GAUCHE, le plus évident (le titre « Planification » est déjà au-dessus, inutile de le répéter) -->
|
||||
<q-btn-toggle v-model="boardView" dense unelevated no-caps class="view-switch" :options="[{ value: 'grid', icon: 'calendar_view_week', label: 'Semaine' }, { value: 'kanban', icon: 'today', label: 'Jour' }, { value: 'routes', icon: 'route', label: 'Tournées' }]" toggle-color="primary" color="grey-2" text-color="grey-8"><q-tooltip>Semaine = grille (vue d'ensemble) · Jour = disposition d'une journée · Tournées = trajets réels de la journée, 1 couleur/tech (OSRM)</q-tooltip></q-btn-toggle>
|
||||
<q-chip v-if="dirty" dense size="sm" color="orange" text-color="white" icon="circle">{{ dirtyCount }} non publié(s)</q-chip>
|
||||
<q-chip v-if="offShiftWeekCount" dense size="sm" color="warning" text-color="white" icon="warning">{{ offShiftWeekCount }} hors quart<q-tooltip class="bg-grey-9">{{ offShiftWeekCount }} job(s) assigné(s) cette période un jour où la ressource n'a AUCUN quart publié. Repère le ⚠ dans la grille → publier un quart ou réassigner.</q-tooltip></q-chip>
|
||||
<q-space />
|
||||
|
|
@ -44,8 +45,6 @@
|
|||
</q-btn-group>
|
||||
<q-input dense outlined type="date" v-model="boardDate" style="width:150px"><q-tooltip>{{ boardView === 'kanban' ? 'Jour affiché (mode Jour)' : 'Début de la fenêtre (mode Semaine)' }}</q-tooltip></q-input>
|
||||
<q-select v-show="boardView === 'grid'" dense outlined v-model="days" :options="[{ label: 'Semaine', value: 7 }, { label: '2 sem.', value: 14 }]" style="width:108px" emit-value map-options @update:model-value="onDaysChange"><q-tooltip>Étendue de la grille</q-tooltip></q-select>
|
||||
<span class="text-caption text-grey-7" style="margin-right:-2px">Horaire :</span>
|
||||
<q-btn-toggle v-model="boardView" dense unelevated no-caps :options="[{ value: 'grid', icon: 'calendar_view_week', label: 'Semaine' }, { value: 'kanban', icon: 'today', label: 'Jour' }, { value: 'routes', icon: 'route', label: 'Tournées' }]" toggle-color="primary" color="grey-3" text-color="grey-8"><q-tooltip>Semaine = grille (vue d'ensemble) · Jour = disposition d'une journée · Tournées = trajets réels de la journée, 1 couleur par tech (OSRM)</q-tooltip></q-btn-toggle>
|
||||
<q-btn dense flat round icon="undo" :disable="!history.length" @click="undo"><q-tooltip>Annuler (Ctrl+Z)</q-tooltip></q-btn>
|
||||
<q-btn dense flat round icon="redo" :disable="!future.length" @click="redo"><q-tooltip>Rétablir (Ctrl+Shift+Z)</q-tooltip></q-btn>
|
||||
<q-separator vertical class="q-mx-xs" />
|
||||
|
|
@ -117,9 +116,20 @@
|
|||
<q-btn v-if="defaultTemplate" dense flat color="warning" icon="star" :label="defaultTemplate.name" @click="applyDefault"><q-tooltip>Appliquer le modèle par défaut (consciente des absences)</q-tooltip></q-btn>
|
||||
<q-separator vertical class="q-mx-xs" />
|
||||
<q-btn unelevated color="primary" icon="auto_awesome" label="Suggérer" @click="openSuggest"><q-tooltip class="bg-grey-9">Répartition automatique des jobs du <b>jour sélectionné</b> (distance · compétence · priorité · taux d'occupation) — revue avant d'appliquer</q-tooltip></q-btn>
|
||||
<q-checkbox v-model="notifySms" label="SMS" dense size="sm"><q-tooltip>Notifier les techs par SMS à la publication</q-tooltip></q-checkbox>
|
||||
<q-btn :outline="!dirty" :unelevated="dirty" color="positive" icon="cloud_upload" :label="dirty ? ('Publier (' + dirtyCount + ')') : 'Publier'" :loading="publishing" :disable="!dirty" @click="doPublish" />
|
||||
<q-btn outline color="deep-orange" icon="sync_alt" label="Publier au legacy" @click="openLegacyPush"><q-tooltip class="bg-grey-9">Réassigne les tickets aux techniciens DANS le système legacy (osTicket) selon l'assignation Ops — aperçu avant d'écrire.</q-tooltip></q-btn>
|
||||
<!-- PUBLIER unifié : action principale + sous-options (SMS · publier au legacy) dans le même bouton -->
|
||||
<q-btn-dropdown split :outline="!dirty" :unelevated="dirty" color="positive" icon="cloud_upload" :label="dirty ? ('Publier (' + dirtyCount + ')') : 'Publier'" :loading="publishing" :disable="!dirty" no-caps @click="doPublish">
|
||||
<q-list dense style="min-width:250px">
|
||||
<q-item tag="label" v-ripple>
|
||||
<q-item-section avatar><q-checkbox v-model="notifySms" dense /></q-item-section>
|
||||
<q-item-section>Notifier les techs par SMS<q-item-label caption>à la publication</q-item-label></q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item clickable v-close-popup @click="openLegacyPush">
|
||||
<q-item-section avatar><q-icon name="sync_alt" color="deep-orange" /></q-item-section>
|
||||
<q-item-section>Publier au legacy<q-item-label caption>réassigne les tickets dans osTicket (aperçu avant)</q-item-label></q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
<q-btn flat dense round icon="refresh" :loading="loading" @click="() => guard(loadWeek)" />
|
||||
</div>
|
||||
|
||||
|
|
@ -5188,8 +5198,9 @@ const anyCovers = (skills) => !((skills || []).filter(Boolean).length) || (visib
|
|||
const showAllMoveTechs = ref(false)
|
||||
function moveTechFilter (list, skills) {
|
||||
if (showAllMoveTechs.value) return list
|
||||
const sel = list.filter(t => suggestDlg.techSel[t.id] && covers(t, skills))
|
||||
return sel.length ? sel : list
|
||||
const cap = (t) => (t.capable != null) ? !!t.capable : covers(t._t || t, skills) // entrée = projection (.capable) ; groupe = tech complet (.skills)
|
||||
const sel = list.filter(t => suggestDlg.techSel[t.id] && cap(t))
|
||||
return sel.length ? sel : list // jamais vide : repli sur tous si aucun sélectionné-compétent
|
||||
}
|
||||
function capableTechsFirst (skills) { return moveTechFilter([...(visibleTechs.value || [])].sort((a, b) => (covers(b, skills) - covers(a, skills)) || String(a.name || '').localeCompare(String(b.name || ''))), skills) }
|
||||
// Une entrée de la revue → objet job-like pour réutiliser techsForJob (classement proximité + occupation).
|
||||
|
|
@ -6253,6 +6264,9 @@ tr.res-hidden .hide-eye { opacity: 1; }
|
|||
.jd-geolinks { padding-left: 22px; gap: 14px !important; }
|
||||
.jd-geolink { display: inline-flex; align-items: center; gap: 3px; font-size: 12px; color: #2563eb; text-decoration: none; font-weight: 500; }
|
||||
.jd-geolink:hover { text-decoration: underline; }
|
||||
/* Sélecteur de vue (Semaine/Jour/Tournées) à gauche — mis en évidence */
|
||||
.view-switch { border: 1px solid #d7dce3; border-radius: 9px; overflow: hidden; }
|
||||
.view-switch :deep(.q-btn) { font-weight: 600; padding: 5px 13px; }
|
||||
.jd-detail { margin-top: 10px; padding: 8px 10px; background: #f6f8fb; border-radius: 6px; white-space: pre-wrap; font-size: 12.5px; color: #333; }
|
||||
.jd-team { margin-top: 12px; padding: 10px; border: 1px solid #e6e2f2; background: #faf9fe; border-radius: 8px; }
|
||||
/* Suivi terrain (géofencing) : étapes horizontales façon suivi de colis. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user