feat: puntos de extensión por cliente para el menú, las rutas del frontend y los permisos del proxy del Service Layer
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8ba845cc23
commit
3caf94609d
10 files changed
+178
-31
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import { isDevMode } from '@angular/core';
|
||||
import type { Route, Routes } from '@angular/router';
|
||||
import { MENU } from '@basic-erp/sap-types';
|
||||
import { CLIENT_PATHS, CLIENT_ROUTES } from './client-routes';
|
||||
import { authGuard, guestGuard, menuLoadedGuard, permissionGuard } from './core/auth/guards';
|
||||
import { DOCUMENT_PATHS } from './features/documents/document-paths';
|
||||
import { JOURNAL_PATH } from './features/finance/journal-paths';
|
||||
@@ -146,7 +147,7 @@ const adminRoutes: Routes = [
|
||||
];
|
||||
|
||||
/** Resto de pantallas del menú (maestros, etc.): aún sin construir. */
|
||||
const builtPaths = new Set([...DOCUMENT_PATHS, ...MASTER_PATHS, ...PAYMENT_PATHS, JOURNAL_PATH, '/reportes/ejecutar', '/reportes/matricula', '/admin/permisos', '/admin/auditoria']);
|
||||
const builtPaths = new Set([...CLIENT_PATHS, ...DOCUMENT_PATHS, ...MASTER_PATHS, ...PAYMENT_PATHS, JOURNAL_PATH, '/reportes/ejecutar', '/reportes/matricula', '/admin/permisos', '/admin/auditoria']);
|
||||
const pendingRoutes: Routes = MENU.flatMap((m) => m.items)
|
||||
.filter((item) => !builtPaths.has(item.path))
|
||||
.map(
|
||||
@@ -181,6 +182,7 @@ export const routes: Routes = [
|
||||
...journalRoutes,
|
||||
...reportRoutes,
|
||||
...adminRoutes,
|
||||
...CLIENT_ROUTES,
|
||||
...pendingRoutes,
|
||||
],
|
||||
},
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { CLIENT_PATHS, CLIENT_ROUTES, clientRoute } from './client-routes';
|
||||
|
||||
describe('rutas de cliente', () => {
|
||||
it('una pantalla de cliente cuelga de su ruta de menú, con permiso y en diferido', () => {
|
||||
const r = clientRoute('/inventario/ejemplo', 'Ejemplo', async () => class {});
|
||||
expect(r.path).toBe('inventario/ejemplo');
|
||||
expect(r.data).toEqual({ path: '/inventario/ejemplo', title: 'Ejemplo' });
|
||||
expect(r.canActivate).toHaveLength(1);
|
||||
expect(r.loadComponent).toBeTypeOf('function');
|
||||
});
|
||||
|
||||
it('las rutas de cliente salen de la lista de rutas', () => {
|
||||
expect(CLIENT_PATHS).toEqual(CLIENT_ROUTES.map((r) => `/${r.path}`));
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Route, Routes } from '@angular/router';
|
||||
import { permissionGuard } from './core/auth/guards';
|
||||
|
||||
/** Una pantalla de cliente: ruta del menú (`/inventario/inmovilizar-lotes`), título y su componente en diferido. */
|
||||
export const clientRoute = (path: string, title: string, loadComponent: NonNullable<Route['loadComponent']>): Route => ({
|
||||
path: path.slice(1),
|
||||
canActivate: [permissionGuard],
|
||||
data: { path, title },
|
||||
loadComponent,
|
||||
});
|
||||
|
||||
/**
|
||||
* Pantallas propias del cliente (vacío en `main`): cada una con su entrada en `menu.extensions.ts` de `libs/sap-types`.
|
||||
* Se cargan en diferido, como todas.
|
||||
*
|
||||
* Ejemplo:
|
||||
*
|
||||
* clientRoute('/inventario/inmovilizar-lotes', 'Inmovilizar lotes', () => import('./features/client/inmovilizar.page').then((m) => m.InmovilizarPage)),
|
||||
*/
|
||||
export const CLIENT_ROUTES: Routes = [];
|
||||
|
||||
/** Las rutas de menú que ya tienen pantalla de cliente (no se muestran como «en construcción»). */
|
||||
export const CLIENT_PATHS: readonly string[] = CLIENT_ROUTES.map((r) => `/${r.path}`);
|
||||
Reference in new issue
Block a user