19 KiB
📚 IDT App - Documentação Completa
Visão Geral
Bem-vindo à documentação oficial do IDT App, uma aplicação moderna de gestão de frota desenvolvida em Angular 18+ com framework CRUD genérico e design system personalizado.
🗂️ Índice de Documentação
🎯 Soluções Críticas (NOVO)
- Solução de Sincronização de Formulários - Correção completa para problemas de edição
- Resolve "segunda tentativa" para editar campos
- Elimina "blinking" e perda de foco
- Corrige loops infinitos no salvamento
- Proteção tripla contra
ngOnChanges()desnecessário - Sistema de edição controlada e robusta
🚀 Framework CRUD Universal (NOVO)
-
Tab System - Sistema completo de abas e formulários
- Sistema genérico para qualquer domínio
- Sub-abas configuráveis dinamicamente
- Salvamento automático escalável
- API universal para CRUD operations
-
Base Domain Component - Componente base para domínios
- CRUD operations padronizadas
- Herança automática de funcionalidades
- Event handling unificado
- Paginação server-side integrada
-
API Integration Guide - Guia de integração com API PraFrota
- Orientações para consulta ao Swagger
- Templates para implementação de services
- Mapeamento de schemas para interfaces TypeScript
- Checklist completo para novos domínios
📱 Componentes Mobile
- Mobile Footer Menu - Menu de navegação flutuante para dispositivos móveis
- Sistema de notificações em tempo real
- Navegação para Dashboard, Rotas Meli, Veículos e Sidebar
- Design responsivo com tema IDT
🃏 Side Card Component
- Side Card - Componente genérico para informações contextuais
- Sistema genérico e reutilizável
- Suporte completo a temas (claro/escuro)
- Design responsivo com collapse automático no mobile
- Hierarquia inteligente de imagens com fallbacks
- Integrado seamlessly com o sistema de tabs
🎨 Design System
- Typography System - Sistema de tipografia completo
- Logo Relocation Guide - Guia de posicionamento de logo
- Cores e Temas (em desenvolvimento)
- Paleta de cores principal: #FFC82E (dourado) e #000000 (preto)
- Suporte a temas claro e escuro
- Variáveis CSS customizadas
🏗️ Layout e Estrutura
- Layout Restructure Guide - Guia de reestruturação de layout
- Sidebar Styling Guide - Estilização da barra lateral
📋 Documentação Geral
- Cursor Integration - Integração e configuração do Cursor
🚗 Módulos de Domínio (Usando Framework Universal)
-
Motoristas (implementado com BaseDomainComponent)
- CRUD completo automatizado
- Sub-abas: dados, endereço, documentos
- Salvamento genérico integrado
-
Veículos (pronto para implementação)
- Herda automaticamente todas as funcionalidades CRUD
- Configuração declarativa simples
- Sub-abas personalizáveis
🛣️ Rotas e Navegação
- Mercado Livre (em desenvolvimento)
- Integração com API do Mercado Livre
- Gestão de rotas de entrega
- Notificações em tempo real
📊 Dashboard e Relatórios
- Dashboard (em desenvolvimento)
- Widgets personalizáveis
- Métricas em tempo real
- Exportação de dados
🚀 Getting Started
Pré-requisitos
Node.js >= 18.x
Angular CLI >= 18.x
npm ou yarn
Instalação
# Clonar repositório
git clone [url-do-repositorio]
# Instalar dependências
cd web/angular
npm install
# Executar em desenvolvimento
npm start
Build para Produção
# Build otimizado
npm run build:prod
# Build do projeto IDT App
npx ng build idt_app --configuration production
🌐 Integração com API PraFrota
📋 Swagger da API
URL da API: https://prafrota-be-bff-tenant-api.grupopra.tech/swagger#/
🎯 Fluxo para Novos Domínios
Ao implementar um novo domínio usando nosso Framework CRUD Universal, siga este processo:
1. Consultar Swagger da API
# Acessar a documentação da API
https://prafrota-be-bff-tenant-api.grupopra.tech/swagger#/
# Identificar endpoints para o domínio desejado:
# - GET /api/vehicles (listagem)
# - POST /api/vehicles (criação)
# - PUT /api/vehicles/{id} (atualização)
# - DELETE /api/vehicles/{id} (exclusão)
# - GET /api/vehicles/{id} (detalhes)
2. Implementar Service baseado na API
// vehicles.service.ts
@Injectable()
export class VehiclesService implements DomainService<Vehicle> {
private apiUrl = 'https://prafrota-be-bff-tenant-api.grupopra.tech/api';
constructor(private http: HttpClient) {}
// ✅ Método obrigatório para BaseDomainComponent
getEntities(page: number, pageSize: number, filters: any): Observable<{
data: Vehicle[];
totalCount: number;
pageCount: number;
currentPage: number;
}> {
const params = new HttpParams()
.set('page', page.toString())
.set('pageSize', pageSize.toString())
.set('filters', JSON.stringify(filters));
return this.http.get<any>(`${this.apiUrl}/vehicles`, { params });
}
// ✅ Métodos para salvamento genérico
create(vehicle: Partial<Vehicle>): Observable<Vehicle> {
return this.http.post<Vehicle>(`${this.apiUrl}/vehicles`, vehicle);
}
update(id: any, vehicle: Partial<Vehicle>): Observable<Vehicle> {
return this.http.put<Vehicle>(`${this.apiUrl}/vehicles/${id}`, vehicle);
}
delete(id: any): Observable<void> {
return this.http.delete<void>(`${this.apiUrl}/vehicles/${id}`);
}
getById(id: any): Observable<Vehicle> {
return this.http.get<Vehicle>(`${this.apiUrl}/vehicles/${id}`);
}
}
3. Implementar Domain Component
// vehicles.component.ts
@Component({
selector: 'app-vehicles',
template: `<app-tab-system [config]="tabConfig" (tableEvent)="onTableEvent($event)"></app-tab-system>`
})
export class VehiclesComponent extends BaseDomainComponent<Vehicle> {
constructor(
private vehiclesService: VehiclesService,
titleService: TitleService,
headerActionsService: HeaderActionsService,
cdr: ChangeDetectorRef
) {
super(titleService, headerActionsService, cdr, vehiclesService);
}
protected getDomainConfig(): DomainConfig {
return {
domain: 'vehicle',
title: 'Veículos',
entityName: 'veículo',
subTabs: ['dados', 'documentos', 'manutencao'],
columns: [
// ✅ Baseado no schema da API no Swagger
{ field: 'plate', header: 'Placa', sortable: true },
{ field: 'model', header: 'Modelo', sortable: true },
{ field: 'year', header: 'Ano', sortable: true },
{ field: 'status', header: 'Status', filterable: true }
]
};
}
// 🎉 PRONTO! CRUD completo integrado com API PraFrota!
}
4. Definir Interface baseada no Schema da API
// vehicle.interface.ts
// ✅ Baseado no schema do Swagger
export interface Vehicle {
id: string;
plate: string;
model: string;
year: number;
status: 'ACTIVE' | 'INACTIVE' | 'MAINTENANCE';
brand: string;
color: string;
chassisNumber: string;
renavam: string;
licensePlate: string;
// ... outros campos conforme API
}
🔧 Vantagens da Integração
- ✅ Consistência: Schemas alinhados com a API real
- ✅ Validação: TypeScript garante tipagem correta
- ✅ Escalabilidade: Padrão para todos os novos domínios
- ✅ Manutenibilidade: Mudanças na API refletidas facilmente
- ✅ Documentação: Swagger como fonte única da verdade
📋 Checklist para Novos Domínios
Ao implementar um novo domínio:
- ☐ Consultar Swagger - Identificar endpoints disponíveis
- ☐ Definir Interface - Baseada no schema da API
- ☐ Implementar Service - Com métodos CRUD padrão
- ☐ Criar Component - Estendendo BaseDomainComponent
- ☐ Configurar Columns - Baseadas nos campos da API
- ☐ Testar Integração - Verificar CRUD completo
🎮 Exemplo Prático
// Processo completo para domínio "Drivers":
// 1. Swagger: GET /api/drivers, POST /api/drivers, etc.
// 2. Interface: Driver { id, name, cpf, license, ... }
// 3. Service: DriversService implements DomainService<Driver>
// 4. Component: DriversComponent extends BaseDomainComponent<Driver>
// 5. Resultado: CRUD completo integrado com API PraFrota
🏗️ Arquitetura do Framework CRUD
🎯 Nova Arquitetura Universal
🚀 FRAMEWORK CRUD GENÉRICO:
1️⃣ BaseDomainComponent<T> (Genérico)
├── 🔄 CRUD operations padronizadas
├── 📊 Paginação server-side
├── 💾 Sistema de salvamento genérico
└── 🎯 Event handling unificado
2️⃣ TabSystemComponent (Interface Universal)
├── 📑 Abas configuráveis
├── 🎨 Sub-abas dinâmicas
├── 💾 Salvamento automático
└── 🔗 Integração com formulários
3️⃣ GenericTabFormComponent (Formulários)
├── 📝 Campos configuráveis
├── ✅ Validação automática
├── 💾 Salvamento integrado
└── 🎯 Eventos padronizados
📂 Estrutura do Projeto (Atualizada)
projects/idt_app/
├── src/
│ ├── app/
│ │ ├── domain/ # Módulos de negócio
│ │ │ ├── drivers/ # ✅ Usa BaseDomainComponent
│ │ │ ├── vehicles/ # 🔄 Pronto para implementar
│ │ │ └── routes/ # 🔄 Pronto para implementar
│ │ ├── shared/ # Componentes compartilhados
│ │ │ ├── components/ # Componentes reutilizáveis
│ │ │ │ ├── base-domain/ # 🚀 NOVO: Componente base CRUD
│ │ │ │ ├── tab-system/ # 🚀 NOVO: Sistema de abas
│ │ │ │ ├── generic-tab-form/ # 🚀 NOVO: Formulários genéricos
│ │ │ │ └── data-table/ # Tabelas com paginação
│ │ │ ├── services/ # Serviços globais
│ │ │ ├── interfaces/ # Tipos TypeScript
│ │ │ └── sidecard/ # 🔄 Side Card reorganizado
│ │ └── core/ # Configurações centrais
│ ├── assets/ # Recursos estáticos
│ └── styles/ # Estilos globais
├── docs/ # 📚 Esta documentação
└── samples_screen/ # Screenshots e exemplos
Tecnologias Utilizadas
Frontend
- Angular 18+: Framework principal
- TypeScript: Linguagem de desenvolvimento
- RxJS: Programação reativa
- Angular Material: Componentes UI
- SCSS: Pré-processador CSS
Ferramentas
- Angular CLI: Desenvolvimento e build
- ESLint: Linting de código
- Prettier: Formatação de código
- Jest: Testes unitários
🎯 Recursos Principais
✅ Implementados (Framework CRUD)
- BaseDomainComponent - CRUD genérico para qualquer domínio
- TabSystemComponent - Sistema de abas configuráveis
- GenericTabFormComponent - Formulários automáticos
- Sistema de Salvamento Genérico - Auto-detecta create/update
- Sub-abas Dinâmicas - Configuração declarativa
- API Universal - Mesma interface para todos os domínios
- Event-driven Architecture - Comunicação padronizada
- Side Card Integration - Informações contextuais
✅ Recursos de UI
- Mobile Footer Menu - Navegação mobile otimizada
- Data Tables - Tabelas com filtros e paginação
- Design System - Cores e temas consistentes
- Responsive Design - Adaptação para todos os dispositivos
🔄 Em Desenvolvimento
- Dashboard com widgets
- Integração completa com APIs
- Sistema de relatórios
- Notificações push
- Modo offline (PWA)
📱 Componentes Destacados
🚀 Framework CRUD (NOVO)
Implementar Novo Domínio (APENAS 15 LINHAS)
// ✨ CRUD completo para qualquer entidade em 15 linhas!
@Component({
selector: 'app-clients',
template: `<app-tab-system [config]="tabConfig" (tableEvent)="onTableEvent($event)"></app-tab-system>`
})
export class ClientsComponent extends BaseDomainComponent<Client> {
protected getDomainConfig(): DomainConfig {
return {
domain: 'client',
title: 'Clientes',
entityName: 'cliente',
subTabs: ['dados', 'endereco', 'contratos'],
columns: [
{ field: 'name', header: 'Nome', sortable: true },
{ field: 'email', header: 'Email', filterable: true }
]
};
}
// 🎉 PRONTO! CRUD completo funcionando:
// ✅ Listagem com paginação
// ✅ Criação com formulário
// ✅ Edição com sub-abas
// ✅ Salvamento automático
}
API Universal do Tab System
// API genérica - funciona com qualquer entidade
await tabSystemService.openTabWithPreset('driver', 'withDocs', driverData);
await tabSystemService.openTabWithSubTabs('vehicle', vehicleData, ['dados', 'documentos']);
await tabSystemService.openTabWithPreset('client', 'complete', clientData);
// Sistema detecta automaticamente:
// - Se é criação (id === 'new') ou edição
// - Quais sub-abas renderizar
// - Como salvar (create vs update)
Salvamento Genérico
// Sistema automático - sem código adicional necessário
// 1. Formulário é submetido
// 2. TabSystem emite evento 'formSubmit'
// 3. BaseDomainComponent recebe e processa
// 4. Auto-detecta createEntity() ou updateEntity()
// 5. Chama callbacks success/error automaticamente
// 6. Atualiza UI e remove modificações
// Customização opcional:
protected createEntity(data: any): Observable<any> {
return this.entityService.createWithValidation(data);
}
Mobile Footer Menu
// Uso automático - já integrado no layout
// Visível apenas em dispositivos móveis (≤768px)
// Controle programático
import { MobileMenuService } from './services/mobile-menu.service';
// Atualizar notificações
this.mobileMenuService.setMeliNotifications(5);
this.mobileMenuService.setVehicleNotifications(2);
Data Table (Integrada ao Framework)
// Configuração automática via BaseDomainComponent
protected getDomainConfig(): DomainConfig {
return {
columns: [
{ field: 'name', header: 'Nome', sortable: true },
{ field: 'email', header: 'Email', filterable: true }
],
// Ações automáticas: [Editar] [Novo] já incluídas
};
}
🎨 Design Guidelines
Cores Principais
:root {
--idt-primary: #FFC82E; // Dourado
--idt-secondary: #000000; // Preto
--idt-background: #FFFFFF; // Branco
--idt-surface: #F5F5F5; // Cinza claro
}
Breakpoints
// Mobile
@media (max-width: 768px) { }
// Tablet
@media (min-width: 769px) and (max-width: 1024px) { }
// Desktop
@media (min-width: 1025px) { }
🧪 Testes
Framework CRUD (NOVO)
// Teste do fluxo completo CRUD
describe('BaseDomainComponent', () => {
it('should auto-detect create operation', async () => {
const component = new ClientsComponent(...);
const mockData = { id: 'new', name: 'João' };
await component.onFormSubmit({
formData: mockData,
isNewItem: true,
onSuccess: jasmine.createSpy(),
onError: jasmine.createSpy()
});
expect(mockService.createClient).toHaveBeenCalledWith(mockData);
});
});
Executar Testes
# Testes unitários
npm run test
# Testes com cobertura
npm run test:coverage
# Testes end-to-end
npm run e2e
📦 Deploy
Ambiente de Desenvolvimento
# Servidor local
ng serve idt_app
# Acesso: http://localhost:4200
Ambiente de Produção
# Build otimizado
ng build idt_app --configuration production
# Arquivos gerados em: dist/idt_app/
🤝 Contribuição
Workflow
- Fork do repositório
- Branch para feature (
git checkout -b feature/nova-funcionalidade) - Commit das mudanças (
git commit -m 'Add: nova funcionalidade') - Push para branch (
git push origin feature/nova-funcionalidade) - Pull Request detalhado
Padrões do Framework CRUD
// ✅ CORRETO: Usar BaseDomainComponent para novos domínios
export class NewDomainComponent extends BaseDomainComponent<Entity> {
protected getDomainConfig(): DomainConfig { /* configuração */ }
}
// ✅ CORRETO: Usar API genérica para abrir abas
await tabSystemService.openTabWithPreset('entity', 'preset', data);
// ❌ INCORRETO: Reimplementar CRUD manualmente
// export class NewDomainComponent implements OnInit { /* código duplicado */ }
Commits Semânticos
feat: adiciona nova funcionalidade
fix: corrige bug específico
docs: atualiza documentação
style: melhora estilos
refactor: refatora código
test: adiciona testes
📞 Suporte
Canais de Suporte
- Issues: Para bugs e feature requests
- Discussions: Para dúvidas gerais
- Wiki: Para documentação adicional
FAQ
Q: Como implementar um novo domínio CRUD?
// Apenas estender BaseDomainComponent e configurar
export class NewDomainComponent extends BaseDomainComponent<T> {
protected getDomainConfig(): DomainConfig { /* config */ }
}
Q: Como personalizar salvamento de um domínio?
// Sobrescrever createEntity/updateEntity conforme necessário
protected createEntity(data: any): Observable<any> {
return this.service.customCreate(data);
}
Q: Como abrir aba com sub-abas específicas?
// Usar API genérica
await tabSystemService.openTabWithSubTabs('driver', data, ['dados', 'endereco']);
Q: Como forçar o mobile menu em desktop?
// Para testes/desenvolvimento
this.mobileMenuService.setVisibility(true);
📄 Licença
Este projeto está sob licença privada da Equipe GrupoPRA.
🔄 Changelog
v2.0.0 (Junho 2025) - FRAMEWORK CRUD UNIVERSAL
- 🚀 BaseDomainComponent: CRUD genérico para qualquer domínio
- 🚀 TabSystemComponent: Sistema de abas configuráveis com sub-abas
- 🚀 GenericTabFormComponent: Formulários automáticos
- 🚀 Sistema de Salvamento Genérico: Auto-detecta create/update
- 🚀 API Universal: Mesma interface para todos os domínios
- 🚀 Event-driven Architecture: Comunicação padronizada
- ✅ Backwards Compatible: Nenhuma funcionalidade removida
v1.0.0 (Maio 2025)
- ✅ Implementação do Mobile Footer Menu
- ✅ Sistema de notificações em tempo real
- ✅ Design system PraFrota aplicado
- ✅ Integração com layout principal
- ✅ Documentação completa
Última atualização: Junho 2025
Versão da documentação: 2.0.0
Framework: CRUD Universal v2.0.0
Mantido por: Equipe Grupo PRA