9.7 KiB
9.7 KiB
🏗️ BaseDomainComponent - Arquitetura Principal
🎯 Visão Geral
O BaseDomainComponent é o componente base abstrato que padroniza todos os domínios ERP do sistema PraFrota. Ele encapsula funcionalidades comuns como CRUD operations, sistema de abas, paginação server-side, e agora inclui suporte a Dashboard Tabs.
✨ Funcionalidades Principais
- ✅ Sistema de Abas Integrado (TabSystem)
- ✅ CRUD Operations Padronizadas
- ✅ Paginação Server-Side
- ✅ Gerenciamento de Estado Unificado
- ✅ Header Actions Configuráveis
- ✅ Prevenção de Duplicatas
- ✅ Event Handling Padronizado
- ✅ Dashboard Tab System ⭐ NOVO
- ✅ Filtros Avançados
- ✅ Ações em Lote (Bulk Actions)
🚀 Como Usar
Template Básico
@Component({
selector: 'app-clients',
standalone: true,
imports: [CommonModule, TabSystemComponent],
providers: [DatePipe],
templateUrl: './clients.component.html',
styleUrl: './clients.component.scss'
})
export class ClientsComponent extends BaseDomainComponent<Client> {
constructor(
service: ClientsService,
titleService: TitleService,
headerActionsService: HeaderActionsService,
cdr: ChangeDetectorRef
) {
super(titleService, headerActionsService, cdr, service);
}
protected override getDomainConfig(): DomainConfig {
return {
domain: 'client',
title: 'Clientes',
entityName: 'cliente',
subTabs: ['dados', 'contatos'],
showDashboardTab: true, // ⭐ NOVO: Aba Dashboard
columns: [
{ field: "id", header: "Id", sortable: true },
{ field: "name", header: "Nome", sortable: true }
]
};
}
}
Template HTML Obrigatório
<div class="domain-container">
<div class="main-content">
<app-tab-system
#tabSystem
[config]="tabConfig"
[events]="tabEvents"
[showDebugInfo]="false"
(tabSelected)="onTabSelected($event)"
(tabClosed)="onTabClosed($event)"
(tabAdded)="onTabAdded($event)"
(tableEvent)="onTableEvent($event)">
</app-tab-system>
</div>
</div>
📊 Dashboard Tab System ⭐ NOVO
Configuração Básica
protected override getDomainConfig(): DomainConfig {
return {
// ... configurações existentes ...
showDashboardTab: true, // Habilita aba Dashboard
dashboardConfig: {
title: 'Dashboard de Clientes',
showKPIs: true,
showCharts: true,
showRecentItems: true,
customKPIs: [
{
id: 'premium-clients',
label: 'Clientes Premium',
value: 45,
icon: 'fas fa-crown',
color: 'warning',
trend: 'up',
change: '+12%'
}
]
}
};
}
Ordem das Abas
- Dashboard de [Domínio] (se
showDashboardTab: true) - Lista de [Domínio] (sempre presente)
- Abas de Edição (conforme necessário)
KPIs Automáticos
O sistema gera automaticamente:
- Total de Registros: Baseado em
totalItems - Registros Ativos: Se existir campo
status - Registros Recentes: Últimos 7 dias (baseado em
created_at)
🔧 DomainConfig Interface
export interface DomainConfig {
domain: string; // ID do domínio
title: string; // Título para header
entityName: string; // Nome da entidade
subTabs: string[]; // Sub-abas para edição
columns: any[]; // Configuração das colunas
pageSize?: number; // Tamanho padrão da página
maxTabs?: number; // Máximo de abas abertas
allowDuplicates?: boolean; // Permitir abas duplicadas
customActions?: any[]; // Ações customizadas
sideCard?: SideCardConfig; // Configuração do card lateral
filterConfig?: FilterConfig; // Configuração de filtros
bulkActions?: BulkAction[]; // Ações em lote
showDashboardTab?: boolean; // ⭐ NOVO: Mostrar aba Dashboard
dashboardConfig?: DashboardTabConfig; // ⭐ NOVO: Config do dashboard
}
🎯 Métodos Principais
Métodos Abstratos (Obrigatórios)
// Deve ser implementado em cada domínio
protected abstract getDomainConfig(): DomainConfig;
// Opcional: customizar dados de nova entidade
protected getNewEntityData(): Partial<T> {
return {};
}
Métodos de CRUD
// Carregar entidades com paginação
loadEntities(currentPage = 1, itemsPerPage = 50): void
// Criar nova entidade
async createNew(): Promise<void>
// Editar entidade existente
async editEntity(entityData: any): Promise<void>
Métodos de Dashboard ⭐ NOVO
// Criar aba dashboard
private async createDashboardTab(): Promise<void>
// Gerar KPIs automáticos
private generateAutomaticKPIs(): DashboardKPI[]
// Criar abas iniciais (Dashboard + Lista)
private async createInitialTabs(): Promise<void>
// Atualizar dados do dashboard
private updateDashboardTabData(): void
📋 Event Handling
Eventos de Tabela
onTableEvent(eventData: { event: string, data: any }): void {
const { event, data } = eventData;
switch (event) {
case 'sort': this.onSort(data); break;
case 'page': this.onPage(data); break;
case 'filter': this.onFilter(data); break;
case 'actionClick': this.onActionClick(data); break;
case 'formSubmit': this.onFormSubmit(data); break;
case 'advancedFiltersChanged': this.onAdvancedFiltersChanged(data); break;
case 'rowSelectionChanged': this.onRowSelectionChanged(data); break;
}
}
Eventos de Abas
onTabSelected(tab: TabItem): void
onTabClosed(tab: TabItem): void
onTabAdded(tab: TabItem): void
🔄 Ciclo de Vida
graph TD
A[ngOnInit] --> B[setupDomain]
B --> C[loadEntities]
C --> D{Primeira vez?}
D -->|Sim| E[createInitialTabs]
D -->|Não| F[updateTabsData]
E --> G{showDashboardTab?}
G -->|Sim| H[createDashboardTab]
G -->|Não| I[createListTab]
H --> I
F --> J{Dashboard existe?}
J -->|Sim| K[updateDashboardTabData]
J -->|Não| L[updateListTabData]
K --> L
🎨 Customizações Avançadas
Filtros Especiais
filterConfig: {
specialFilters: [
{
id: 'date-range',
label: 'Período',
type: 'date-range',
required: false
}
],
companyFilter: true,
dateRangeFilter: false
}
Ações em Lote
bulkActions: [
{
id: 'activate',
label: 'Ativar Selecionados',
icon: 'fas fa-check',
color: 'success',
action: (selectedItems) => this.activateItems(selectedItems)
}
]
Side Card
sideCard: {
title: 'Informações Adicionais',
component: 'custom-info-card',
data: { /* dados específicos */ }
}
📚 Exemplos Completos
Exemplo 1: Domínio Simples
// vehicles.component.ts
export class VehiclesComponent extends BaseDomainComponent<Vehicle> {
protected override getDomainConfig(): DomainConfig {
return {
domain: 'vehicle',
title: 'Veículos',
entityName: 'veículo',
subTabs: ['dados', 'documentos'],
showDashboardTab: true,
columns: [
{ field: "license_plate", header: "Placa", sortable: true },
{ field: "brand", header: "Marca", sortable: true },
{ field: "model", header: "Modelo", sortable: true }
]
};
}
}
Exemplo 2: Domínio Avançado
// drivers.component.ts
export class DriversComponent extends BaseDomainComponent<Driver> {
protected override getDomainConfig(): DomainConfig {
return {
domain: 'driver',
title: 'Motoristas',
entityName: 'motorista',
subTabs: ['dados', 'photos', 'documents', 'fines'],
showDashboardTab: true,
dashboardConfig: {
title: 'Dashboard de Motoristas',
customKPIs: [
{
id: 'drivers-with-license',
label: 'Com CNH Válida',
value: '85%',
icon: 'fas fa-id-card',
color: 'success',
trend: 'up',
change: '+3%'
}
]
},
filterConfig: {
companyFilter: true,
specialFilters: [
{
id: 'license-status',
label: 'Status da CNH',
type: 'custom-select',
config: {
options: [
{ value: 'valid', label: 'Válida' },
{ value: 'expired', label: 'Vencida' },
{ value: 'suspended', label: 'Suspensa' }
]
}
}
]
},
bulkActions: [
{
id: 'send-notification',
label: 'Enviar Notificação',
icon: 'fas fa-bell',
color: 'primary'
}
],
columns: [
{ field: "id", header: "Id", sortable: true },
{ field: "name", header: "Nome", sortable: true },
{ field: "cpf", header: "CPF", sortable: true },
{ field: "phone", header: "Telefone", sortable: true },
{ field: "license_number", header: "CNH", sortable: true }
]
};
}
}
🔗 Componentes Relacionados
📈 Métricas e Performance
- Prevenção de Loops: Proteção contra chamadas duplicadas
- Lazy Loading: Componentes carregados sob demanda
- Server-Side Pagination: Otimização para grandes datasets
- Change Detection: Controle otimizado de atualizações
Atualizado em: Janeiro 2025
Versão: 2.0 (Dashboard Tab System)
Autor: Sistema PraFrota