From 30d09eb2ac7e4c4d6d94591180482e5ad42f799a Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 8 May 2026 19:27:32 -0300 Subject: [PATCH] AgendaEventDialog: props lockType + lockPatient + slot #headerLeft (additivos) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User escolheu caminho A: modificar AgendaEventDialog em vez de copiar. Mudancas SAO ADITIVAS — comportamento atual dos 5 callsites legacy (TherapistDashboard, PatientsListPage, MelissaAgenda, MelissaAgendamentosRecebidos, MelissaLayout) preservado. VALIDACAO: rodei os 7 spec files do agenda — 301 testes passaram. Zero regressao. ADICIONADO em src/features/agenda/components/AgendaEventDialog.vue - Prop lockType (Boolean, default false): pula step 1 (escolha de tipo) e vai direto pro form. Watch immediate em [lockType, modelValue] forca step.value=2 quando lockType=true e dialog abre. - Prop lockPatient (Boolean, default false): esconde botoes "trocar"/ "limpar" do paciente. Mostra icon de lock com tooltip "Paciente do prontuario". Cobre o cenario "criar sessao pra paciente fixo" sem precisar do isEdit que o patientLocked computed exige. - Slot #headerLeft: substitui o conteudo esquerdo do header (default era header-dot + headerTitle + previewRange). Permite callsites customizar com icon+title+subtitle proprios sem mexer no resto do header (X / actions). - v-if no Step 1: "step === 1 && !lockType" - v-if nos buttons trocar/limpar: "!patientLocked && !lockPatient" - Lock icon: "patientLocked || lockPatient" + tooltip dinamico MELISSAPACIENTE.VUE - Reverte o inject-only do commit 88dff50. - Mantem o inject(MELISSA_AGENDA_KEY) APENAS pra LER dados pesados (commitmentOptions, workRules, allEvents, agendaSettings, feriados, ownerId, tenantId) — evita re-fetch. - State LOCAL pro dialog: sessaoDialogOpen, sessaoDialogEventRow, sessaoDialogStartISO, sessaoDialogEndISO. Nao colide com o dialog global do MelissaLayout que continua na Agenda. - goAgendar(): inicializa eventRow com paciente_id fixo + tipo='sessao' + defaults razoaveis (proximo slot 15min + duracao da agenda), abre o dialog local. - Handlers onSessaoDialogSave / onSessaoDialogDelete delegam pros handlers globais (M.onDialogSave/Delete) e ao final refetcham sessions+recorrencias do paciente in-place. - Render com lock-type=true + lock-patient=true + slot #headerLeft custom (icon pi-calendar-plus em quadrado primary 40x40 + "Nova sessão" + nome do paciente como subtitulo). Resultado: prontuario tem o MESMO componente da Agenda (form completo de sessao, frequencia com preview de ocorrencias + conflitos, vinculacao de servicos/billing, edicao de serie, etc) mas pre-fixado no contexto do paciente, com header proprio e single source of truth. ESLint: 31 errors pre-existentes em ambos arquivos (variaveis declaradas nao usadas — confirmado via git stash baseline). 0 errors da minha mudanca. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../agenda/components/AgendaEventDialog.vue | 57 ++++++-- src/layout/melissa/MelissaPaciente.vue | 130 +++++++++++++++--- 2 files changed, 154 insertions(+), 33 deletions(-) diff --git a/src/features/agenda/components/AgendaEventDialog.vue b/src/features/agenda/components/AgendaEventDialog.vue index 5f08a50..3d4dbbf 100644 --- a/src/features/agenda/components/AgendaEventDialog.vue +++ b/src/features/agenda/components/AgendaEventDialog.vue @@ -105,7 +105,24 @@ const props = defineProps({ feriados: { type: Array, default: () => [] }, // Rota para cadastro completo de paciente (abre em nova aba) - newPatientRoute: { type: String, default: '' } + newPatientRoute: { type: String, default: '' }, + + // ── Locks aditivos (default false — comportamento atual) ────────── + // Usados pelo MelissaPaciente.vue pra abrir esse dialog ja em + // contexto de Sessao + paciente fixo do prontuario. Os 5 callsites + // existentes (TherapistDashboard, PatientsListPage, MelissaAgenda, + // MelissaAgendamentosRecebidos, MelissaLayout) seguem com defaults. + // + // lockType=true: pula o step de escolha de tipo (commitment cards) e + // vai direto pro form. Espera que eventRow ja venha com tipo+commitment + // resolvidos (no MelissaPaciente: tipo='sessao'). + // + // lockPatient=true: esconde os botoes "trocar"/"limpar" do paciente + // e mostra o icon de lock (mesma UX do patientLocked computed que + // ja existia pra modo edit, agora cobre tambem cenarios "criar sessao + // pra paciente fixo"). + lockType: { type: Boolean, default: false }, + lockPatient: { type: Boolean, default: false } }); const emit = defineEmits(['update:modelValue', 'save', 'delete', 'updateSeriesEvent', 'editSeriesOccurrence', 'updated']); @@ -176,6 +193,17 @@ const { resetForm } = _composer; +// Lock de tipo: quando lockType=true (callsite no contexto de Sessao do +// paciente, ex: MelissaPaciente), pula o step 1 e vai direto pro form. +// Watch immediate cobre tanto open quanto re-open com novo eventRow. +watch( + () => [props.lockType, props.modelValue], + ([locked, open]) => { + if (locked && open) step.value = 2; + }, + { immediate: true } +); + // ── recorrência: opções estáticas (consts data — não migradas) ── const freqOpcoes = [ { value: 'avulsa', label: 'Avulsa' }, @@ -718,13 +746,18 @@ const googleCalendarUrl = computed(() => { - + + + +