feat(product-detail): enhance product variant handling with inventory policies and update UI components
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
<div class="quantity-selector d-inline-flex align-items-center overflow-hidden rounded" [class.quantity-selector--small]="size() === 'small'" aria-label="Selector de cantidad">
|
||||
<div
|
||||
class="quantity-selector d-inline-flex align-items-center overflow-hidden rounded"
|
||||
[class.quantity-selector--small]="size() === 'small'"
|
||||
aria-label="Selector de cantidad"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="quantity-selector__button border-0 p-0 fw-bold lh-1"
|
||||
@@ -9,13 +13,16 @@
|
||||
-
|
||||
</button>
|
||||
|
||||
<span class="quantity-selector__value flex-grow-1 min-w-0 text-center fw-bold lh-1 user-select-none">{{ quantity() }}</span>
|
||||
<span
|
||||
class="quantity-selector__value flex-grow-1 min-w-0 text-center fw-bold lh-1 user-select-none"
|
||||
>{{ quantity() }}</span
|
||||
>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="quantity-selector__button border-0 p-0 fw-bold lh-1"
|
||||
aria-label="Aumentar cantidad"
|
||||
[disabled]="quantity() >= max()"
|
||||
[disabled]="atMaximum()"
|
||||
(click)="onIncrease()"
|
||||
>
|
||||
+
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { QuantitySelectorComponent } from './quantity-selector.component';
|
||||
|
||||
describe('QuantitySelectorComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [QuantitySelectorComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('stops increasing when it reaches a numeric maximum', () => {
|
||||
const fixture = TestBed.createComponent(QuantitySelectorComponent);
|
||||
fixture.componentRef.setInput('max', 2);
|
||||
fixture.detectChanges();
|
||||
|
||||
const increaseButton = fixture.nativeElement.querySelector(
|
||||
'button:last-child',
|
||||
) as HTMLButtonElement;
|
||||
increaseButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.quantity()).toBe(2);
|
||||
expect(increaseButton.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it('keeps increasing when maximum is null', () => {
|
||||
const fixture = TestBed.createComponent(QuantitySelectorComponent);
|
||||
fixture.componentRef.setInput('max', null);
|
||||
fixture.detectChanges();
|
||||
|
||||
const increaseButton = fixture.nativeElement.querySelector(
|
||||
'button:last-child',
|
||||
) as HTMLButtonElement;
|
||||
increaseButton.click();
|
||||
increaseButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.quantity()).toBe(3);
|
||||
expect(increaseButton.disabled).toBe(false);
|
||||
});
|
||||
|
||||
it('does not decrease below the configured minimum', () => {
|
||||
const fixture = TestBed.createComponent(QuantitySelectorComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const decreaseButton = fixture.nativeElement.querySelector(
|
||||
'button:first-child',
|
||||
) as HTMLButtonElement;
|
||||
|
||||
expect(decreaseButton.disabled).toBe(true);
|
||||
expect(fixture.componentInstance.quantity()).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, input, model, output } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, computed, input, model, output } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-quantity-selector',
|
||||
@@ -6,14 +6,19 @@ import { ChangeDetectionStrategy, Component, input, model, output } from '@angul
|
||||
imports: [],
|
||||
templateUrl: './quantity-selector.component.html',
|
||||
styleUrl: './quantity-selector.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class QuantitySelectorComponent {
|
||||
readonly quantity = model<number>(1);
|
||||
readonly min = input<number>(1);
|
||||
readonly max = input<number>(100);
|
||||
readonly max = input<number | null>(100);
|
||||
readonly size = input<'small' | 'medium'>('medium');
|
||||
|
||||
protected readonly atMaximum = computed(() => {
|
||||
const max = this.max();
|
||||
return max !== null && this.quantity() >= max;
|
||||
});
|
||||
|
||||
readonly increase = output<void>();
|
||||
readonly decrease = output<void>();
|
||||
|
||||
@@ -25,7 +30,7 @@ export class QuantitySelectorComponent {
|
||||
}
|
||||
|
||||
protected onIncrease(): void {
|
||||
if (this.quantity() < this.max()) {
|
||||
if (!this.atMaximum()) {
|
||||
this.quantity.set(this.quantity() + 1);
|
||||
this.increase.emit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user