fix(catalog): expose full toggle options across product group
This commit is contained in:
@@ -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'"
|
||||||
|
|||||||
Reference in New Issue
Block a user