From 8ff9ed216c6c37f75fd008367586e79c52b62508 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Fri, 14 Aug 2026 10:01:56 -0300 Subject: [PATCH] fix(ticket-selector): reset invalid variant selections --- .../product-ticket-selector.component.html | 1 + .../product-ticket-selector.component.ts | 6 ++++- .../variant-selector.component.spec.ts | 20 +++++++++++++++++ .../variant-selector.component.ts | 22 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.html b/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.html index 0ab5838..9f33317 100644 --- a/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.html +++ b/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.html @@ -27,6 +27,7 @@ [variants]="variantsForRow(row.id)" [disabled]="rowDisabled(row)" [autoSelectFirst]="false" + [resetToken]="row.resetToken" [selectedVariant]="row.variantId" (selectedVariantChange)="updateCandidate(row.id, $event)" (selectionValuesChange)="onSelectionChange(row.id, $event)" diff --git a/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.ts b/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.ts index 069a942..65cbd7c 100644 --- a/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.ts +++ b/src/app/shared/components/product-ticket-selector/product-ticket-selector.component.ts @@ -47,6 +47,7 @@ interface TicketSelectionRow { remoteVariants: TicketSelectorVariant[] | null; status: TicketSelectionStatus; error: string | null; + resetToken: number; } @Component({ @@ -211,9 +212,11 @@ export class ProductTicketSelectorComponent { if (!response.valid) { this.patchRow(rowId, { variantId: null, - remoteVariants: variants, + selectedValues: {}, + remoteVariants: null, status: 'error', error: 'La combinación seleccionada ya no está disponible.', + resetToken: row.resetToken + 1, }); return; } @@ -324,6 +327,7 @@ export class ProductTicketSelectorComponent { remoteVariants: null, status: 'selecting', error: null, + resetToken: 0, }; } diff --git a/src/app/shared/components/variant-selector/variant-selector.component.spec.ts b/src/app/shared/components/variant-selector/variant-selector.component.spec.ts index e5bb83b..47763a5 100644 --- a/src/app/shared/components/variant-selector/variant-selector.component.spec.ts +++ b/src/app/shared/components/variant-selector/variant-selector.component.spec.ts @@ -114,4 +114,24 @@ describe('VariantSelectorComponent', () => { expect(fixture.componentInstance.selectedVariant()).toBe(2); }); + + it('clears every selected value when the reset token changes', async () => { + await TestBed.configureTestingModule({ + imports: [VariantSelectorComponent], + }).compileComponents(); + const fixture = TestBed.createComponent(VariantSelectorComponent); + fixture.componentRef.setInput('variants', [{ id: 1, values: { sector: 'A', asiento: '1' } }]); + fixture.componentRef.setInput('autoSelectFirst', false); + fixture.detectChanges(); + + (fixture.componentInstance as any).onValueChange('sector', 'A'); + (fixture.componentInstance as any).onValueChange('asiento', '1'); + expect(fixture.componentInstance.selectedVariant()).toBe(1); + + fixture.componentRef.setInput('resetToken', 1); + fixture.detectChanges(); + + expect(fixture.componentInstance.selectedVariant()).toBeNull(); + expect((fixture.componentInstance as any).selectedValues()).toEqual({}); + }); }); diff --git a/src/app/shared/components/variant-selector/variant-selector.component.ts b/src/app/shared/components/variant-selector/variant-selector.component.ts index fac5801..58b09fd 100644 --- a/src/app/shared/components/variant-selector/variant-selector.component.ts +++ b/src/app/shared/components/variant-selector/variant-selector.component.ts @@ -55,6 +55,7 @@ export class VariantSelectorComponent { readonly disabled = input(false); readonly compact = input(false); readonly autoSelectFirst = input(true); + readonly resetToken = input(0); readonly selectionValuesChange = output(); protected readonly selectedValues = signal>({}); @@ -87,6 +88,27 @@ export class VariantSelectorComponent { }); constructor() { + let initializedResetToken = false; + let previousResetToken = 0; + + effect(() => { + const resetToken = this.resetToken(); + + untracked(() => { + if (!initializedResetToken) { + initializedResetToken = true; + previousResetToken = resetToken; + return; + } + + if (resetToken === previousResetToken) return; + + previousResetToken = resetToken; + this.selectedValues.set({}); + this.selectedVariant.set(null); + }); + }); + effect(() => { const variants = this.variants(); const selectedVariant = this.selectedVariant();