feat(web): el stock por almacén oculta los almacenes sin cantidades (casilla marcada por defecto; el total sigue sumando todos)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a659276d9a
commit
aa520d574f
4 files changed
+25
-2
No files matched your search
@@ -148,6 +148,8 @@ export const ARTICULOS_SCREENS: readonly MasterScreen[] = [
|
|||||||
key: 'ItemWarehouseInfoCollection',
|
key: 'ItemWarehouseInfoCollection',
|
||||||
mode: 'replace',
|
mode: 'replace',
|
||||||
readonly: true,
|
readonly: true,
|
||||||
|
hideEmptyBy: ['InStock', 'Committed', 'Ordered'],
|
||||||
|
hideEmptyLabel: 'Solo almacenes con stock, comprometido o pedido',
|
||||||
identity: ['WarehouseCode'],
|
identity: ['WarehouseCode'],
|
||||||
columns: [
|
columns: [
|
||||||
{ key: 'WarehouseCode', title: 'Almacén', type: 'text', width: '110px' },
|
{ key: 'WarehouseCode', title: 'Almacén', type: 'text', width: '110px' },
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
[rows]="rowsOf(c)"
|
[rows]="rowsOf(c)"
|
||||||
(rowsChange)="setRows(c, $event)"
|
(rowsChange)="setRows(c, $event)"
|
||||||
[readonly]="!!c.readonly"
|
[readonly]="!!c.readonly"
|
||||||
|
[hideEmptyBy]="c.readonly ? (c.hideEmptyBy ?? null) : null"
|
||||||
|
[hideEmptyLabel]="c.hideEmptyLabel ?? 'Ocultar las filas en 0'"
|
||||||
[removable]="growable(c)"
|
[removable]="growable(c)"
|
||||||
[emptyText]="c.readonly ? 'Sin datos.' : 'Sin filas.'"
|
[emptyText]="c.readonly ? 'Sin datos.' : 'Sin filas.'"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ export interface MasterCollection {
|
|||||||
mode: 'replace' | 'merge';
|
mode: 'replace' | 'merge';
|
||||||
/** Campo que identifica una fila en `merge` (`PriceList`). */
|
/** Campo que identifica una fila en `merge` (`PriceList`). */
|
||||||
rowKey?: string;
|
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). */
|
/** Solo se muestra (el stock por almacén). */
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
/** Se pueden añadir y quitar filas (por defecto sí; no en `merge` ni en solo lectura). */
|
/** Se pueden añadir y quitar filas (por defecto sí; no en `merge` ni en solo lectura). */
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10)
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
imports: [ValueHelp],
|
imports: [ValueHelp],
|
||||||
template: `
|
template: `
|
||||||
|
@if (hideEmptyBy()) {
|
||||||
|
<label class="only"><input type="checkbox" [checked]="onlyFilled()" (change)="onlyFilled.set($any($event.target).checked)" /> {{ hideEmptyLabel() }}</label>
|
||||||
|
}
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
@@ -47,7 +50,7 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10)
|
|||||||
}
|
}
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@for (row of rows(); track $index; let i = $index) {
|
@for (row of shown(); track $index; let i = $index) {
|
||||||
<tr>
|
<tr>
|
||||||
<td class="rn">{{ i + 1 }}</td>
|
<td class="rn">{{ i + 1 }}</td>
|
||||||
@for (c of columns(); track c.key) {
|
@for (c of columns(); track c.key) {
|
||||||
@@ -99,7 +102,7 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10)
|
|||||||
</tr>
|
</tr>
|
||||||
} @empty {
|
} @empty {
|
||||||
<tr class="none">
|
<tr class="none">
|
||||||
<td [attr.colspan]="columns().length + 2">{{ emptyText() }}</td>
|
<td [attr.colspan]="columns().length + 2">{{ rows().length ? 'Ninguna fila cumple el filtro.' : emptyText() }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -130,6 +133,8 @@ const dateOnly = (v: unknown): string => (typeof v === 'string' ? v.slice(0, 10)
|
|||||||
`,
|
`,
|
||||||
styles: `
|
styles: `
|
||||||
:host { display: block; }
|
: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 { 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 { padding: 0; background: var(--btn); border: 1px solid var(--field-b); border-radius: var(--radius); cursor: pointer; }
|
||||||
.pick button:hover { background: var(--btn-h); }
|
.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). */
|
/** Se pueden quitar filas (por defecto, si la tabla es editable). */
|
||||||
readonly removable = input(true);
|
readonly removable = input(true);
|
||||||
readonly emptyText = input('Sin filas.');
|
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<readonly string[] | null>(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 lookupApi = inject(SlLookupApi);
|
||||||
private readonly http = inject(HttpClient);
|
private readonly http = inject(HttpClient);
|
||||||
|
|||||||
Reference in new issue
Block a user