Custom selection fixes

This commit is contained in:
Simon Gruber
2026-03-29 16:23:49 +02:00
parent 8f8f6b9dea
commit 1ced3eb574
3 changed files with 49 additions and 11 deletions
+6 -3
View File
@@ -220,10 +220,13 @@ function AppContent({
<div style={{ width: "100%", maxWidth: 980, margin: "0 auto" }}>
<Divider style={{ margin: "8px 0 12px" }} />
<Paragraph type="secondary">
<Link href="mailto:lunchtime@sgruber.at">Feedback</Link> {" "}
<Link href="https://git.sgruber.at/lunchtime" target="_blank">
<Link href="https://git.sgruber.at/lunchtime/lunchtime-web" target="_blank">
Source Code
</Link>
</Link> {" "}
<Link href="https://git.sgruber.at/lunchtime/lunchtime-menus" target="_blank">
Menu Templates
</Link> {" "}
<Link href="mailto:lunchtime@sgruber.at">Feedback</Link>
</Paragraph>
</div>
</Footer>
@@ -45,6 +45,15 @@ function getCategoryRules(category: OrderFormCategory) {
];
}
function keepLastSelection(value: unknown) {
if (!Array.isArray(value)) {
return [];
}
const cleaned = value.map((entry) => String(entry).trim()).filter(Boolean);
return cleaned.length > 0 ? [cleaned[cleaned.length - 1]] : [];
}
export default function ParticipantCategoryFields({
categories,
isClosed,
@@ -56,15 +65,27 @@ export default function ParticipantCategoryFields({
const options = toCategoryOptions(category);
const selectPlaceholder = `Select ${category.label.toLowerCase()}`;
const rules = getCategoryRules(category);
const isSingleCustom = category.custom && !category.multiple;
const selectMode = category.custom
? "tags"
: category.multiple
? "multiple"
: undefined;
const extra = category.custom
? `Your ${category.label.toLowerCase()} of choice. (Custom entries allowed)`
: `Your ${category.label.toLowerCase()} of choice.`;
return (
<Col xs={24} md={12} key={category.id}>
<Form.Item extra={extra} label={category.label} name={category.id} rules={rules}>
<Form.Item
extra={extra}
label={category.label}
name={category.id}
rules={rules}
getValueFromEvent={isSingleCustom ? keepLastSelection : undefined}
>
<Select
mode={category.multiple ? "multiple" : undefined}
mode={selectMode}
allowClear={!category.required}
showSearch
placeholder={selectPlaceholder}
+20 -6
View File
@@ -48,16 +48,29 @@ function serializeSelections(values: NormalizedOrderSelections) {
return JSON.stringify(values);
}
function toFormValues(values: NormalizedOrderSelections): FormModel {
function toFormValues(
values: NormalizedOrderSelections,
config: OrderFormConfig,
): FormModel {
const model: FormModel = {};
Object.entries(values).forEach(([key, value]) => {
if (Array.isArray(value)) {
model[key] = value;
config.categories.forEach((category) => {
const value = values[category.id];
if (category.multiple) {
model[category.id] = Array.isArray(value) ? value : [];
return;
}
model[key] = value ?? undefined;
if (category.custom) {
const singleValue = Array.isArray(value) ? value[0] : value;
const trimmed = typeof singleValue === "string" ? singleValue.trim() : "";
model[category.id] = trimmed ? [trimmed] : undefined;
return;
}
const singleValue = Array.isArray(value) ? value[0] : value;
model[category.id] = singleValue ?? undefined;
});
return model;
@@ -229,8 +242,9 @@ export default function ParticipantView({ orderId }: { orderId: string }) {
return;
}
form.setFieldsValue(toFormValues(normalizedSavedValues));
form.setFieldsValue(toFormValues(normalizedSavedValues, config));
}, [
config,
existingSubmission,
form,
isEditingSubmittedOrder,