624 lines
19 KiB
Markdown
624 lines
19 KiB
Markdown
# 📚 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](./FORM_SYNCHRONIZATION_SOLUTION.md)** - 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](../src/app/shared/components/tab-system/README.md)** - 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](../src/app/shared/components/base-domain/base-domain.component.ts)** - 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](./API_INTEGRATION_GUIDE.md)** - 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](./mobile/MOBILE_FOOTER_MENU.md)** - 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](../src/app/shared/sidecard/README.md)** - 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](./ui-design/TYPOGRAPHY_SYSTEM.md)** - Sistema de tipografia completo
|
||
- **[Logo Relocation Guide](./ui-design/LOGO_RELOCATION_GUIDE.md)** - Guia de posicionamento de logo
|
||
- **[Cores e Temas](./DESIGN_SYSTEM.md)** *(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](./layout/LAYOUT_RESTRUCTURE_GUIDE.md)** - Guia de reestruturação de layout
|
||
- **[Sidebar Styling Guide](./layout/SIDEBAR_STYLING_GUIDE.md)** - Estilização da barra lateral
|
||
|
||
### 📋 Documentação Geral
|
||
- **[Cursor Integration](./general/CURSOR.md)** - Integração e configuração do Cursor
|
||
|
||
### 🚗 Módulos de Domínio *(Usando Framework Universal)*
|
||
- **[Motoristas](./DRIVERS.md)** *(implementado com BaseDomainComponent)*
|
||
- CRUD completo automatizado
|
||
- Sub-abas: dados, endereço, documentos
|
||
- Salvamento genérico integrado
|
||
|
||
- **[Veículos](./VEHICLES.md)** *(pronto para implementação)*
|
||
- Herda automaticamente todas as funcionalidades CRUD
|
||
- Configuração declarativa simples
|
||
- Sub-abas personalizáveis
|
||
|
||
### 🛣️ Rotas e Navegação
|
||
- **[Mercado Livre](./MERCADO_LIVRE.md)** *(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](./DASHBOARD.md)** *(em desenvolvimento)*
|
||
- Widgets personalizáveis
|
||
- Métricas em tempo real
|
||
- Exportação de dados
|
||
|
||
## 🚀 Getting Started
|
||
|
||
### Pré-requisitos
|
||
```bash
|
||
Node.js >= 18.x
|
||
Angular CLI >= 18.x
|
||
npm ou yarn
|
||
```
|
||
|
||
### Instalação
|
||
```bash
|
||
# 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
|
||
```bash
|
||
# 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#/](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**
|
||
```bash
|
||
# 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**
|
||
```typescript
|
||
// 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**
|
||
```typescript
|
||
// 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**
|
||
```typescript
|
||
// 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:
|
||
|
||
1. **☐ Consultar Swagger** - Identificar endpoints disponíveis
|
||
2. **☐ Definir Interface** - Baseada no schema da API
|
||
3. **☐ Implementar Service** - Com métodos CRUD padrão
|
||
4. **☐ Criar Component** - Estendendo BaseDomainComponent
|
||
5. **☐ Configurar Columns** - Baseadas nos campos da API
|
||
6. **☐ Testar Integração** - Verificar CRUD completo
|
||
|
||
### **🎮 Exemplo Prático**
|
||
|
||
```typescript
|
||
// 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)**
|
||
- [x] **BaseDomainComponent** - CRUD genérico para qualquer domínio
|
||
- [x] **TabSystemComponent** - Sistema de abas configuráveis
|
||
- [x] **GenericTabFormComponent** - Formulários automáticos
|
||
- [x] **Sistema de Salvamento Genérico** - Auto-detecta create/update
|
||
- [x] **Sub-abas Dinâmicas** - Configuração declarativa
|
||
- [x] **API Universal** - Mesma interface para todos os domínios
|
||
- [x] **Event-driven Architecture** - Comunicação padronizada
|
||
- [x] **Side Card Integration** - Informações contextuais
|
||
|
||
### ✅ **Recursos de UI**
|
||
- [x] **Mobile Footer Menu** - Navegação mobile otimizada
|
||
- [x] **Data Tables** - Tabelas com filtros e paginação
|
||
- [x] **Design System** - Cores e temas consistentes
|
||
- [x] **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)**
|
||
```typescript
|
||
// ✨ 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**
|
||
```typescript
|
||
// 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**
|
||
```typescript
|
||
// 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**
|
||
```typescript
|
||
// 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)**
|
||
```typescript
|
||
// 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
|
||
```scss
|
||
:root {
|
||
--idt-primary: #FFC82E; // Dourado
|
||
--idt-secondary: #000000; // Preto
|
||
--idt-background: #FFFFFF; // Branco
|
||
--idt-surface: #F5F5F5; // Cinza claro
|
||
}
|
||
```
|
||
|
||
### Breakpoints
|
||
```scss
|
||
// Mobile
|
||
@media (max-width: 768px) { }
|
||
|
||
// Tablet
|
||
@media (min-width: 769px) and (max-width: 1024px) { }
|
||
|
||
// Desktop
|
||
@media (min-width: 1025px) { }
|
||
```
|
||
|
||
## 🧪 Testes
|
||
|
||
### **Framework CRUD (NOVO)**
|
||
```typescript
|
||
// 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
|
||
```bash
|
||
# Testes unitários
|
||
npm run test
|
||
|
||
# Testes com cobertura
|
||
npm run test:coverage
|
||
|
||
# Testes end-to-end
|
||
npm run e2e
|
||
```
|
||
|
||
## 📦 Deploy
|
||
|
||
### Ambiente de Desenvolvimento
|
||
```bash
|
||
# Servidor local
|
||
ng serve idt_app
|
||
# Acesso: http://localhost:4200
|
||
```
|
||
|
||
### Ambiente de Produção
|
||
```bash
|
||
# Build otimizado
|
||
ng build idt_app --configuration production
|
||
|
||
# Arquivos gerados em: dist/idt_app/
|
||
```
|
||
|
||
## 🤝 Contribuição
|
||
|
||
### Workflow
|
||
1. **Fork** do repositório
|
||
2. **Branch** para feature (`git checkout -b feature/nova-funcionalidade`)
|
||
3. **Commit** das mudanças (`git commit -m 'Add: nova funcionalidade'`)
|
||
4. **Push** para branch (`git push origin feature/nova-funcionalidade`)
|
||
5. **Pull Request** detalhado
|
||
|
||
### **Padrões do Framework CRUD**
|
||
```typescript
|
||
// ✅ 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
|
||
```bash
|
||
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?**
|
||
```typescript
|
||
// Apenas estender BaseDomainComponent e configurar
|
||
export class NewDomainComponent extends BaseDomainComponent<T> {
|
||
protected getDomainConfig(): DomainConfig { /* config */ }
|
||
}
|
||
```
|
||
|
||
**Q: Como personalizar salvamento de um domínio?**
|
||
```typescript
|
||
// 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?**
|
||
```typescript
|
||
// Usar API genérica
|
||
await tabSystemService.openTabWithSubTabs('driver', data, ['dados', 'endereco']);
|
||
```
|
||
|
||
**Q: Como forçar o mobile menu em desktop?**
|
||
```typescript
|
||
// 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 |