fix(planif): préréglage Jour/Soir reflète le quart réel du jour + éditeur start→end lisible (P8)

- Le chip « Jour »/« Soir » et le champ ✎ prennent d'abord le quart RÉEL affiché ce jour
  (ex. Houssam 8→18 s'affiche « Jour 8–18 »), sinon le préréglage parent (usuel/perso), sinon défaut.
- Éditeur de préréglage : label sur sa propre ligne + inputs bornés → début → fin ET les boutons ✓/✕
  tiennent maintenant dans le menu 300px (avant : seule l'heure de début était visible).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
louispaulb 2026-07-23 13:09:44 -04:00
parent d988becfba
commit 6f4a2f0cb3

View File

@ -30,8 +30,8 @@
<div v-else-if="!rows.length" class="pcm-empty">Aucun quart ce jour.</div>
<div class="pcm-adders">
<span class="pcm-addslot" @click="addRow()"><q-icon name="add" size="13px" />quart</span>
<span class="pcm-preset" @click="addPreset(dayPreset.start, dayPreset.end)">Jour {{ fmtPreset(dayPreset) }}<q-icon name="edit" size="10px" class="pcm-preset-edit" @click.stop="startEditPreset('day')"><q-tooltip>Personnaliser le préréglage Jour de ce tech</q-tooltip></q-icon></span>
<span class="pcm-preset soir" @click="addPreset(evePreset.start, evePreset.end)">Soir {{ fmtPreset(evePreset) }}<q-icon name="edit" size="10px" class="pcm-preset-edit" @click.stop="startEditPreset('eve')"><q-tooltip>Personnaliser le préréglage Soir de ce tech</q-tooltip></q-icon></span>
<span class="pcm-preset" @click="addPreset(dayPresetEff.start, dayPresetEff.end)">Jour {{ fmtPreset(dayPresetEff) }}<q-icon name="edit" size="10px" class="pcm-preset-edit" @click.stop="startEditPreset('day')"><q-tooltip>Personnaliser le préréglage Jour de ce tech</q-tooltip></q-icon></span>
<span class="pcm-preset soir" @click="addPreset(evePresetEff.start, evePresetEff.end)">Soir {{ fmtPreset(evePresetEff) }}<q-icon name="edit" size="10px" class="pcm-preset-edit" @click.stop="startEditPreset('eve')"><q-tooltip>Personnaliser le préréglage Soir de ce tech</q-tooltip></q-icon></span>
</div>
<!-- Personnalisation du préréglage PAR TECH (ex. Philip = 7:3017:30) : édité une fois, réutilisé à chaque clic Jour/Soir. -->
<div v-if="editPreset" class="pcm-preset-editor">
@ -81,7 +81,7 @@
<script setup>
// Menu de cellule réutilisable voir en-tête du template. Émet l'INTENTION `set-windows` (liste { min, max } en
// heures décimales) ; le parent la réconcilie (crée/retire les quarts réguliers, garde préservée).
import { ref, reactive, watch } from 'vue'
import { ref, reactive, watch, computed } from 'vue'
const props = defineProps({
title: { type: String, default: '' },
shifts: { type: Array, default: () => [] }, // [{ shift, shift_name, hours, start?, end?, on_call? }]
@ -157,7 +157,12 @@ function fmtHLabel (h) { const n = Number(h); if (!Number.isFinite(n)) return ''
function fmtPreset (p) { return fmtHLabel(p && p.start) + '' + fmtHLabel(p && p.end) }
const editPreset = ref(null) // 'day' | 'eve' | null
const presetBuf = reactive({ start: '', end: '' })
function startEditPreset (kind) { editPreset.value = kind; const p = kind === 'day' ? props.dayPreset : props.evePreset; presetBuf.start = numToTime(p.start); presetBuf.end = numToTime(p.end) }
// Préréglage EFFECTIF : le quart RÉEL de ce jour (le plus fiable pour ce tech ex. Houssam 818 s'affiche tel quel),
// sinon le préréglage fourni par le parent (perso enregistré / fenêtre usuelle / défaut). matin = début < 12h, soir sinon.
const rowWins = () => rows.value.map(r => ({ a: toNum(r.start), b: toNum(r.end) })).filter(w => w.a != null && w.b != null && w.b > w.a)
const dayPresetEff = computed(() => { const w = rowWins().find(x => x.a < 12); return w ? { start: w.a, end: w.b } : (props.dayPreset || { start: 8, end: 16 }) })
const evePresetEff = computed(() => { const w = rowWins().find(x => x.a >= 12); return w ? { start: w.a, end: w.b } : (props.evePreset || { start: 16, end: 20 }) })
function startEditPreset (kind) { editPreset.value = kind; const p = kind === 'day' ? dayPresetEff.value : evePresetEff.value; presetBuf.start = numToTime(p.start); presetBuf.end = numToTime(p.end) }
function commitPreset () {
const s = toNum(norm24(presetBuf.start)); const e = toNum(norm24(presetBuf.end))
if (s == null || e == null || e <= s) { editPreset.value = null; return } // saisie invalide on annule sans écrire
@ -189,8 +194,9 @@ function clearAll () { rows.value = []; overlap.value = false; clearTimeout(emit
.pcm-preset:hover { filter: brightness(0.97); }
.pcm-preset-edit { margin-left: 4px; opacity: 0.55; }
.pcm-preset-edit:hover { opacity: 1; }
.pcm-preset-editor { display: flex; align-items: center; gap: 5px; margin-top: 5px; padding: 4px 6px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 6px; }
.pcm-preset-lbl { font-size: 11px; font-weight: 600; color: #475569; white-space: nowrap; }
.pcm-preset-editor { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-top: 5px; padding: 4px 6px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 6px; }
.pcm-preset-lbl { flex-basis: 100%; font-size: 11px; font-weight: 600; color: #475569; white-space: nowrap; } /* label sur sa propre ligne → début → fin + ✓/✕ tiennent en dessous (menu 300px) */
.pcm-preset-editor .pcm-time { width: 52px; }
/* « Vider » = action destructive du jour → visible (rouge outline) mais pas dominante, pour éviter les clics accidentels. */
.pcm-clear { letter-spacing: 0.2px; }
.pcm-clear:hover { background: #fef2f2; }