Aprende paso a paso cómo agregar un nuevo módulo a la arquitectura de Nebula ERP, basado en los ejemplos funcionales de Accounting y Tesorería
🎯 Basado en arquitectura Nx + Angular + Nebula UI Kit
▼
Cada módulo sigue esta estructura estándar de carpetas dentro del monorepo:
📁 libs/
📁 src/
📁 feature-[nombre-modulo]/
📄 [nombre-modulo].component.ts
📄 [nombre-modulo].component.html
📄 [nombre-modulo].component.scss
📄 [nombre-modulo].routes.ts
📁 [vistas-especificas]/
📄 index.ts
💡 Nota: El módulo de ejemplo será "sales" (Ventas). Reemplaza "sales" con el nombre de tu módulo.
▼
Ejecuta estos comandos para crear la estructura base del módulo:
Copiar
# Crear el nuevo módulo (ejemplo: "sales")
mkdir -p libs/sales/src/lib/feature-sales/src/lib
mkdir -p libs/sales/src/lib/feature-sales/src/lib/sales
mkdir -p libs/sales/src/lib/feature-sales/src/lib/customers
mkdir -p libs/sales/src/lib/feature-sales/src/lib/invoices
mkdir -p libs/sales/src/lib/feature-sales/src/lib/products
▼
Archivo: libs/sales/src/lib/feature-sales/src/lib/sales/sales.component.ts
Copiar
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import {
TabContainerComponent,
TabContainerConfig,
} from '@nebula/layout';
import { TabItem } from 'nebula-ui-kit';
@Component({
selector: 'app-sales',
standalone: true,
imports: [CommonModule, TabContainerComponent],
template: `
<app-tab-container
[config]="tabConfig"
[showClose]="true"
[contentMinHeight]="'500px'"
[emptyMessage]="'Selecciona una opción de Ventas para comenzar'"
(tabActivated)="onTabActivated($event)"
[showNavButtons]="true"
(tabClosed)="onTabClosed($event)">
</app-tab-container>
`
})
export class SalesComponent {
readonly tabConfig: TabContainerConfig = {
moduleKey: 'sales', // 🔑 Identificador único
moduleLabel: 'Ventas', // 📝 Etiqueta visible
enableBreadcrumb: true,
enableUrlSync: true
};
onTabActivated(tab: TabItem): void {
// Lógica cuando se activa una pestaña
}
onTabClosed(tabId: string): void {
// Lógica cuando se cierra una pestaña
}
}
▼
Archivo: libs/sales/src/lib/feature-sales/src/lib/sales.routes.ts
Copiar
import { Routes } from '@angular/router';
import { SalesComponent } from './sales/sales.component';
import { CustomersComponent } from './customers/customers.component';
import { InvoicesComponent } from './invoices/invoices.component';
import { ProductsComponent } from './products/products.component';
export const SALES_ROUTES: Routes = [
{
path: '',
component: SalesComponent,
title: 'Nebula ERP - Ventas',
data: {
showSidebar: true,
showHeader: true,
showBreadcrumb: true,
},
children: [
{
path: 'customers/list',
component: CustomersComponent,
title: 'Clientes',
data: { breadcrumb: 'Clientes' }
},
{
path: 'invoices/list',
component: InvoicesComponent,
title: 'Facturas',
data: { breadcrumb: 'Facturas' }
},
{
path: 'products/list',
component: ProductsComponent,
title: 'Productos',
data: { breadcrumb: 'Productos' }
}
],
runGuardsAndResolvers: 'paramsOrQueryParamsChange',
},
];
▼
Archivo: libs/sales/src/index.ts
Copiar
// Exportar las rutas para que puedan ser cargadas desde el layout
export { SALES_ROUTES } from './lib/feature-sales/src/lib/sales.routes';
// Exportar el componente principal (opcional)
export { SalesComponent } from './lib/feature-sales/src/lib/sales/sales.component';
▼
Archivo: libs/const/src/lib/modules.constant.ts
Copiar
export const MODULES = {
ACCOUNTING: 'accounting',
TREASURY: 'tesorería',
BUDGET: 'budget',
SALES: 'sales', // ✅ Agregar nuevo módulo
} as const;
export type ModuleValue = typeof MODULES[keyof typeof MODULES];
▼
Archivo: libs/config/src/lib/modules.config.ts
Copiar
import { MODULES } from '@nebula/const';
export const MODULES_CONFIG: Record = {
// ... configuraciones existentes ...
[MODULES.SALES]: { // ✅ Agregar nueva configuración
name: MODULES.SALES,
routePath: 'sales', // Ruta URL
basePath: 'sales',
aliases: ['ventas', 'selling'], // Alias opcionales
patterns: {
requiredPrefix: 'sales-masters', // Prefijo requerido para rutas
exceptions: ['home', 'dashboard', 'list', 'report'],
},
specialComponentKeys: [
'sales-masters/customers/list',
'sales-masters/products/list',
'invoices/list'
],
},
};
▼
Archivo: libs/const/src/lib/labels-menu.constant.ts
Copiar
export const LABELS_MAPPING_MENU: Record = {
// ... etiquetas existentes ...
// ✅ Agregar etiquetas para el nuevo módulo
MODULES_SALES_NAME: 'Ventas',
OPTIONS_SALES_PARAMETERS: 'Parámetros de Ventas',
SUB_MODULES_SALES_MASTERS_NAME: 'Maestros de Ventas',
OPTIONS_CUSTOMERS: 'Clientes',
OPTIONS_PRODUCTS: 'Productos',
OPTIONS_INVOICES: 'Facturas',
};
▼
Archivo: apps/shell/src/app/app.routes.ts
Copiar
export const routes: Routes = [
// ... rutas existentes ...
{
path: 'layout',
component: LayoutComponent,
canActivate: [authGuard],
children: [
// ... otros módulos ...
// ✅ Agregar nueva ruta para el módulo
{
path: 'sales',
loadChildren: () => import('@nebula/sales').then(m => m.SALES_ROUTES),
data: {
showSidebar: true,
showHeader: true,
showBreadcrumb: true,
},
},
],
},
];
▼
Archivo: libs/utils/src/lib/route-validator.ts
Copiar
export const VALID_ROUTES = [
// ... rutas existentes ...
// ✅ Agregar rutas válidas del nuevo módulo
'customers/list',
'invoices/list',
'products/list',
'sales-masters/customers/list',
'sales-masters/products/list',
] as const;
export function getModuleFromRoute(route: string): 'accounting' | 'tesorería' | 'budget' | 'sales' | 'products' | 'company' | null {
const lower = route.toLowerCase();
// ... condiciones existentes ...
// ✅ Agregar detección del nuevo módulo
if (lower.includes('/sales/') || lower.includes('customers') || lower.includes('invoices')) {
return 'sales';
}
return null;
}
▼
Archivo: tsconfig.base.json
Copiar
{
"compilerOptions": {
"paths": {
"@nebula/sales": ["libs/sales/src/index.ts"],
"@nebula/sales/*": ["libs/sales/src/lib/*"]
}
}
}
▼
⚠️ Importante: Después de modificar tsconfig.base.json, reinicia el servidor de desarrollo.
▼
🎯 Convenciones de nombres:
cost-center.component.ts)routePath en modules.config.ts🔧 Data en rutas: Siempre incluir estas propiedades en la configuración de rutas:
showSidebar: trueshowHeader: trueshowBreadcrumb: true✅ Validación: Agregar todas las rutas a VALID_ROUTES para evitar warnings en la consola.
🎉 Verificación:
nx serve shell/layout/sales📚 Guía basada en la arquitectura de Nebula ERP | Módulos de referencia: Accounting, Tesorería, Budget
© 2024 - Documentación para desarrolladores