testes/Modulos Angular/scripts/create-domain-v2-generators.js

820 lines
28 KiB
JavaScript

// 🎯 GERADORES V2.0 - CREATE-DOMAIN
// Arquivo complementar com as funções de geração para o create-domain-v2.js
const fs = require('fs');
const path = require('path');
// ===== GERAÇÃO DO COMPONENT V2.0 =====
function generateComponentV2(domainConfig) {
const componentName = capitalize(domainConfig.name);
return `import { Component, ChangeDetectorRef } from "@angular/core";
import { CommonModule, DatePipe${domainConfig.hasFooter ? ', CurrencyPipe' : ''} } from "@angular/common";
import { TitleService } from "../../shared/services/theme/title.service";
import { HeaderActionsService } from "../../shared/services/header-actions.service";
import { ${componentName}Service } from "./${domainConfig.name}.service";
import { ${componentName} } from "./${domainConfig.name}.interface";
import { TabSystemComponent } from "../../shared/components/tab-system/tab-system.component";
import { BaseDomainComponent, DomainConfig } from "../../shared/components/base-domain/base-domain.component";
import { TabFormConfig } from "../../shared/interfaces/generic-tab-form.interface";
import { TabFormConfigService } from "../../shared/components/tab-system/services/tab-form-config.service";
${domainConfig.hasBulkActions ? `import { ConfirmationService } from "../../shared/services/confirmation/confirmation.service";` : ''}
${domainConfig.hasDateRangeUtils ? `import { DateRangeShortcuts } from "../../shared/utils/date-range.utils";` : ''}
// 🔧 SearchOptionsLibrary inline (V2.0)
const SearchOptionsLibrary = {
statusComplex: [
{ value: 'active', label: 'Ativo' },
{ value: 'inactive', label: 'Inativo' },
{ value: 'pending', label: 'Pendente' },
{ value: 'cancelled', label: 'Cancelado' },
{ value: 'suspended', label: 'Suspenso' },
{ value: 'archived', label: 'Arquivado' }
]
};
/**
* 🎯 ${componentName}Component - Gestão de ${domainConfig.displayName}
*
* ✨ Implementa BaseDomainComponent + Registry Pattern
* 🚀 Auto-registro de configurações para escalabilidade infinita!
*
* 🆕 V2.0 Features:
${domainConfig.hasFooter ? ` * - FooterConfig: Configuração avançada de rodapé` : ''}
${domainConfig.hasCheckboxGrouped ? ` * - CheckboxGrouped: ${domainConfig.checkboxGroupedConfig?.groups?.length || 'N/A'} grupos configurados` : ''}
${domainConfig.hasBulkActions ? ` * - BulkActions: Ações em lote configuradas` : ''}
${domainConfig.hasDateRangeUtils ? ` * - DateRangeUtils: Integração automática` : ''}
*/
@Component({
selector: 'app-${domainConfig.name}',
standalone: true,
imports: [CommonModule, TabSystemComponent],
providers: [DatePipe${domainConfig.hasFooter ? ', CurrencyPipe' : ''}],
templateUrl: './${domainConfig.name}.component.html',
styleUrl: './${domainConfig.name}.component.scss'
})
export class ${componentName}Component extends BaseDomainComponent<${componentName}> {
constructor(
private ${domainConfig.name}Service: ${componentName}Service,
titleService: TitleService,
headerActionsService: HeaderActionsService,
cdr: ChangeDetectorRef,
private datePipe: DatePipe,
${domainConfig.hasFooter ? `private currencyPipe: CurrencyPipe,` : ''}
private tabFormConfigService: TabFormConfigService${domainConfig.hasBulkActions ? `,
private confirmationService: ConfirmationService` : ''}
) {
super(titleService, headerActionsService, cdr, ${domainConfig.name}Service);
this.registerFormConfig();
}
private registerFormConfig(): void {
this.tabFormConfigService.registerFormConfig('${domainConfig.name}', () => this.getFormConfig());
}
// ========================================
// 🎯 CONFIGURAÇÃO DO DOMÍNIO ${domainConfig.name.toUpperCase()}
// ========================================
protected override getDomainConfig(): DomainConfig {
return {
domain: '${domainConfig.name}',
title: '${domainConfig.displayName}',
entityName: '${domainConfig.name}',
pageSize: 50,
subTabs: [${generateSubTabsList(domainConfig)}],
columns: [
{
field: "id",
header: "Id",
sortable: true,
filterable: true,
search: true,
searchType: "number"
},
{
field: "name",
header: "Nome",
sortable: true,
filterable: true,
search: true,
searchType: "text"${domainConfig.hasFooter && domainConfig.footerConfig?.columns?.find(c => c.field === 'name') ? `,
footer: ${JSON.stringify(domainConfig.footerConfig.columns.find(c => c.field === 'name'), null, 10).replace(/"/g, "'")}` : ''}
},
${generateStatusColumn(domainConfig)}
${generateFooterColumns(domainConfig)}
{
field: "createdAt",
header: "Criado em",
sortable: true,
filterable: true,
search: true,
searchType: "date",
label: (date: any) => this.datePipe.transform(date, "dd/MM/yyyy HH:mm") || "-"
}
]${domainConfig.hasBulkActions ? `,
bulkActions: ${generateBulkActionsConfig(domainConfig)}` : ''}${domainConfig.hasSideCard || domainConfig.hasAdvancedSideCard ? `,
sideCard: ${generateSideCardConfig(domainConfig)}` : ''}
};
}
// ========================================
// 📋 CONFIGURAÇÃO COMPLETA DO FORMULÁRIO
// ========================================
getFormConfig(): TabFormConfig {
return {
title: 'Dados do ${componentName}',
entityType: '${domainConfig.name}',
fields: [],
submitLabel: 'Salvar ${componentName}',
showCancelButton: true,
subTabs: [
{
id: 'dados',
label: 'Dados Básicos',
icon: 'fa-info-circle',
enabled: true,
order: 1,
templateType: 'fields',
requiredFields: ['name'],
fields: [
{
key: 'name',
label: 'Nome',
type: 'text',
required: true,
placeholder: 'Digite o nome'
}${generateFormFields(domainConfig)}
]
}${generateFormSubTabs(domainConfig)}
]
};
}
${generateBulkActionMethods(domainConfig)}
}`;
}
// ===== GERAÇÃO DO SERVICE V2.0 =====
function generateServiceV2(domainConfig) {
const componentName = capitalize(domainConfig.name);
return `import { Injectable } from '@angular/core';
import { Observable, of, map } from 'rxjs';
import { catchError } from 'rxjs/operators';
${domainConfig.hasDateRangeUtils ? `import { firstValueFrom } from 'rxjs';` : ''}
import { ${componentName} } from './${domainConfig.name}.interface';
import { ApiClientService } from '../../shared/services/api/api-client.service';
import { DomainService } from '../../shared/components/base-domain/base-domain.component';
import { PaginatedResponse } from '../../shared/interfaces/paginate.interface';
${domainConfig.hasDateRangeUtils ? `import { DateRangeShortcuts } from '../../shared/utils/date-range.utils';` : ''}
/**
* 🎯 ${componentName}Service - Serviço para gestão de ${domainConfig.displayName}
*
* ✨ Implementa DomainService<${componentName}>
* 🚀 Padrões de nomenclatura obrigatórios: create, update, delete, getById, get${componentName}s
*
* 🆕 V2.0 Features:
${domainConfig.hasDateRangeUtils ? ` * - DateRangeUtils: Filtros de data automáticos` : ''}
* - ApiClientService: NUNCA usar HttpClient diretamente
* - Fallback: Dados mock para desenvolvimento
*/
@Injectable({
providedIn: 'root'
})
export class ${componentName}Service implements DomainService<${componentName}> {
constructor(
private apiClient: ApiClientService
) {}
// ========================================
// 🎯 IMPLEMENTAÇÃO DA INTERFACE DOMAINSERVICE
// ========================================
getEntities(page: number, pageSize: number, filters: any): Observable<{
data: ${componentName}[];
totalCount: number;
pageCount: number;
currentPage: number;
}> {
return this.get${componentName}s(page, pageSize, filters).pipe(
map(response => ({
data: response.data,
totalCount: response.totalCount,
pageCount: response.pageCount,
currentPage: response.currentPage
}))
);
}
create(data: any): Observable<${componentName}> {
return this.apiClient.post<${componentName}>('${domainConfig.name}s', data);
}
update(id: any, data: any): Observable<${componentName}> {
return this.apiClient.patch<${componentName}>(\`${domainConfig.name}s/\${id}\`, data);
}
// ========================================
// 🎯 MÉTODOS ESPECÍFICOS DO DOMÍNIO
// ========================================
get${componentName}s(
page = 1,
limit = 10,
filters?: any
): Observable<PaginatedResponse<${componentName}>> {
${domainConfig.hasDateRangeUtils ? `
// ✨ V2.0: DateRangeUtils automático
const dateFilters = filters?.dateRange ? DateRangeShortcuts.currentMonth() : {};
const allFilters = { ...filters, ...dateFilters };
` : 'const allFilters = filters || {};'}
let url = \`${domainConfig.name}s?page=\${page}&limit=\${limit}\`;
if (allFilters) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(allFilters)) {
if (value) {
params.append(key, value.toString());
}
}
if (params.toString()) {
url += \`&\${params.toString()}\`;
}
}
return this.apiClient.get<PaginatedResponse<${componentName}>>(url).pipe(
catchError(error => {
console.warn('⚠️ Backend indisponível, usando dados de fallback', error);
return of(this.getFallbackData(page, limit, allFilters));
})
);
}
getById(id: string): Observable<${componentName}> {
return this.apiClient.get<${componentName}>(\`${domainConfig.name}s/\${id}\`);
}
delete(id: string): Observable<void> {
return this.apiClient.delete<void>(\`${domainConfig.name}s/\${id}\`);
}
${generateBulkServiceMethods(domainConfig)}
private getFallbackData(page: number, limit: number, filters?: any): PaginatedResponse<${componentName}> {
const mockData: ${componentName}[] = ${generateMockData(domainConfig)};
const startIndex = (page - 1) * limit;
const endIndex = startIndex + limit;
const paginatedData = mockData.slice(startIndex, endIndex);
const totalPages = Math.ceil(mockData.length / limit);
return {
data: paginatedData,
totalCount: mockData.length,
pageCount: totalPages,
currentPage: page,
isFirstPage: page === 1,
isLastPage: page === totalPages,
nextPage: page < totalPages ? page + 1 : null,
previousPage: page > 1 ? page - 1 : null
};
}
}`;
}
// ===== GERAÇÃO DA INTERFACE V2.0 =====
async function generateInterfaceV2(domainConfig) {
const componentName = capitalize(domainConfig.name);
// 🚀 USAR API ANALYZER para geração automática de interface
try {
const { analyzeAPIForDomain } = require('./create-domain-v2-api-analyzer.js');
// 🔍 MODO FLEXÍVEL - Tenta API mas permite fallback
console.log(`🔍 Iniciando análise híbrida para domínio: ${domainConfig.name}`);
const apiAnalysis = await analyzeAPIForDomain(domainConfig.name, undefined, false);
if (apiAnalysis.success && apiAnalysis.interface) {
console.log(`✅ Interface gerada via API Analyzer - Estratégia: ${apiAnalysis.strategy}`);
console.log(`📊 Metadados:`, apiAnalysis.metadata);
// Adicionar campos específicos do V2.0 se não estiverem presentes
let interfaceCode = apiAnalysis.interface;
// 🔧 Adicionar campo de imagens PRIMEIRO (SideCard)
if (domainConfig.hasAdvancedSideCard && domainConfig.sideCardConfig?.imageField) {
const imageField = `${domainConfig.sideCardConfig.imageField}?: string[]; // Imagens do SideCard V2.0`;
if (!interfaceCode.includes(domainConfig.sideCardConfig.imageField)) {
// Adicionar antes do último }
const lastBraceIndex = interfaceCode.lastIndexOf('}');
interfaceCode = interfaceCode.slice(0, lastBraceIndex) + ` ${imageField}\n` + interfaceCode.slice(lastBraceIndex);
}
}
// 🔧 Adicionar checkbox grouped DEPOIS (para não interferir com o replace)
if (domainConfig.hasCheckboxGrouped) {
const checkboxField = `${domainConfig.checkboxGroupedConfig?.fieldName}?: {
[groupId: string]: {
[itemId: string]: boolean;
};
}; // Checkbox agrupado V2.0`;
if (!interfaceCode.includes(domainConfig.checkboxGroupedConfig?.fieldName)) {
// Adicionar antes do último }
const lastBraceIndex = interfaceCode.lastIndexOf('}');
interfaceCode = interfaceCode.slice(0, lastBraceIndex) + ` ${checkboxField}\n` + interfaceCode.slice(lastBraceIndex);
}
}
// Adicionar comentário sobre a estratégia usada
const strategyComment = `/**
* 🎯 ${componentName} Interface - V2.0 + API Analysis
*
* ✨ Auto-generated using API Analyzer - Strategy: ${apiAnalysis.strategy}
* 📊 Source: ${apiAnalysis.metadata.source || 'unknown'}
* 🔗 Fields detected: ${apiAnalysis.fields.length}
*
* 🆕 V2.0 Features Enhanced:
${domainConfig.hasCheckboxGrouped ? ` * - ${domainConfig.checkboxGroupedConfig?.fieldName}: Checkbox agrupado configurado` : ''}
${domainConfig.hasAdvancedSideCard ? ` * - ${domainConfig.sideCardConfig?.imageField}: Imagens para SideCard avançado` : ''}
*/`;
return interfaceCode.replace(/\/\*\*[\s\S]*?\*\//, strategyComment);
}
} catch (error) {
// 🚨 TRATAR ERROS CRÍTICOS DO MODO RIGOROSO
if (error.code === 'ENDPOINT_ACCESS_FAILED') {
console.error(`\n🚨 ERRO CRÍTICO: ${error.message}`);
console.error(`🔗 Endpoint: ${error.endpoint}`);
console.error(`\n📋 POSSÍVEIS SOLUÇÕES:`);
console.error(`1. 🔐 Verificar autenticação (Bearer token necessário?)`);
console.error(`2. 🌐 Verificar CORS (bloqueando requisições?)`);
console.error(`3. 📁 Verificar estrutura da resposta (tem campo 'data'?)`);
console.error(`4. 🔧 Verificar se endpoint está ativo no backend`);
console.error(`\n❌ INTERROMPENDO GERAÇÃO DE DOMÍNIO`);
throw error;
}
if (error.code === 'STRICT_MODE_FAILURE') {
console.error(`\n🚨 ERRO CRÍTICO: ${error.message}`);
console.error(`\n📋 AÇÕES NECESSÁRIAS:`);
console.error(`1. 🔍 Verificar se endpoint /${domainConfig.name}/ existe na API`);
console.error(`2. 🔐 Verificar configuração de autenticação`);
console.error(`3. 🌐 Verificar configuração de CORS`);
console.error(`4. 📊 Verificar estrutura da resposta da API`);
console.error(`\n❌ INTERROMPENDO GERAÇÃO DE DOMÍNIO`);
throw error;
}
// Outros erros - fallback com aviso
console.log(`⚠️ API Analyzer falhou: ${error.message}`);
console.log('🔄 Usando geração de interface padrão...');
}
// ✨ FALLBACK: Geração padrão V2.0 (se API Analyzer falhar)
return `/**
* 🎯 ${componentName} Interface - V2.0 Fallback
*
* Representa a estrutura de dados de ${domainConfig.displayName.toLowerCase()} no sistema.
*
* ⚠️ Generated using fallback template (API not available)
*
* 🆕 V2.0 Features:
${domainConfig.hasCheckboxGrouped ? ` * - ${domainConfig.checkboxGroupedConfig.fieldName}: Checkbox agrupado configurado` : ''}
${domainConfig.hasColor ? ` * - color: Configuração de cor com name e code` : ''}
*/
export interface ${componentName} {
id: number;
name: string;
${domainConfig.hasStatus ? `status: string;` : ''}
${domainConfig.hasColor ? `color?: {
name: string;
code: string;
};` : ''}
${domainConfig.hasKilometer ? `odometer?: number;` : ''}
${domainConfig.hasCheckboxGrouped ? `${domainConfig.checkboxGroupedConfig.fieldName}?: {
[groupId: string]: {
[itemId: string]: boolean;
};
};` : ''}
description?: string;
createdAt?: string;
updatedAt?: string;
${domainConfig.hasAdvancedSideCard && domainConfig.sideCardConfig.imageField ? `${domainConfig.sideCardConfig.imageField}?: string[];` : ''}
}`;
}
// ===== HELPERS =====
function generateSubTabsList(domainConfig) {
const tabs = ["'dados'"];
if (domainConfig.hasPhotos) tabs.push("'photos'");
if (domainConfig.hasCheckboxGrouped) tabs.push(`'${domainConfig.checkboxGroupedConfig.fieldName}'`);
return tabs.join(', ');
}
function generateStatusColumn(domainConfig) {
if (!domainConfig.hasStatus) return '';
const searchOptions = domainConfig.hasExtendedSearchOptions && domainConfig.searchOptionsConfig?.useStatusComplex
? 'SearchOptionsLibrary.statusComplex'
: `[
{ value: 'active', label: 'Ativo' },
{ value: 'inactive', label: 'Inativo' }
]`;
return `{
field: "status",
header: "Status",
sortable: true,
filterable: true,
allowHtml: true,
search: true,
searchType: "select",
searchOptions: ${searchOptions},
label: (value: any) => {
const statusConfig: { [key: string]: { label: string, class: string } } = {
'active': { label: 'Ativo', class: 'status-active' },
'inactive': { label: 'Inativo', class: 'status-inactive' }
};
const config = statusConfig[value?.toLowerCase()] || { label: value, class: 'status-unknown' };
return \`<span class="status-badge \${config.class}">\${config.label}</span>\`;
}
},`;
}
function generateFooterColumns(domainConfig) {
if (!domainConfig.hasFooter || !domainConfig.footerConfig?.columns?.length) return '';
return domainConfig.footerConfig.columns
.filter(col => col.field !== 'name') // Já incluído na coluna name
.map(col => `{
field: "${col.field}",
header: "${capitalize(col.field)}",
sortable: true,
filterable: true,
search: true,
searchType: "${col.type === 'count' ? 'number' : 'text'}",
${col.format === 'currency' ? `label: (value: any) => {
if (!value) return '-';
return this.currencyPipe.transform(value, 'BRL', 'symbol', '1.2-2', 'pt-BR') || '-';
},` : ''}
footer: ${JSON.stringify(col, null, 10).replace(/"/g, "'")}
}`)
.join(',\n ');
}
function generateBulkActionsConfig(domainConfig) {
if (!domainConfig.hasBulkActions) return '';
// 🔧 Ações padrão se não configuradas
const defaultActions = [
{
id: 'delete',
label: 'Excluir Selecionados',
icon: 'delete',
action: 'this.bulkDelete(selectedItems)'
}
];
const actions = (domainConfig.bulkActionsConfig?.actions || defaultActions)
.map(action => {
if (action.subActions) {
return `{
id: '${action.id}',
label: '${action.label}',
icon: '${action.icon}',
subActions: [
${action.subActions.map(sub => `{
id: '${sub.id}',
label: '${sub.label}',
icon: '${sub.icon}',
action: ${sub.action}
}`).join(',\n ')}
]
}`;
} else {
return `{
id: '${action.id}',
label: '${action.label}',
icon: '${action.icon}',
action: ${action.action}
}`;
}
})
.join(',\n ');
return `[
${actions}
]`;
}
function generateSideCardConfig(domainConfig) {
if (domainConfig.hasAdvancedSideCard) {
return `{
enabled: true,
title: "Resumo do ${capitalize(domainConfig.name)}",
position: "right",
width: "400px",
component: "summary",
data: {
${domainConfig.sideCardConfig.imageField ? `imageField: "${domainConfig.sideCardConfig.imageField}",` : ''}
displayFields: [
{
key: "name",
label: "Nome",
type: "text"
},
${domainConfig.hasStatus ? `{
key: "status",
label: "Status",
type: "status"
},` : ''}
{
key: "createdAt",
label: "Criado em",
type: "date"
}
],
${domainConfig.hasStatus ? `statusConfig: {
"active": { label: "Ativo", color: "#d4edda", icon: "fa-check-circle" },
"inactive": { label: "Inativo", color: "#f8d7da", icon: "fa-times-circle" }
}` : ''}
}
}`;
}
return `{
enabled: true,
title: "Resumo do ${capitalize(domainConfig.name)}",
position: "right",
width: "400px",
component: "summary",
data: {
displayFields: [
{
key: "name",
label: "Nome",
type: "text"
},
${domainConfig.hasStatus ? `{
key: "status",
label: "Status",
type: "status"
},` : ''}
{
key: "createdAt",
label: "Criado em",
type: "date"
}
],
statusField: "status"
}
}`;
}
function generateFormFields(domainConfig) {
let fields = [];
if (domainConfig.hasStatus) {
const statusOptions = domainConfig.hasExtendedSearchOptions && domainConfig.searchOptionsConfig.useStatusComplex
? `[
{ value: 'active', label: 'Ativo' },
{ value: 'inactive', label: 'Inativo' },
{ value: 'pending', label: 'Pendente' },
{ value: 'processing', label: 'Processando' },
{ value: 'completed', label: 'Concluído' },
{ value: 'cancelled', label: 'Cancelado' }
]`
: `[
{ value: 'active', label: 'Ativo' },
{ value: 'inactive', label: 'Inativo' }
]`;
fields.push(`{
key: 'status',
label: 'Status',
type: 'select',
required: true,
options: ${statusOptions}
}`);
}
if (domainConfig.hasKilometer) {
fields.push(`{
key: 'odometer',
label: 'Quilometragem',
type: 'kilometer-input',
placeholder: '0',
formatOptions: {
locale: 'pt-BR',
useGrouping: true,
suffix: ' km'
}
}`);
}
if (domainConfig.hasColor) {
fields.push(`{
key: 'color',
label: 'Cor',
type: 'color-input',
required: false,
options: [
{ value: { name: 'Branco', code: '#ffffff' }, label: 'Branco' },
{ value: { name: 'Preto', code: '#000000' }, label: 'Preto' },
{ value: { name: 'Azul', code: '#0000ff' }, label: 'Azul' },
{ value: { name: 'Vermelho', code: '#ff0000' }, label: 'Vermelho' }
]
}`);
}
return fields.length > 0 ? ',\n ' + fields.join(',\n ') : '';
}
function generateFormSubTabs(domainConfig) {
let subTabs = [];
if (domainConfig.hasPhotos) {
subTabs.push(`{
id: 'photos',
label: 'Fotos',
icon: 'fa-camera',
enabled: true,
order: 2,
templateType: 'component',
requiredFields: [],
dynamicComponent: {
selector: 'app-send-image',
inputs: {
entityType: '${domainConfig.name}',
maxFiles: 5,
acceptedTypes: ['image/jpeg', 'image/png']
}
}
}`);
}
if (domainConfig.hasCheckboxGrouped) {
subTabs.push(`{
id: '${domainConfig.checkboxGroupedConfig.fieldName}',
label: '${capitalize(domainConfig.checkboxGroupedConfig.fieldName)}',
icon: 'fa-cog',
enabled: true,
order: ${subTabs.length + 3},
templateType: 'fields',
requiredFields: ['${domainConfig.checkboxGroupedConfig.fieldName}'],
fields: [
{
key: '${domainConfig.checkboxGroupedConfig.fieldName}',
label: '${capitalize(domainConfig.checkboxGroupedConfig.fieldName)}',
type: 'checkbox-grouped',
hideLabel: true,
groups: ${JSON.stringify(domainConfig.checkboxGroupedConfig.groups, null, 14).replace(/"/g, "'")}
}
]
}`);
}
return subTabs.length > 0 ? ',\n ' + subTabs.join(',\n ') : '';
}
function generateBulkActionMethods(domainConfig) {
if (!domainConfig.hasBulkActions) return '';
const componentName = capitalize(domainConfig.name);
return `
// ========================================
// ⚡ BULK ACTIONS V2.0
// ========================================
async bulkDelete(selectedItems: ${componentName}[]) {
const confirmed = await this.confirmationService.confirm({
title: 'Confirmar exclusão',
message: \`Tem certeza que deseja excluir \${selectedItems.length} \${selectedItems.length === 1 ? 'item' : 'itens'}?\`,
confirmText: 'Excluir'
});
if (confirmed) {
// Implementar lógica de exclusão em lote
console.log('Excluindo itens:', selectedItems);
}
}
async bulkExport(selectedItems: ${componentName}[]) {
// Implementar lógica de exportação
console.log('Exportando itens:', selectedItems);
}
${domainConfig.bulkActionsConfig.type === 'advanced' ? `
async updateViaExternalAPI(selectedItems: ${componentName}[]) {
// Implementar atualização via API externa
console.log('Atualizando via API externa:', selectedItems);
}
async bulkEdit(selectedItems: ${componentName}[]) {
// Implementar edição em lote
console.log('Edição em lote:', selectedItems);
}
async bulkStatusChange(selectedItems: ${componentName}[]) {
// Implementar alteração de status em lote
console.log('Alterando status:', selectedItems);
}` : ''}`;
}
function generateBulkServiceMethods(domainConfig) {
if (!domainConfig.hasBulkActions) return '';
const componentName = capitalize(domainConfig.name);
return `
// ========================================
// ⚡ BULK OPERATIONS V2.0
// ========================================
bulkDelete(ids: string[]): Observable<void> {
return this.apiClient.post<void>(\`${domainConfig.name}s/bulk-delete\`, { ids });
}
bulkUpdate(updates: Array<{id: string, data: Partial<${componentName}>}>): Observable<${componentName}[]> {
return this.apiClient.patch<${componentName}[]>(\`${domainConfig.name}s/bulk\`, { updates });
}
${domainConfig.hasDateRangeUtils ? `
// ✨ V2.0: Exemplo de uso do DateRangeUtils
async getRecentItems(): Promise<${componentName}[]> {
const dateFilters = DateRangeShortcuts.last30Days();
const response = await firstValueFrom(this.get${componentName}s(1, 100, dateFilters));
return response.data;
}` : ''}`;
}
function generateMockData(domainConfig) {
const mockItems = [];
for (let i = 1; i <= 5; i++) {
const item = {
id: i,
name: `${domainConfig.displayName} ${i}`,
createdAt: new Date(Date.now() - i * 24 * 60 * 60 * 1000).toISOString(),
updatedAt: new Date(Date.now() - i * 24 * 60 * 60 * 1000).toISOString()
};
if (domainConfig.hasStatus) {
item.status = i % 2 === 0 ? 'active' : 'inactive';
}
if (domainConfig.hasKilometer) {
item.odometer = Math.floor(Math.random() * 100000);
}
if (domainConfig.hasColor) {
const colors = [
{ name: 'Branco', code: '#ffffff' },
{ name: 'Preto', code: '#000000' },
{ name: 'Azul', code: '#0000ff' }
];
item.color = colors[i % colors.length];
}
mockItems.push(item);
}
return JSON.stringify(mockItems, null, 4);
}
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
module.exports = {
generateComponentV2,
generateServiceV2,
generateInterfaceV2,
generateSubTabsList,
generateStatusColumn,
generateFooterColumns,
generateBulkActionsConfig,
generateSideCardConfig,
generateFormFields,
generateFormSubTabs,
generateBulkActionMethods,
generateBulkServiceMethods,
generateMockData,
capitalize
};