Melissa: hub Configuracoes + Embed + 9 Pages novas + dialog blueprint dark
Sprints 04-29 + 04-30 acumuladas. - MelissaConfiguracoes: hub 2-col com 6 grupos (Layout/Conta/Agenda/ Financeiro/WhatsApp/Sistema), tudo embedado via MelissaEmbed. - MelissaEmbed: wrapper generico que injeta layout-variant=melissa e remove cromos pra reaproveitar Pages tradicionais. - 9 Melissa Pages novas: CadastrosRecebidos, Compromissos, Configuracoes, Conversas, Embed, Grupos, Medicos, Recorrencias, Tags. - Dialog blueprint atualizado: bg-gray-100 (hardcoded light) -> bg-[var(--surface-ground)] (tema-aware). 22 dialogs migrados em 9 arquivos. Anti-pattern documentado. - PatientsCadastroPage: bug fix dropdown Grupo (optionLabel nome->name), toggle vertical/abas com persist localStorage, sticky margin-top. - Surface picker no popover do MelissaLayout (8 swatches). - useTopbarPlanMenu, useMelissaWhatsapp, useMelissaPacientesAside novos. - Migration: status agenda remarcado/confirmado. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -153,20 +153,24 @@ watch(() => props.entityId, async (v) => {
|
||||
if (v) await api.loadPhones(props.entityType, v);
|
||||
else api.phones.value = [];
|
||||
});
|
||||
|
||||
// Re-emite `change` sempre que a lista mudar (load, add, edit, remove,
|
||||
// setPrimary). Permite que o parent trackee count e faça validação de
|
||||
// "pelo menos 1 telefone obrigatório" sem precisar inspeccionar o
|
||||
// componente. immediate:true garante emit no load inicial.
|
||||
watch(api.phones, (arr) => emit('change', arr), { deep: true, immediate: true });
|
||||
|
||||
// Exposto pro parent — usado pelo PatientsCadastroPage no fluxo de criação:
|
||||
// telefones inseridos antes de salvar o paciente ficam em modo pendente
|
||||
// (id: 'pending_*') e são gravados em lote depois que o paciente recebe id.
|
||||
async function flushPending(entityType, entityId) {
|
||||
return api.flushPending(entityType, entityId);
|
||||
}
|
||||
defineExpose({ flushPending });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-2">
|
||||
<!-- Aviso sobre telefone principal -->
|
||||
<div class="text-[0.7rem] text-[var(--text-color-secondary)] flex items-start gap-1.5 px-1">
|
||||
<i class="pi pi-info-circle text-sky-500 mt-0.5 shrink-0" />
|
||||
<span>
|
||||
Marque um telefone como <strong>principal</strong> — ele é usado pra
|
||||
<strong>cobranças, lembretes automáticos e contato padrão</strong>.
|
||||
Número vindo do CRM WhatsApp recebe a etiqueta <strong>"vinculado"</strong>.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Lista de telefones -->
|
||||
<div v-if="api.loading.value" class="text-xs text-center py-3 text-[var(--text-color-secondary)]">
|
||||
<i class="pi pi-spin pi-spinner mr-1" /> Carregando…
|
||||
@@ -325,7 +329,7 @@ watch(() => props.entityId, async (v) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Botão + -->
|
||||
<!-- Botão + (sempre habilitado: sem entityId vai pro modo pendente) -->
|
||||
<Button
|
||||
v-if="!readonly && !showAddForm"
|
||||
label="Adicionar telefone"
|
||||
@@ -334,8 +338,6 @@ watch(() => props.entityId, async (v) => {
|
||||
outlined
|
||||
size="small"
|
||||
class="self-start rounded-full"
|
||||
:disabled="!props.entityId"
|
||||
v-tooltip.right="!props.entityId ? 'Salve o cadastro primeiro pra adicionar telefones' : null"
|
||||
@click="openAddForm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user