feat(web): lista de documentos con barra de filtros y búsqueda por columna
Cada pantalla de documento del menú abre primero la lista de los últimos documentos; desde ahí se crea uno (/nuevo) o se abre uno (/:docEntry). - sbo-list-view: título, botón de alta, barra de filtros, tabla y paginación (50 por página, más recientes primero). - sbo-filter-bar (como el FilterBar del mini-erp): búsqueda por la columna activa + filtros declarativos text / select (con valor por defecto) / multi (chips + lista de valores) / date (siempre rango [desde – hasta]), con Ir y Limpiar. Ir aplica búsqueda y filtros en una sola consulta. - Búsqueda numérica por igualdad (DocNum eq 314) con aviso si no es número; una columna con texto calculado (format) ya no es buscable por defecto. - Piezas compartidas con sbo-value-help, que se refactoriza sobre ellas: createSlList (estado de búsqueda/paginación), sbo-data-table, sbo-pager, sbo-search-bar. Insignias de estado (tone) y estilos de botón globales. - DOCUMENT_SCREENS: columnas y filtros de 17 documentos (ventas, compras, inventario) según los campos verificados en el Service Layer real (PurchaseRequests no tiene CardCode; StockTransfers no tiene estado). - Rutas generadas desde el registro: lista, nuevo y :docEntry bajo el permiso de la ruta de menú. El formulario es un marcador (paso 9). - Presupuesto: el aviso del bundle inicial sube a 300 kB; httpResource aporta ~18 kB al chunk compartido (278 kB, 78 kB comprimido). - Verificado en Chrome contra SAP real: 49 órdenes abiertas, 314 en total, rango de fechas, chips de monedas, búsqueda por número, navegación y botón atrás, tema oscuro; ofertas (4391), transferencias y entradas. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
68caf401a7
commit
598307960e
36 files changed
+2163
-359
No files matched your search
@@ -1,14 +1,47 @@
|
||||
import type { Routes } from '@angular/router';
|
||||
import type { Route, Routes } from '@angular/router';
|
||||
import { MENU } from '@basic-erp/sap-types';
|
||||
import { authGuard, guestGuard, menuLoadedGuard, permissionGuard } from './core/auth/guards';
|
||||
import { DOCUMENT_SCREENS, menuLabel } from './features/documents/document-screens';
|
||||
|
||||
/** Una ruta por pantalla del menú; las que aún no existen muestran "no disponible". */
|
||||
const screens: Routes = MENU.flatMap((m) => m.items).map((item) => ({
|
||||
path: item.path.slice(1),
|
||||
canActivate: [permissionGuard],
|
||||
data: { path: item.path, title: item.label },
|
||||
loadComponent: () => import('./features/shared/coming-soon.page').then((m) => m.ComingSoonPage),
|
||||
}));
|
||||
/**
|
||||
* Pantallas de documento: la ruta del menú muestra la lista de los últimos documentos;
|
||||
* `nuevo` abre el formulario vacío y `:docEntry` el documento para ver o editar.
|
||||
* El permiso de menú gobierna las tres (el guard del padre; `data` se hereda en los hijos).
|
||||
*/
|
||||
const documentRoutes: Routes = DOCUMENT_SCREENS.map(
|
||||
(screen): Route => ({
|
||||
path: screen.path.slice(1),
|
||||
canActivate: [permissionGuard],
|
||||
data: { path: screen.path, title: menuLabel(screen.path), screen },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
loadComponent: () => import('./features/documents/document-list.page').then((m) => m.DocumentListPage),
|
||||
},
|
||||
{
|
||||
path: 'nuevo',
|
||||
loadComponent: () => import('./features/documents/document-form.page').then((m) => m.DocumentFormPage),
|
||||
},
|
||||
{
|
||||
path: ':docEntry',
|
||||
loadComponent: () => import('./features/documents/document-form.page').then((m) => m.DocumentFormPage),
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
/** Resto de pantallas del menú (maestros, etc.): aún sin construir. */
|
||||
const documentPaths = new Set(DOCUMENT_SCREENS.map((s) => s.path));
|
||||
const pendingRoutes: Routes = MENU.flatMap((m) => m.items)
|
||||
.filter((item) => !documentPaths.has(item.path))
|
||||
.map(
|
||||
(item): Route => ({
|
||||
path: item.path.slice(1),
|
||||
canActivate: [permissionGuard],
|
||||
data: { path: item.path, title: item.label },
|
||||
loadComponent: () => import('./features/shared/coming-soon.page').then((m) => m.ComingSoonPage),
|
||||
}),
|
||||
);
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
@@ -26,7 +59,8 @@ export const routes: Routes = [
|
||||
path: 'sin-acceso',
|
||||
loadComponent: () => import('./features/shared/no-access.page').then((m) => m.NoAccessPage),
|
||||
},
|
||||
...screens,
|
||||
...documentRoutes,
|
||||
...pendingRoutes,
|
||||
],
|
||||
},
|
||||
{ path: '**', redirectTo: '' },
|
||||
|
||||
Reference in new issue
Block a user