fix(catalog): expose full toggle options across product group

This commit is contained in:
Ruslan Bakiev
2026-04-03 14:27:28 +07:00
parent d2c5ee600f
commit 0ed6296aa0

View File

@@ -195,14 +195,10 @@ function sortParamValues(values: ParamValue[]) {
}); });
} }
function getFieldOptions(group: ProductGroup, state: GroupState, field: ParamFieldKey) { function getAllFieldOptions(group: ProductGroup, field: ParamFieldKey) {
const values = new Set<ParamValue>(); const values = new Set<ParamValue>();
for (const product of group.products) { for (const product of group.products) {
if (!matchesState(product, state, field)) {
continue;
}
const value = product[field]; const value = product[field];
if (value !== null) { if (value !== null) {
values.add(value); values.add(value);
@@ -213,6 +209,7 @@ function getFieldOptions(group: ProductGroup, state: GroupState, field: ParamFie
} }
function createGroupState(group: ProductGroup): GroupState { function createGroupState(group: ProductGroup): GroupState {
void group;
const state: GroupState = { const state: GroupState = {
widthMm: null, widthMm: null,
lengthM: null, lengthM: null,
@@ -222,29 +219,9 @@ function createGroupState(group: ProductGroup): GroupState {
isExpanded: false, isExpanded: false,
}; };
for (const key of PARAM_KEYS) {
const options = getFieldOptions(group, state, key);
state[key] = (options[0] as GroupState[typeof key] | undefined) ?? null;
}
return state; return state;
} }
function normalizeState(group: ProductGroup, state: GroupState) {
for (const key of PARAM_KEYS) {
const options = getFieldOptions(group, state, key);
if (options.length === 0) {
state[key] = null;
continue;
}
const current = state[key];
if (current === null || !options.some((option) => option === current)) {
state[key] = (options[0] as GroupState[typeof key] | undefined) ?? null;
}
}
}
watch( watch(
productGroups, productGroups,
(groups) => { (groups) => {
@@ -260,7 +237,6 @@ watch(
if (!groupStates[group.key]) { if (!groupStates[group.key]) {
groupStates[group.key] = createGroupState(group); groupStates[group.key] = createGroupState(group);
} }
normalizeState(group, groupStates[group.key]);
} }
}, },
{ immediate: true }, { immediate: true },
@@ -280,11 +256,13 @@ function getGroupState(group: ProductGroup): GroupState {
function updateField(group: ProductGroup, field: ParamFieldKey, value: ParamValue) { function updateField(group: ProductGroup, field: ParamFieldKey, value: ParamValue) {
const state = getGroupState(group); const state = getGroupState(group);
state[field] = value as GroupState[typeof field]; state[field] = value as GroupState[typeof field];
normalizeState(group, state);
} }
function selectedProduct(group: ProductGroup) { function selectedProduct(group: ProductGroup) {
const state = getGroupState(group); const state = getGroupState(group);
if (PARAM_KEYS.some((key) => state[key] === null)) {
return null;
}
return group.products.find((product) => matchesState(product, state)) ?? null; return group.products.find((product) => matchesState(product, state)) ?? null;
} }
@@ -311,7 +289,7 @@ function formatOptionLabel(field: ParamFieldKey, value: ParamValue) {
function selectedFieldValue(group: ProductGroup, field: ParamFieldKey) { function selectedFieldValue(group: ProductGroup, field: ParamFieldKey) {
const value = getGroupState(group)[field]; const value = getGroupState(group)[field];
if (value === null) { if (value === null) {
return ''; return 'не выбрано';
} }
return formatOptionLabel(field, value); return formatOptionLabel(field, value);
} }
@@ -436,7 +414,7 @@ function decrementSelected(group: ProductGroup) {
<p class="text-xs font-semibold uppercase tracking-wide text-base-content/60">{{ field.label }}</p> <p class="text-xs font-semibold uppercase tracking-wide text-base-content/60">{{ field.label }}</p>
<div class="mt-2 flex flex-wrap gap-2"> <div class="mt-2 flex flex-wrap gap-2">
<button <button
v-for="option in getFieldOptions(group, getGroupState(group), field.key)" v-for="option in getAllFieldOptions(group, field.key)"
:key="`${group.key}-${field.key}-${option}`" :key="`${group.key}-${field.key}-${option}`"
class="btn btn-sm" class="btn btn-sm"
:class="getGroupState(group)[field.key] === option ? 'btn-neutral' : 'btn-outline'" :class="getGroupState(group)[field.key] === option ? 'btn-neutral' : 'btn-outline'"