feat(catalog): fetch options for partial variant selections

This commit is contained in:
2026-08-14 09:43:47 -03:00
parent 0defe75adb
commit 15979874ce
3 changed files with 36 additions and 4 deletions

View File

@@ -117,6 +117,14 @@ export interface CatalogFeaturedItemVariant {
values: Record<string, CatalogVariantValue>; values: Record<string, CatalogVariantValue>;
} }
export interface CatalogVariantOptionsResponse {
variants: CatalogFeaturedItemVariant[];
options: Record<string, CatalogVariantValue[]>;
selected_values: Record<string, string | string[]>;
resolved_variant_id: number | null;
valid: boolean;
}
export interface CatalogFeaturedItem { export interface CatalogFeaturedItem {
id: number; id: number;
type: CatalogItemType; type: CatalogItemType;

View File

@@ -12,6 +12,7 @@ import {
CatalogFeaturedItem, CatalogFeaturedItem,
CatalogFeaturedItems, CatalogFeaturedItems,
CatalogItemDetail, CatalogItemDetail,
CatalogVariantOptionsResponse,
CategoryItemsResponse, CategoryItemsResponse,
Product, Product,
} from './catalog.interface'; } from './catalog.interface';
@@ -74,10 +75,7 @@ export class CatalogService extends BaseApiService {
); );
} }
getCatalogItem( getCatalogItem(id: number, variantId?: number): Observable<CatalogItemDetail> {
id: number,
variantId?: number,
): Observable<CatalogItemDetail> {
let params = new HttpParams(); let params = new HttpParams();
if (variantId) { if (variantId) {
params = params.set('variant_id', variantId); params = params.set('variant_id', variantId);
@@ -90,6 +88,21 @@ export class CatalogService extends BaseApiService {
.pipe(map((response) => response.data)); .pipe(map((response) => response.data));
} }
getVariantOptions(
catalogItemId: number,
payload: {
selected_values: Record<string, string | string[]>;
excluded_variant_ids?: number[];
cart_item_id?: number | null;
},
): Observable<CatalogVariantOptionsResponse> {
return this.http
.post<
ApiResponse<CatalogVariantOptionsResponse>
>(`${this.tenantApiUrl}/catalog-items/${catalogItemId}/variant-options`, payload, { withCredentials: true })
.pipe(map((response) => response.data));
}
private buildHttpParams(params?: ApiPaginationQueryParams): HttpParams { private buildHttpParams(params?: ApiPaginationQueryParams): HttpParams {
if (!params) { if (!params) {
return new HttpParams(); return new HttpParams();

View File

@@ -5,6 +5,7 @@ import {
effect, effect,
input, input,
model, model,
output,
signal, signal,
untracked, untracked,
} from '@angular/core'; } from '@angular/core';
@@ -23,6 +24,11 @@ export interface VariantSelectorVariant {
values: Record<string, VariantAttributeValue>; values: Record<string, VariantAttributeValue>;
} }
export interface VariantSelectorSelectionChange {
values: Record<string, VariantAttributeValue>;
selectedVariant: unknown;
}
interface VariantSelectorOption { interface VariantSelectorOption {
key: string; key: string;
label: string; label: string;
@@ -49,6 +55,7 @@ export class VariantSelectorComponent {
readonly disabled = input(false); readonly disabled = input(false);
readonly compact = input(false); readonly compact = input(false);
readonly autoSelectFirst = input(true); readonly autoSelectFirst = input(true);
readonly selectionValuesChange = output<VariantSelectorSelectionChange>();
protected readonly selectedValues = signal<Record<string, VariantAttributeValue>>({}); protected readonly selectedValues = signal<Record<string, VariantAttributeValue>>({});
protected readonly compareValues = ( protected readonly compareValues = (
@@ -143,6 +150,10 @@ export class VariantSelectorComponent {
this.selectedValues.set(values); this.selectedValues.set(values);
this.selectedVariant.set(matchingVariant?.id ?? null); this.selectedVariant.set(matchingVariant?.id ?? null);
this.selectionValuesChange.emit({
values: { ...values },
selectedVariant: matchingVariant?.id ?? null,
});
} }
private optionsFor(variants: VariantSelectorVariant[], key: string): VariantSelectorOption[] { private optionsFor(variants: VariantSelectorVariant[], key: string): VariantSelectorOption[] {