From 279b4f78e8a2301ddb7c6f06e929f11487e519bc Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 11 May 2026 10:46:31 -0300 Subject: [PATCH] melissa/agenda: view lista 2 anos + selector SelectButton + sticky header + visual inativo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit View lista: 'listWeek' -> custom 'listAll' (duration { years: 2 }, centrada em hoje via gotoDate(hoje - 1 ano) no setView). Antes a lista mostrava so 7 dias e ocultava 3 das 4 ocorrencias semanais — agora cobre passado + presente + futuro numa varredura. Cap MAX_RANGE_DAYS=730 do loadAndExpand bate exato com 2 anos. Banner showRecurrenceHint: aparece quando ha virtuais visiveis em day/week/month (nao mostra em listAll). Texto curto + botao "Ver na lista" que chama setView('lista'). Sticky day header (.fc-list-day): adicionado position:relative + z-index 3 + bg opaco. Sem isso, .fc-event passava POR CIMA do header conforme scroll (stacking context da row de evento ganhava do cushion sem z-index). View selector: botoes manuais (.ma-cal__view-btn) -> PrimeVue SelectButton. Visual herdado do tema, menos CSS custom. Visual evento inativo: classNames=['ma-evt--inactive-patient'] em fcEvents quando paciente_status === 'Arquivado'|'Inativo'. CSS aplica borda tracejada + opacidade 0.58 (italico em list view). Mantem a cor do commitment pra preservar contexto. FC touch defaults: adiciona spread de FC_TOUCH_DEFAULTS (utility commitada antes) — paridade touch <-> mouse, tap dispara select na hora em vez de exigir long-press de 1000ms. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/layout/melissa/MelissaAgenda.vue | 132 +++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 19 deletions(-) diff --git a/src/layout/melissa/MelissaAgenda.vue b/src/layout/melissa/MelissaAgenda.vue index 4b1ff5e..467fa23 100644 --- a/src/layout/melissa/MelissaAgenda.vue +++ b/src/layout/melissa/MelissaAgenda.vue @@ -22,6 +22,7 @@ import dayGridPlugin from '@fullcalendar/daygrid'; import listPlugin from '@fullcalendar/list'; import interactionPlugin from '@fullcalendar/interaction'; import ptBrLocale from '@fullcalendar/core/locales/pt-br'; +import { FC_TOUCH_DEFAULTS } from '@/features/agenda/utils/fcDefaults'; import { useMelissaEventosRange, useMelissaTodasSessoesPaciente } from './composables/useMelissaEventos'; import { MELISSA_AGENDA_KEY } from './composables/useMelissaAgenda'; import { useMelissaPacientesAside } from './composables/useMelissaPacientesAside'; @@ -244,7 +245,11 @@ const VIEW_MAP = { dia: 'timeGridDay', semana: 'timeGridWeek', mes: 'dayGridMonth', - lista: 'listWeek' + // listAll é view custom (configurada em fcOptions.views) — cobre 2 anos + // (1 ano antes + 1 ano depois de hoje). Substituiu listWeek que mostrava + // só 7 dias e escondia recorrências semanais/quinzenais futuras. Cap do + // loadAndExpand é 730d (MAX_RANGE_DAYS), 2 anos cai exatamente no limite. + lista: 'listAll' }; const fcRef = ref(null); @@ -384,6 +389,11 @@ const fcEvents = computed(() => { const evPid = ev.patient_id || ev.paciente_id; if (onlySess && !evPid) continue; if (pacienteId && evPid !== pacienteId) continue; + // Eventos cujo paciente foi arquivado/desativado ganham classe + // visual ("inativo") — borda tracejada + opacidade reduzida no CSS + // abaixo. Mantem a cor do commitment pra nao perder contexto. + const pStatus = ev.paciente_status; + const isInactivePatient = pStatus === 'Arquivado' || pStatus === 'Inativo'; out.push({ id: ev.id, title: ev.label, @@ -392,6 +402,7 @@ const fcEvents = computed(() => { backgroundColor: `${ev.color}26`, // ~15% opacity borderColor: ev.color, textColor: 'white', + classNames: isInactivePatient ? ['ma-evt--inactive-patient'] : undefined, extendedProps: ev }); } @@ -403,6 +414,19 @@ const fcEvents = computed(() => { return out; }); +// Hint pra trocar pra view 'lista' quando há ocorrências de recorrência +// visíveis em view dia/semana/mês. Cada view dessas cobre janela curta +// (1d / 7d / ~35d) — séries semanais com 4+ ocorrências sempre extrapolam. +// Lista cobre 2 anos centrada no usuário, então mostra passado/presente/futuro. +// Não mostra no modo "Ver todas" (já tá em modo lista paralela) nem na própria +// view lista. Some quando nenhum virtual aparece (sem recorrência ativa visível). +const showRecurrenceHint = computed(() => { + if (calendarView.value === 'lista') return false; + if (verTodasSessoes.value) return false; + if (!eventosSemana.value?.length) return false; + return eventosSemana.value.some((ev) => ev.is_occurrence); +}); + // ── slotMinTime / slotMaxTime baseado em timeMode ───────────── // 24: 00–24h. 12: 06–18h. my: range das workRules (snap em 30min). function _hhmmToMin(t) { @@ -492,11 +516,22 @@ function slotLabelContent(arg) { const fcOptions = computed(() => ({ plugins: [timeGridPlugin, dayGridPlugin, listPlugin, interactionPlugin], + ...FC_TOUCH_DEFAULTS, locale: ptBrLocale, headerToolbar: false, // toolbar é nossa (custom glass) initialView: VIEW_MAP[calendarView.value] || 'timeGridWeek', initialDate: refDate.value, nowIndicator: true, + // View custom "listAll": list view cobrindo 2 anos. Usada quando user clica + // o toggle "Lista" — exibe passadas + presentes + futuras numa varredura só. + // setView('lista') faz gotoDate(hoje - 1 ano) pra centrar. + views: { + listAll: { + type: 'list', + duration: { years: 2 }, + buttonText: 'Lista' + } + }, // Drag/resize/select habilitam apenas com M (composable disponível) — // standalone (sem M) fica readonly por compat (preview puro). editable: !!M, @@ -696,6 +731,14 @@ function goToday() { fcApi()?.today(); } function setView(v) { calendarView.value = v; fcApi()?.changeView(VIEW_MAP[v]); + // Lista cobre 2 anos — abrimos centrado: pula pra (hoje - 1 ano) pra + // mostrar passado + presente + futuro de uma vez. Outras views mantém + // o refDate atual (datesSet sincroniza viewStart/End normalmente). + if (v === 'lista') { + const umAnoAtras = new Date(); + umAnoAtras.setFullYear(umAnoAtras.getFullYear() - 1); + fcApi()?.gotoDate(umAnoAtras); + } } // ── Menu de Bloqueio (toolbar) ───────────────────────────────── @@ -1574,16 +1617,21 @@ defineExpose({ @bloqueio="onActionsBloqueio" /> -
- +
+
@@ -1662,6 +1710,32 @@ defineExpose({ + + +
+ + + Há sessões recorrentes visíveis — pode haver mais fora deste período. + + +
+
+