feat(web): el selector de artículo de una línea admite varios (el primero completa la línea, los demás se insertan debajo)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1528f7cb96
commit
45c0ca536e
5 files changed
+37
-1
No files matched your search
@@ -49,6 +49,7 @@ export const DOCUMENT_LINE_COLUMNS: readonly GridColumn[] = [
|
||||
{ key: 'ItemName', title: 'Descripción' },
|
||||
],
|
||||
},
|
||||
multiple: true,
|
||||
apply: (item, line) => ({ ...line, ItemCode: item['ItemCode'], ItemDescription: item['ItemName'] ?? line['ItemDescription'] }),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -8,6 +8,8 @@ export type GridLine = Record<string, unknown>;
|
||||
export interface GridLookup {
|
||||
config: VhLookup;
|
||||
apply: (picked: ListRow, line: GridLine) => GridLine;
|
||||
/** Permite marcar varias filas: la primera completa la línea actual y cada una de las demás crea una línea nueva. */
|
||||
multiple?: boolean;
|
||||
}
|
||||
|
||||
export interface GridColumn {
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
[baseFilter]="cfg.baseFilter"
|
||||
[orderby]="cfg.orderby"
|
||||
[rowKey]="cfg.valueKey"
|
||||
[selection]="lookupMultiple() ? 'multiple' : 'single'"
|
||||
(selected)="lookupPicked($event)"
|
||||
(closed)="lookupClosed()"
|
||||
/>
|
||||
|
||||
@@ -218,11 +218,34 @@ describe('LinesGrid', () => {
|
||||
await tick();
|
||||
(q('.dlg tbody tr') as HTMLElement).click();
|
||||
await tick();
|
||||
(q('.dlg footer .btn.main') as HTMLElement).click();
|
||||
await tick();
|
||||
expect(lines()[0]).toMatchObject({ ItemCode: 'I00002', ItemDescription: 'DVD+R Disc 50-Pack', Quantity: 2, Price: 50, LineTotal: 100 });
|
||||
expect(el.querySelector('.dlg')).toBeNull();
|
||||
expect(document.activeElement).toBe(cell(0, 0));
|
||||
});
|
||||
|
||||
it('varios artículos: el primero completa la línea y los demás se insertan debajo', async () => {
|
||||
fixture.componentInstance.lines.set([line('A', 2, 50), line('Z', 1, 10)]);
|
||||
await tick();
|
||||
(qa('.pick button')[0] as HTMLButtonElement).click();
|
||||
await tick();
|
||||
ctrl.expectOne((r) => r.url === '/api/sl/Items').flush({
|
||||
value: [
|
||||
{ ItemCode: 'I1', ItemName: 'Uno' },
|
||||
{ ItemCode: 'I2', ItemName: 'Dos' },
|
||||
],
|
||||
'odata.count': '2',
|
||||
});
|
||||
await tick();
|
||||
qa('.dlg tbody tr').forEach((r) => (r as HTMLElement).click());
|
||||
await tick();
|
||||
(q('.dlg footer .btn.main') as HTMLElement).click();
|
||||
await tick();
|
||||
expect(lines().map((l) => l['ItemCode'])).toEqual(['I1', 'I2', 'Z']);
|
||||
expect(lines()[0]).toMatchObject({ Quantity: 2, Price: 50 });
|
||||
});
|
||||
|
||||
it('F4 abre la lista de la celda; una celda sin lista no', async () => {
|
||||
await key(0, 3, 'F4'); // almacén
|
||||
ctrl.expectOne((r) => r.url === '/api/sl/Warehouses').flush({ value: [], 'odata.count': '0' });
|
||||
|
||||
@@ -55,6 +55,7 @@ export class LinesGrid {
|
||||
protected readonly lookupTarget = signal<LookupTarget | null>(null);
|
||||
protected readonly multiOpen = signal(false);
|
||||
protected readonly lookup = computed(() => this.lookupTarget()?.column.lookup?.config);
|
||||
protected readonly lookupMultiple = computed(() => !!this.lookupTarget()?.column.lookup?.multiple);
|
||||
|
||||
protected cellText(line: GridLine, column: GridColumn): string {
|
||||
if (column.format) return column.format(line);
|
||||
@@ -216,7 +217,15 @@ export class LinesGrid {
|
||||
const picked = rows[0];
|
||||
const line = target ? this.lines()[target.row] : undefined;
|
||||
if (!target || !picked || !line || !target.column.lookup) return;
|
||||
this.replace(target.row, target.column.lookup.apply(picked, line), target.column.key);
|
||||
const lookup = target.column.lookup;
|
||||
this.replace(target.row, lookup.apply(picked, line), target.column.key);
|
||||
const rest = rows.slice(1).map((r) => {
|
||||
const added = lookup.apply(r, this.newLine()());
|
||||
return this.recalc()?.(added, target.column.key) ?? added;
|
||||
});
|
||||
if (rest.length) {
|
||||
this.lines.update((ls) => [...ls.slice(0, target.row + 1), ...rest, ...ls.slice(target.row + 1)]);
|
||||
}
|
||||
}
|
||||
|
||||
protected lookupClosed(): void {
|
||||
|
||||
Reference in new issue
Block a user