mirror of
https://github.com/faiztyanirh/clqms-shadcn-v1.git
synced 2026-04-22 17:19:52 +07:00
130 lines
3.6 KiB
JavaScript
130 lines
3.6 KiB
JavaScript
const optionsMode = {
|
|
default: async (field, selectOptions, loadingOptions) => {
|
|
if (selectOptions[field.key]?.length > 0) return;
|
|
|
|
loadingOptions[field.key] = true;
|
|
|
|
try {
|
|
const res = await fetch(field.optionsEndpoint);
|
|
const json = await res.json();
|
|
|
|
// selectOptions[field.key] = json?.data ?? [];
|
|
|
|
const data = json?.data ?? [];
|
|
const valueKey = field.valueKey ?? 'value';
|
|
const labelKey = field.labelKey ?? 'label';
|
|
|
|
selectOptions[field.key] = data.map((item) => {
|
|
const baseOption = {
|
|
value: item[valueKey],
|
|
label: typeof labelKey === 'function' ? labelKey(item) : item[labelKey],
|
|
};
|
|
|
|
if (field.key === 'FormulaInput') {
|
|
return {
|
|
...baseOption,
|
|
testid: item.TestSiteID,
|
|
level: item.isCountStat,
|
|
};
|
|
}
|
|
|
|
return baseOption;
|
|
});
|
|
|
|
} catch (err) {
|
|
console.error("Failed to fetch options for", field.key, err);
|
|
selectOptions[field.key] = [];
|
|
} finally {
|
|
loadingOptions[field.key] = false;
|
|
}
|
|
},
|
|
|
|
cascade: async (field, selectOptions, loadingOptions, form, lastFetched) => {
|
|
const parentValue = field.dependsOn ? form?.[field.dependsOn] : null;
|
|
// console.log(parentValue);
|
|
|
|
// If has dependency and parent changed, or not fetched yet
|
|
if (field.dependsOn) {
|
|
// If parent value exists and already fetched for this parent value, skip
|
|
if (selectOptions[field.key]?.length > 0 &&
|
|
lastFetched[field.key] === parentValue) {
|
|
return;
|
|
}
|
|
|
|
// If no parent value, clear options
|
|
if (!parentValue) {
|
|
selectOptions[field.key] = [];
|
|
return;
|
|
}
|
|
} else {
|
|
// Non-dependent field, only fetch once
|
|
if (selectOptions[field.key]?.length > 0) return;
|
|
}
|
|
|
|
let endpoint = field.optionsEndpoint;
|
|
|
|
// Add parent parameter if exists
|
|
if (parentValue && field.endpointParamKey) {
|
|
endpoint += `?${field.endpointParamKey}=${parentValue}`;
|
|
}
|
|
|
|
loadingOptions[field.key] = true;
|
|
|
|
try {
|
|
const res = await fetch(endpoint);
|
|
const json = await res.json();
|
|
|
|
// selectOptions[field.key] = json?.data ?? [];
|
|
|
|
const data = json?.data ?? [];
|
|
const valueKey = field.valueKey ?? 'value';
|
|
const labelKey = field.labelKey ?? 'label';
|
|
|
|
selectOptions[field.key] = data.map((item) => ({
|
|
value: item[valueKey],
|
|
label: typeof labelKey === 'function' ? labelKey(item) : item[labelKey],
|
|
}));
|
|
|
|
// Track last fetched parent value for dependent fields
|
|
if (field.dependsOn) {
|
|
lastFetched[field.key] = parentValue;
|
|
}
|
|
} catch (err) {
|
|
console.error("Failed to fetch options for", field.key, err);
|
|
selectOptions[field.key] = [];
|
|
} finally {
|
|
loadingOptions[field.key] = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
export function useFormOptions(optMode = 'default') {
|
|
const selectOptions = $state({});
|
|
const loadingOptions = $state({});
|
|
const lastFetched = $state({});
|
|
|
|
async function fetchOptions(field, form = null) {
|
|
if (!field?.optionsEndpoint) return;
|
|
|
|
const modeFn = optionsMode[optMode];
|
|
if (!modeFn) return;
|
|
|
|
await modeFn(field, selectOptions, loadingOptions, form, lastFetched);
|
|
}
|
|
|
|
function clearDependentOptions(parentKey, dependentKeys, form) {
|
|
dependentKeys.forEach(key => {
|
|
selectOptions[key] = [];
|
|
if (form) form[key] = '';
|
|
lastFetched[key] = null;
|
|
});
|
|
}
|
|
|
|
return {
|
|
selectOptions,
|
|
loadingOptions,
|
|
lastFetched,
|
|
fetchOptions,
|
|
clearDependentOptions,
|
|
};
|
|
} |