agenda C12 UX: filtrar cancelled do dialog Lancamentos da sessao

Iteracao UX #2 do C12: records cancelled (do ciclo Revogar+Antecipar
e tambem das multas) poluiam o dialog "Lancamentos da sessao",
escondendo o que importa (ativos).

lancamentosShowHistory ref (default false) + lancamentosFiltered
computed filtra status !== 'cancelled'. lancamentosCancelledCount
computa contagem pra feedback.

UI:
- Dialog abre limpo (sempre lancamentosShowHistory=false em
  onVerLancamentos)
- Quando ha cancelled e existe ativo: linha acima da lista com
  "{N} cancelado(s) ocultos" + botao toggle "Mostrar/Ocultar
  historico"
- Quando todos sao cancelled: empty state especial "Sem
  lancamentos ativos. {N} cancelado(s) no historico" + botao
  pra expandir
- Cards cancelled atenuados (opacity 0.55, border-dashed,
  background sutil, description com line-through) — claramente
  audit trail, nao-ativo

Combina com "Trocar metodo" (commit anterior) — agora o caso 99%
do tempo ele ve so o record ativo, nao precisa nem expandir
historico.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-05-21 05:31:01 -03:00
parent 9c518a2b44
commit b7f3c23ad6
+43 -2
View File
@@ -751,6 +751,17 @@ const lancamentosDialogOpen = ref(false);
const lancamentosList = ref([]); const lancamentosList = ref([]);
const lancamentosLoading = ref(false); const lancamentosLoading = ref(false);
const lancamentosEventoTitulo = ref(''); const lancamentosEventoTitulo = ref('');
// Por default esconde cancelled (poluem o que importa quando user só
// quer ver os ativos). Toggle 'Mostrar histórico' libera audit trail.
// Resetado a cada abertura do dialog (onVerLancamentos).
const lancamentosShowHistory = ref(false);
const lancamentosFiltered = computed(() => {
if (lancamentosShowHistory.value) return lancamentosList.value;
return lancamentosList.value.filter((r) => r.status !== 'cancelled');
});
const lancamentosCancelledCount = computed(() =>
lancamentosList.value.filter((r) => r.status === 'cancelled').length
);
// Antecipar pagamento (Fase 5, 2026-05-14): paciente quer pagar antes da // Antecipar pagamento (Fase 5, 2026-05-14): paciente quer pagar antes da
// sessão (caso típico em pacote saldo). Materializa a ocorrência (se virtual) // sessão (caso típico em pacote saldo). Materializa a ocorrência (se virtual)
// + cria financial_record paid (PIX/etc) ou pending (Asaas). NÃO decrementa // + cria financial_record paid (PIX/etc) ou pending (Asaas). NÃO decrementa
@@ -1088,6 +1099,7 @@ async function onVerLancamentos() {
const isVirtual = ev.is_occurrence || isVirtualId; const isVirtual = ev.is_occurrence || isVirtualId;
lancamentosEventoTitulo.value = ev.pacienteNome || ev.label || ev.titulo || 'Sessão'; lancamentosEventoTitulo.value = ev.pacienteNome || ev.label || ev.titulo || 'Sessão';
lancamentosShowHistory.value = false; // sempre abre limpo (sem cancelled)
lancamentosDialogOpen.value = true; lancamentosDialogOpen.value = true;
lancamentosLoading.value = true; lancamentosLoading.value = true;
try { try {
@@ -3221,12 +3233,29 @@ function onKeydown(e) {
<div v-else-if="!lancamentosList.length" class="py-6 text-center text-sm opacity-70"> <div v-else-if="!lancamentosList.length" class="py-6 text-center text-sm opacity-70">
<i class="pi pi-info-circle mr-1" /> Nenhum lançamento vinculado a esta sessão. <i class="pi pi-info-circle mr-1" /> Nenhum lançamento vinculado a esta sessão.
</div> </div>
<div v-else-if="!lancamentosFiltered.length" class="py-6 text-center text-sm opacity-70">
<i class="pi pi-info-circle mr-1" /> Sem lançamentos ativos. {{ lancamentosCancelledCount }} cancelado(s) no histórico.
<div class="mt-3">
<Button :label="`Mostrar ${lancamentosCancelledCount} cancelado(s)`" size="small" text @click="lancamentosShowHistory = true" />
</div>
</div>
<div v-else class="flex flex-col gap-2.5"> <div v-else class="flex flex-col gap-2.5">
<!-- Toggle de histórico ( aparece quando cancelled) -->
<div v-if="lancamentosCancelledCount > 0" class="flex items-center justify-end gap-2 text-xs opacity-70">
<span v-if="!lancamentosShowHistory">{{ lancamentosCancelledCount }} cancelado(s) ocultos.</span>
<Button
:label="lancamentosShowHistory ? 'Ocultar histórico' : 'Mostrar histórico'"
:icon="lancamentosShowHistory ? 'pi pi-eye-slash' : 'pi pi-history'"
size="small"
text
@click="lancamentosShowHistory = !lancamentosShowHistory"
/>
</div>
<div <div
v-for="(r, idx) in lancamentosList" v-for="(r, idx) in lancamentosFiltered"
:key="r.id" :key="r.id"
class="ml-lanc-card" class="ml-lanc-card"
:class="{ 'ml-lanc-card--child': idx > 0 }" :class="{ 'ml-lanc-card--child': idx > 0, 'ml-lanc-card--cancelled': r.status === 'cancelled' }"
> >
<div class="ml-lanc-card__head"> <div class="ml-lanc-card__head">
<i v-if="idx > 0" class="pi pi-arrow-right-and-arrow-left-up-down ml-lanc-card__indent" /> <i v-if="idx > 0" class="pi pi-arrow-right-and-arrow-left-up-down ml-lanc-card__indent" />
@@ -3853,6 +3882,18 @@ function onKeydown(e) {
margin-left: 1.5rem; margin-left: 1.5rem;
border-color: color-mix(in srgb, var(--p-primary-color) 25%, var(--surface-border)); border-color: color-mix(in srgb, var(--p-primary-color) 25%, var(--surface-border));
} }
/* Cancelled — apenas visíveis quando user expande o histórico.
Visual atenuado pra sinalizar "audit trail, não-ativo". */
.ml-lanc-card--cancelled {
opacity: 0.55;
border-style: dashed;
background: color-mix(in srgb, var(--surface-ground) 60%, transparent);
}
.ml-lanc-card--cancelled .ml-lanc-card__desc {
text-decoration: line-through;
text-decoration-color: currentColor;
text-decoration-thickness: 1px;
}
.ml-lanc-card__head { .ml-lanc-card__head {
display: flex; display: flex;
align-items: center; align-items: center;