melissa/templates: usa DataView pros templates do tenant

Substitui o <div class="mdt-grid"> v-for simples por <DataView>
do PrimeVue na coluna "Seus documentos".

Beneficios:
- Paginacao automatica quando passa de 12 templates (era scroll
  infinito virando lento)
- Slot #grid permite manter o layout de cards atual
- Footer com paginator integrado ao design (border-top + bg
  transparente)

CSS:
- .mdt-dataview flex column ocupando o main
- :deep(.p-dataview-content) flex 1 + overflow auto = scroll
  interno dos cards
- :deep(.p-dataview-paginator-bottom) flex-shrink 0 = paginator
  sempre visivel no fundo
- .mdt-main .mdt-grid passa a ter padding 12 e gap 10 (era
  herdado do .mdt-grid global)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-05-21 17:11:10 -03:00
parent c9afe8f009
commit 17f114f32f
@@ -17,6 +17,7 @@ import { useDocumentTemplates } from '@/features/documents/composables/useDocume
import DocumentTemplateEditor from '@/features/documents/components/DocumentTemplateEditor.vue';
// Button/Menu/Skeleton: auto via PrimeVueResolver
import Menu from 'primevue/menu';
import DataView from 'primevue/dataview';
const emit = defineEmits(['close']);
const toast = useToast();
@@ -411,55 +412,66 @@ onMounted(() => {
</button>
</div>
<!-- Grid dos templates do tenant -->
<div v-else class="mdt-grid">
<div
v-for="tpl in tenantTemplates"
:key="tpl.id"
class="mdt-card mdt-card--tenant"
role="button"
tabindex="0"
@click="openEdit(tpl)"
@keydown.enter.prevent="openEdit(tpl)"
>
<div class="mdt-card__head">
<span class="mdt-card__icon mdt-card__icon--primary">
<i class="pi pi-file-edit" />
</span>
<div class="mdt-card__main">
<div class="mdt-card__name">{{ tpl.nome_template }}</div>
<div class="mdt-card__tipo">{{ tipoLabel(tpl.tipo) }}</div>
<div v-if="tpl.descricao" class="mdt-card__desc">{{ tpl.descricao }}</div>
<!-- DataView dos templates do tenant paginação + layout grid -->
<DataView
v-else
:value="tenantTemplates"
layout="grid"
:paginator="tenantTemplates.length > 12"
:rows="12"
class="mdt-dataview"
>
<template #grid="slotProps">
<div class="mdt-grid">
<div
v-for="tpl in slotProps.items"
:key="tpl.id"
class="mdt-card mdt-card--tenant"
role="button"
tabindex="0"
@click="openEdit(tpl)"
@keydown.enter.prevent="openEdit(tpl)"
>
<div class="mdt-card__head">
<span class="mdt-card__icon mdt-card__icon--primary">
<i class="pi pi-file-edit" />
</span>
<div class="mdt-card__main">
<div class="mdt-card__name">{{ tpl.nome_template }}</div>
<div class="mdt-card__tipo">{{ tipoLabel(tpl.tipo) }}</div>
<div v-if="tpl.descricao" class="mdt-card__desc">{{ tpl.descricao }}</div>
</div>
</div>
<!-- Menu de ações -->
<div class="mdt-card__menu" @click.stop>
<Button
icon="pi pi-ellipsis-v"
text
rounded
size="small"
class="!w-7 !h-7 mdt-card__menu-btn"
@click.stop="$refs[`menu_${tpl.id}`]?.[0]?.toggle($event)"
/>
<Menu
:ref="`menu_${tpl.id}`"
:model="getCardMenuItems(tpl)"
:popup="true"
/>
</div>
<div class="mdt-card__foot">
<span v-if="!tpl.ativo" class="mdt-card__badge mdt-card__badge--inactive">
inativo
</span>
<span class="mdt-card__vars">
&lt; {{ tpl.variaveis?.length || 0 }} variáveis &gt;
</span>
</div>
</div>
</div>
<!-- Menu de ações -->
<div class="mdt-card__menu" @click.stop>
<Button
icon="pi pi-ellipsis-v"
text
rounded
size="small"
class="!w-7 !h-7 mdt-card__menu-btn"
@click.stop="$refs[`menu_${tpl.id}`]?.[0]?.toggle($event)"
/>
<Menu
:ref="`menu_${tpl.id}`"
:model="getCardMenuItems(tpl)"
:popup="true"
/>
</div>
<div class="mdt-card__foot">
<span v-if="!tpl.ativo" class="mdt-card__badge mdt-card__badge--inactive">
inativo
</span>
<span class="mdt-card__vars">
&lt; {{ tpl.variaveis?.length || 0 }} variáveis &gt;
</span>
</div>
</div>
</div>
</template>
</DataView>
</main>
</div>
</template>
@@ -834,15 +846,38 @@ onMounted(() => {
.mdt-main__empty-btn { margin-top: 10px; }
.mdt-main .mdt-grid {
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
padding: 12px;
gap: 10px;
}
/* DataView wrapper — preenche o main e quebra em paginator/grid */
.mdt-dataview {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
background: transparent;
}
.mdt-dataview :deep(.p-dataview-content) {
flex: 1;
min-height: 0;
overflow-y: auto;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
background: transparent;
scrollbar-width: thin;
scrollbar-color: var(--m-border-strong) transparent;
}
.mdt-main .mdt-grid::-webkit-scrollbar { width: 5px; }
.mdt-main .mdt-grid::-webkit-scrollbar-thumb { background: var(--m-border-strong); border-radius: 3px; }
.mdt-dataview :deep(.p-dataview-content)::-webkit-scrollbar { width: 5px; }
.mdt-dataview :deep(.p-dataview-content)::-webkit-scrollbar-thumb {
background: var(--m-border-strong);
border-radius: 3px;
}
.mdt-dataview :deep(.p-dataview-paginator-bottom) {
flex-shrink: 0;
background: transparent;
border-top: 1px solid var(--m-border);
}
/* ── Preview de template do sistema ── */
.mdt-preview-actions {