diff --git a/apps/web/src/app/features/masters/articulos/articulos.screens.ts b/apps/web/src/app/features/masters/articulos/articulos.screens.ts index d295792..1fc6e3a 100644 --- a/apps/web/src/app/features/masters/articulos/articulos.screens.ts +++ b/apps/web/src/app/features/masters/articulos/articulos.screens.ts @@ -148,6 +148,8 @@ export const ARTICULOS_SCREENS: readonly MasterScreen[] = [ key: 'ItemWarehouseInfoCollection', mode: 'replace', readonly: true, + hideEmptyBy: ['InStock', 'Committed', 'Ordered'], + hideEmptyLabel: 'Solo almacenes con stock, comprometido o pedido', identity: ['WarehouseCode'], columns: [ { key: 'WarehouseCode', title: 'Almacén', type: 'text', width: '110px' }, diff --git a/apps/web/src/app/features/masters/master-form.page.html b/apps/web/src/app/features/masters/master-form.page.html index 43767e6..dff1d05 100644 --- a/apps/web/src/app/features/masters/master-form.page.html +++ b/apps/web/src/app/features/masters/master-form.page.html @@ -45,6 +45,8 @@ [rows]="rowsOf(c)" (rowsChange)="setRows(c, $event)" [readonly]="!!c.readonly" + [hideEmptyBy]="c.readonly ? (c.hideEmptyBy ?? null) : null" + [hideEmptyLabel]="c.hideEmptyLabel ?? 'Ocultar las filas en 0'" [removable]="growable(c)" [emptyText]="c.readonly ? 'Sin datos.' : 'Sin filas.'" /> diff --git a/apps/web/src/app/features/masters/master-types.ts b/apps/web/src/app/features/masters/master-types.ts index 43c7a6f..b382edd 100644 --- a/apps/web/src/app/features/masters/master-types.ts +++ b/apps/web/src/app/features/masters/master-types.ts @@ -20,6 +20,9 @@ export interface MasterCollection { mode: 'replace' | 'merge'; /** Campo que identifica una fila en `merge` (`PriceList`). */ rowKey?: string; + /** Columnas numéricas por las que se ocultan las filas en 0, con una casilla marcada por defecto (solo con `readonly`). */ + hideEmptyBy?: readonly string[]; + hideEmptyLabel?: string; /** Solo se muestra (el stock por almacén). */ readonly?: boolean; /** Se pueden añadir y quitar filas (por defecto sí; no en `merge` ni en solo lectura). */ diff --git a/apps/web/src/app/shared/grid/rows-table.ts b/apps/web/src/app/shared/grid/rows-table.ts index 8ce887f..81b2396 100644 --- a/apps/web/src/app/shared/grid/rows-table.ts +++ b/apps/web/src/app/shared/grid/rows-table.ts @@ -22,6 +22,9 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10) changeDetection: ChangeDetectionStrategy.OnPush, imports: [ValueHelp], template: ` + @if (hideEmptyBy()) { + + }
@@ -47,7 +50,7 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10) } - @for (row of rows(); track $index; let i = $index) { + @for (row of shown(); track $index; let i = $index) { @for (c of columns(); track c.key) { @@ -99,7 +102,7 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10) } @empty { - + } @@ -130,6 +133,8 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10) `, styles: ` :host { display: block; } + .only { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 6px; cursor: pointer; } + .only input { width: auto; height: auto; margin: 0; } .pick { display: grid; grid-template-columns: minmax(0, 1fr) 22px; } .pick button { padding: 0; background: var(--btn); border: 1px solid var(--field-b); border-radius: var(--radius); cursor: pointer; } .pick button:hover { background: var(--btn-h); } @@ -164,6 +169,17 @@ export class RowsTable { /** Se pueden quitar filas (por defecto, si la tabla es editable). */ readonly removable = input(true); readonly emptyText = input('Sin filas.'); + /** Columnas numéricas por las que se puede ocultar las filas en 0 (solo lectura): aparece una casilla encima de la tabla, marcada. */ + readonly hideEmptyBy = input(null); + readonly hideEmptyLabel = input('Ocultar las filas en 0'); + protected readonly onlyFilled = signal(true); + /** Las filas que se ven; los totales siguen sumando todas. */ + protected readonly shown = computed(() => { + const keys = this.hideEmptyBy(); + const rows = this.rows(); + if (!keys || !this.onlyFilled()) return rows; + return rows.filter((r) => keys.some((k) => Number(r[k]) !== 0 && Number.isFinite(Number(r[k])))); + }); private readonly lookupApi = inject(SlLookupApi); private readonly http = inject(HttpClient);
{{ i + 1 }}
{{ emptyText() }}{{ rows().length ? 'Ninguna fila cumple el filtro.' : emptyText() }}