@open-mercato/ui 0.6.6-develop.6543.1.49fadb4c31 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js +20 -37
- package/dist/backend/custom-fields/FieldDefinitionsEditor.js.map +2 -2
- package/dist/backend/messages/useMessageCompose.js +0 -1
- package/dist/backend/messages/useMessageCompose.js.map +2 -2
- package/package.json +4 -5
- package/src/backend/custom-fields/FieldDefinitionsEditor.tsx +24 -52
- package/src/backend/messages/useMessageCompose.ts +0 -4
- package/src/backend/messages/__tests__/useMessageCompose.test.tsx +0 -60
|
@@ -30,15 +30,6 @@ import {
|
|
|
30
30
|
import {
|
|
31
31
|
normalizeCustomFieldOptions
|
|
32
32
|
} from "@open-mercato/shared/modules/entities/options";
|
|
33
|
-
function formatFallback(template, params) {
|
|
34
|
-
if (!params) return template;
|
|
35
|
-
return template.replace(/\{\{(\w+)\}\}|\{(\w+)\}/g, (match, doubleKey, singleKey) => {
|
|
36
|
-
const key = doubleKey ?? singleKey;
|
|
37
|
-
if (!key) return match;
|
|
38
|
-
const value = params[key];
|
|
39
|
-
return value === void 0 ? match : String(value);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
33
|
const DEFAULT_VALUE_NONE = "__open_mercato_no_default__";
|
|
43
34
|
function getDefaultValueNoneOptionValue(options) {
|
|
44
35
|
const optionValues = new Set(options.map((option) => String(option.value)));
|
|
@@ -143,10 +134,10 @@ function FieldDefinitionsEditor({
|
|
|
143
134
|
const hasFieldsets = fieldsets.length > 0;
|
|
144
135
|
const contextT = useOptionalT();
|
|
145
136
|
const t = React.useCallback(
|
|
146
|
-
(key,
|
|
147
|
-
if (translate) return translate(key,
|
|
148
|
-
if (contextT) return contextT(key,
|
|
149
|
-
return
|
|
137
|
+
(key, fallback) => {
|
|
138
|
+
if (translate) return translate(key, fallback);
|
|
139
|
+
if (contextT) return contextT(key, fallback);
|
|
140
|
+
return fallback;
|
|
150
141
|
},
|
|
151
142
|
[translate, contextT]
|
|
152
143
|
);
|
|
@@ -208,9 +199,7 @@ function FieldDefinitionsEditor({
|
|
|
208
199
|
if (!onFieldsetsChange) return;
|
|
209
200
|
if (!resolvedActiveFieldset) return;
|
|
210
201
|
const confirmed = await confirm({
|
|
211
|
-
title: t("entities.customFields.editor.deleteFieldsetTitle", 'Delete fieldset "{code}"?',
|
|
212
|
-
code: resolvedActiveFieldset
|
|
213
|
-
}),
|
|
202
|
+
title: t("entities.customFields.editor.deleteFieldsetTitle", 'Delete fieldset "{code}"?').replace("{code}", resolvedActiveFieldset),
|
|
214
203
|
text: t("entities.customFields.editor.deleteFieldsetText", "This will move its fields to Unassigned."),
|
|
215
204
|
variant: "destructive"
|
|
216
205
|
});
|
|
@@ -506,13 +495,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard2({
|
|
|
506
495
|
() => typeof local.configJson?.fieldset === "string" ? local.configJson.fieldset : "",
|
|
507
496
|
[local.configJson?.fieldset]
|
|
508
497
|
);
|
|
509
|
-
const t = React.useCallback(
|
|
510
|
-
(key, fallbackOrParams, params) => {
|
|
511
|
-
if (translate) return translate(key, fallbackOrParams, params);
|
|
512
|
-
return typeof fallbackOrParams === "string" ? formatFallback(fallbackOrParams, params) : key;
|
|
513
|
-
},
|
|
514
|
-
[translate]
|
|
515
|
-
);
|
|
498
|
+
const t = React.useCallback((key, fallback) => translate ? translate(key, fallback) : fallback, [translate]);
|
|
516
499
|
React.useEffect(() => {
|
|
517
500
|
localRef.current = definition;
|
|
518
501
|
setLocal(definition);
|
|
@@ -988,17 +971,17 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard2({
|
|
|
988
971
|
children: [
|
|
989
972
|
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
990
973
|
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
991
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "required", children:
|
|
992
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "date", children:
|
|
993
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "integer", children:
|
|
994
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "float", children:
|
|
995
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "lt", children:
|
|
996
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "lte", children:
|
|
997
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "gt", children:
|
|
998
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "gte", children:
|
|
999
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "eq", children:
|
|
1000
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "ne", children:
|
|
1001
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "regex", children:
|
|
974
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "required", children: "required" }),
|
|
975
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "date", children: "date" }),
|
|
976
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "integer", children: "integer" }),
|
|
977
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "float", children: "float" }),
|
|
978
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "lt", children: "lt" }),
|
|
979
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "lte", children: "lte" }),
|
|
980
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "gt", children: "gt" }),
|
|
981
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "gte", children: "gte" }),
|
|
982
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "eq", children: "eq" }),
|
|
983
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "ne", children: "ne" }),
|
|
984
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "regex", children: "regex" })
|
|
1002
985
|
] })
|
|
1003
986
|
]
|
|
1004
987
|
}
|
|
@@ -1006,7 +989,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard2({
|
|
|
1006
989
|
/* @__PURE__ */ jsx("div", { className: "md:col-span-4", children: /* @__PURE__ */ jsx(
|
|
1007
990
|
Input,
|
|
1008
991
|
{
|
|
1009
|
-
placeholder: rule?.rule === "regex" ? t("entities.customFields.editor.rulePatternPlaceholder", "Pattern (e.g. ^[a-z]+$)") : ["lt", "lte", "gt", "gte"].includes(rule?.rule) ? t("entities.customFields.editor.ruleNumberPlaceholder", "Number") :
|
|
992
|
+
placeholder: rule?.rule === "regex" ? t("entities.customFields.editor.rulePatternPlaceholder", "Pattern (e.g. ^[a-z]+$)") : ["lt", "lte", "gt", "gte"].includes(rule?.rule) ? t("entities.customFields.editor.ruleNumberPlaceholder", "Number") : "\u2014",
|
|
1010
993
|
value: rule?.param ?? "",
|
|
1011
994
|
onChange: (event) => {
|
|
1012
995
|
const value = ["lt", "lte", "gt", "gte"].includes(rule?.rule) ? Number(event.target.value) : event.target.value;
|
|
@@ -1313,7 +1296,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard2({
|
|
|
1313
1296
|
size: "xs",
|
|
1314
1297
|
className: "text-muted-foreground hover:text-foreground",
|
|
1315
1298
|
onClick: () => handleEditGroupEntry(group),
|
|
1316
|
-
"aria-label": t("entities.customFields.editor.editGroupAria", "Edit {code}"
|
|
1299
|
+
"aria-label": t("entities.customFields.editor.editGroupAria", "Edit {code}").replace("{code}", group.code),
|
|
1317
1300
|
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
1318
1301
|
}
|
|
1319
1302
|
),
|
|
@@ -1324,7 +1307,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard2({
|
|
|
1324
1307
|
size: "xs",
|
|
1325
1308
|
className: "text-destructive hover:text-destructive/80",
|
|
1326
1309
|
onClick: () => handleRemoveGroupEntry(group.code),
|
|
1327
|
-
"aria-label": t("entities.customFields.editor.deleteGroupAria", "Delete {code}"
|
|
1310
|
+
"aria-label": t("entities.customFields.editor.deleteGroupAria", "Delete {code}").replace("{code}", group.code),
|
|
1328
1311
|
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
1329
1312
|
}
|
|
1330
1313
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/backend/custom-fields/FieldDefinitionsEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Cog, GripVertical, Languages, Pencil, Plus, Trash2, X } from 'lucide-react'\nimport { Button } from '../../primitives/button'\nimport { CheckboxField } from '../../primitives/checkbox-field'\nimport { FormField } from '../../primitives/form-field'\nimport { IconButton } from '../../primitives/icon-button'\nimport { Input } from '../../primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../primitives/select'\nimport { CUSTOM_FIELD_KINDS } from '@open-mercato/shared/modules/entities/kinds'\nimport { useOptionalT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { FieldRegistry } from '../fields/registry'\nimport { slugify } from '@open-mercato/shared/lib/slugify'\nimport { useConfirmDialog } from '../confirm-dialog'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../../primitives/dialog'\nimport {\n normalizeCustomFieldOptions,\n type CustomFieldOptionDto,\n} from '@open-mercato/shared/modules/entities/options'\n\ntype FieldsetGroup = { code: string; title?: string; hint?: string }\ntype FieldsetConfig = { code: string; label: string; icon?: string; description?: string; groups?: FieldsetGroup[] }\n\nfunction formatFallback(template: string, params?: Record<string, string | number>) {\n if (!params) return template\n return template.replace(/\\{\\{(\\w+)\\}\\}|\\{(\\w+)\\}/g, (match, doubleKey, singleKey) => {\n const key = doubleKey ?? singleKey\n if (!key) return match\n const value = params[key]\n return value === undefined ? match : String(value)\n })\n}\n\nexport type FieldDefinition = {\n key: string\n kind: string\n configJson?: Record<string, unknown>\n isActive?: boolean\n}\n\nexport type FieldDefinitionError = { key?: string; kind?: string }\n\nexport type FieldDefinitionsEditorProps = {\n definitions: FieldDefinition[]\n errors?: Record<number, FieldDefinitionError>\n deletedKeys?: string[]\n kindOptions?: Array<{ value: string; label: string }>\n orderNotice?: { dirty: boolean; saving?: boolean; message?: string }\n infoNote?: React.ReactNode\n addButtonLabel?: string\n fieldsets?: FieldsetConfig[]\n activeFieldset?: string | null\n onActiveFieldsetChange?: (code: string | null) => void\n onFieldsetsChange?: (next: FieldsetConfig[]) => void\n onFieldsetCodeChange?: (previousCode: string, nextCode: string) => void\n onFieldsetRemoved?: (code: string) => void\n onAddField: () => void\n onRemoveField: (index: number) => void\n onDefinitionChange: (index: number, next: FieldDefinition) => void\n onRestoreField?: (key: string) => void\n onReorder?: (from: number, to: number) => void\n onTranslate?: (definition: FieldDefinition, index: number) => void\n listRef?: React.Ref<HTMLDivElement>\n listProps?: React.HTMLAttributes<HTMLDivElement>\n singleFieldsetPerRecord?: boolean\n onSingleFieldsetPerRecordChange?: (value: boolean) => void\n translate?: TranslateFn\n}\n\nconst DEFAULT_VALUE_NONE = '__open_mercato_no_default__'\n\nfunction getDefaultValueNoneOptionValue(options: CustomFieldOptionDto[]): string {\n const optionValues = new Set(options.map((option) => String(option.value)))\n let candidate = DEFAULT_VALUE_NONE\n while (optionValues.has(candidate)) {\n candidate = `${candidate}_`\n }\n return candidate\n}\n\nconst FIELDSET_ICON_OPTIONS = [\n { value: 'layers', label: 'Layers' },\n { value: 'tag', label: 'Tag' },\n { value: 'sparkles', label: 'Sparkles' },\n { value: 'package', label: 'Package' },\n { value: 'shirt', label: 'Shirt' },\n { value: 'grid', label: 'Grid' },\n { value: 'shoppingBag', label: 'Shopping bag' },\n { value: 'shoppingCart', label: 'Shopping cart' },\n { value: 'store', label: 'Store' },\n { value: 'users', label: 'Users' },\n { value: 'briefcase', label: 'Briefcase' },\n { value: 'building', label: 'Building' },\n { value: 'bookOpen', label: 'Book open' },\n { value: 'bookmark', label: 'Bookmark' },\n { value: 'camera', label: 'Camera' },\n { value: 'car', label: 'Car' },\n { value: 'clock', label: 'Clock' },\n { value: 'cloud', label: 'Cloud' },\n { value: 'compass', label: 'Compass' },\n { value: 'creditCard', label: 'Credit card' },\n { value: 'database', label: 'Database' },\n { value: 'flame', label: 'Flame' },\n { value: 'gift', label: 'Gift' },\n { value: 'globe', label: 'Globe' },\n { value: 'heart', label: 'Heart' },\n { value: 'key', label: 'Key' },\n { value: 'map', label: 'Map' },\n { value: 'palette', label: 'Palette' },\n { value: 'shield', label: 'Shield' },\n { value: 'star', label: 'Star' },\n { value: 'truck', label: 'Truck' },\n { value: 'zap', label: 'Zap' },\n { value: 'coins', label: 'Coins' },\n]\n\nfunction slugifyFieldsetCode(value: string): string {\n return slugify(value, { replacement: '', allowedChars: '_-' })\n}\n\nfunction ensureUniqueFieldsetCode(base: string, existing: FieldsetConfig[]): string {\n const sanitizedBase = slugifyFieldsetCode(base) || 'fieldset'\n let candidate = sanitizedBase\n let counter = 1\n const existingCodes = new Set(existing.map((fs) => fs.code))\n while (existingCodes.has(candidate)) {\n counter += 1\n candidate = `${sanitizedBase}_${counter}`\n }\n return candidate\n}\n\nfunction normalizeGroupValue(raw: unknown): FieldsetGroup | null {\n if (!raw) return null\n if (typeof raw === 'string') {\n const code = raw.trim()\n return code ? { code } : null\n }\n if (typeof raw !== 'object') return null\n const entry = raw as Record<string, unknown>\n const code = typeof entry.code === 'string' ? entry.code.trim() : ''\n if (!code) return null\n const group: FieldsetGroup = { code }\n if (typeof entry.title === 'string' && entry.title.trim()) group.title = entry.title.trim()\n if (typeof entry.hint === 'string' && entry.hint.trim()) group.hint = entry.hint.trim()\n return group\n}\n\nexport function FieldDefinitionsEditor({\n definitions,\n errors,\n deletedKeys,\n kindOptions,\n orderNotice,\n infoNote,\n addButtonLabel,\n fieldsets = [],\n activeFieldset = null,\n onActiveFieldsetChange,\n onFieldsetsChange,\n onFieldsetCodeChange,\n onFieldsetRemoved,\n singleFieldsetPerRecord,\n onSingleFieldsetPerRecordChange,\n onAddField,\n onRemoveField,\n onDefinitionChange,\n onRestoreField,\n onReorder,\n onTranslate,\n listRef,\n listProps,\n translate,\n}: FieldDefinitionsEditorProps) {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const dragIndex = React.useRef<number | null>(null)\n const hasFieldsets = fieldsets.length > 0\n const contextT = useOptionalT()\n const t = React.useCallback<TranslateFn>(\n (key, fallbackOrParams, params) => {\n if (translate) return translate(key, fallbackOrParams, params)\n if (contextT) return contextT(key, fallbackOrParams, params)\n return typeof fallbackOrParams === 'string'\n ? formatFallback(fallbackOrParams, params)\n : key\n },\n [translate, contextT],\n )\n const resolvedKindOptions = React.useMemo(\n () =>\n kindOptions ??\n CUSTOM_FIELD_KINDS.map((kind) => ({\n value: kind,\n label: t(`entities.customFields.editor.kindOption.${kind}`, kind.charAt(0).toUpperCase() + kind.slice(1)),\n })),\n [kindOptions, t],\n )\n const resolvedInfoNote = infoNote !== undefined ? infoNote : (\n <div className=\"text-xs text-muted-foreground mt-2\">\n {t(\n 'entities.customFields.editor.supportedKindsNote',\n 'Supported kinds: text, multiline, integer, float, boolean, select (with options/optionsUrl), currency (fixed currencies list), relation (with related entity and options URL).',\n )}\n </div>\n )\n const resolvedAddButtonLabel = addButtonLabel ?? t('entities.customFields.editor.addField', 'Add Field')\n const resolvedActiveFieldset = React.useMemo(() => {\n if (!hasFieldsets) return activeFieldset ?? null\n if (activeFieldset === null) return null\n return fieldsets.some((fs) => fs.code === activeFieldset) ? activeFieldset : (fieldsets[0]?.code ?? null)\n }, [activeFieldset, fieldsets, hasFieldsets])\n\n const filteredDefinitions = React.useMemo(\n () =>\n definitions\n .map((definition, index) => ({ definition, index }))\n .filter(({ definition }) => {\n if (!hasFieldsets) return true\n const assigned = typeof definition.configJson?.fieldset === 'string' ? definition.configJson.fieldset : undefined\n if (!resolvedActiveFieldset) return !assigned\n return assigned === resolvedActiveFieldset\n }),\n [definitions, hasFieldsets, resolvedActiveFieldset],\n )\n\n const activeFieldsetConfig = hasFieldsets && resolvedActiveFieldset\n ? fieldsets.find((fs) => fs.code === resolvedActiveFieldset) ?? null\n : null\n\n const handleActiveFieldsetChange = (value: string) => {\n if (!onActiveFieldsetChange) return\n onActiveFieldsetChange(value ? value : null)\n }\n\n const handleFieldsetPatch = (code: string, patch: Partial<FieldsetConfig>) => {\n if (!onFieldsetsChange) return\n const next = fieldsets.map((fs) => (fs.code === code ? { ...fs, ...patch } : fs))\n onFieldsetsChange(next)\n }\n\n const handleFieldsetCodeInput = (code: string, nextValue: string) => {\n if (!onFieldsetsChange) return\n const target = fieldsets.find((fs) => fs.code === code)\n if (!target) return\n const sanitized = slugifyFieldsetCode(nextValue)\n if (!sanitized) return\n const next = fieldsets.map((fs) => (fs.code === code ? { ...fs, code: sanitized } : fs))\n onFieldsetsChange(next)\n onFieldsetCodeChange?.(code, sanitized)\n onActiveFieldsetChange?.(sanitized)\n }\n\n const handleAddFieldset = () => {\n if (!onFieldsetsChange) return\n const code = ensureUniqueFieldsetCode(`fieldset_${fieldsets.length + 1}`, fieldsets)\n const nextFieldsets = [...fieldsets, { code, label: t('entities.customFields.editor.newFieldsetLabel', 'New fieldset'), icon: 'layers' }]\n onFieldsetsChange(nextFieldsets)\n onActiveFieldsetChange?.(code)\n }\n\n const handleRemoveFieldset = async () => {\n if (!onFieldsetsChange) return\n if (!resolvedActiveFieldset) return\n const confirmed = await confirm({\n title: t('entities.customFields.editor.deleteFieldsetTitle', 'Delete fieldset \"{code}\"?', {\n code: resolvedActiveFieldset,\n }),\n text: t('entities.customFields.editor.deleteFieldsetText', 'This will move its fields to Unassigned.'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const next = fieldsets.filter((fs) => fs.code !== resolvedActiveFieldset)\n onFieldsetsChange(next)\n onFieldsetRemoved?.(resolvedActiveFieldset)\n const fallback = next[0]?.code ?? null\n onActiveFieldsetChange?.(fallback)\n }\n\n const registerGroup = React.useCallback(\n (fieldsetCode: string, group: FieldsetGroup) => {\n if (!onFieldsetsChange || !fieldsetCode) return\n const next = fieldsets.map((fs) => {\n if (fs.code !== fieldsetCode) return fs\n const list = Array.isArray(fs.groups) ? fs.groups : []\n const existingIndex = list.findIndex((entry) => entry.code === group.code)\n if (existingIndex >= 0) {\n const updated = [...list]\n updated[existingIndex] = { ...list[existingIndex], ...group }\n return { ...fs, groups: updated }\n }\n return { ...fs, groups: [...list, group] }\n })\n onFieldsetsChange(next)\n },\n [fieldsets, onFieldsetsChange],\n )\n const removeGroup = React.useCallback(\n (fieldsetCode: string, groupCode: string) => {\n if (!onFieldsetsChange || !fieldsetCode || !groupCode) return\n const next = fieldsets.map((fs) => {\n if (fs.code !== fieldsetCode) return fs\n const list = Array.isArray(fs.groups) ? fs.groups : []\n return { ...fs, groups: list.filter((entry) => entry.code !== groupCode) }\n })\n onFieldsetsChange(next)\n },\n [fieldsets, onFieldsetsChange],\n )\n const availableGroups = activeFieldsetConfig?.groups ?? []\n const canToggleSingleFieldset = hasFieldsets && fieldsets.length > 1\n const singleFieldsetChecked = singleFieldsetPerRecord !== false\n\n const handleReorder = React.useCallback(\n (from: number, to: number) => {\n if (from === to) return\n onReorder?.(from, to)\n },\n [onReorder],\n )\n\n return (\n <div\n ref={listRef}\n className=\"space-y-3\"\n {...listProps}\n >\n {hasFieldsets ? (\n <div className=\"rounded border bg-card p-3 space-y-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('entities.customFields.fieldsetSelectorLabel', 'Fieldset')}</label>\n <Select\n value={resolvedActiveFieldset || undefined}\n onValueChange={(value) => handleActiveFieldsetChange(value ?? '')}\n >\n <SelectTrigger size=\"sm\" className=\"w-auto min-w-[10rem]\">\n <SelectValue placeholder={t('entities.customFields.editor.unassignedFields', 'Unassigned fields')} />\n </SelectTrigger>\n <SelectContent>\n {fieldsets.map((fs) => (\n <SelectItem key={fs.code} value={fs.code}>\n {fs.label || fs.code}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAddFieldset}\n className=\"text-xs\"\n >\n <Plus className=\"h-3.5 w-3.5\" /> {t('entities.customFields.editor.add', 'Add')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleRemoveFieldset}\n disabled={!resolvedActiveFieldset}\n className=\"text-xs\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" /> {t('entities.customFields.editor.delete', 'Delete')}\n </Button>\n </div>\n {resolvedActiveFieldset && activeFieldsetConfig ? (\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-3\">\n <FormField label={t('entities.customFields.editor.code', 'Code')}>\n <Input\n size=\"sm\"\n inputClassName=\"font-mono\"\n value={activeFieldsetConfig.code}\n onChange={(event) => handleFieldsetCodeInput(activeFieldsetConfig.code, event.target.value)}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n size=\"sm\"\n value={activeFieldsetConfig.label}\n onChange={(event) => handleFieldsetPatch(activeFieldsetConfig.code, { label: event.target.value })}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.icon', 'Icon')}>\n <Select\n value={activeFieldsetConfig.icon || undefined}\n onValueChange={(value) =>\n handleFieldsetPatch(activeFieldsetConfig.code, {\n icon: value || undefined,\n })\n }\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('entities.customFields.editor.defaultOption', 'Default')} />\n </SelectTrigger>\n <SelectContent>\n {FIELDSET_ICON_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {t(`entities.customFields.editor.iconOption.${option.value}`, option.label)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n <FormField label={t('entities.customFields.editor.description', 'Description')}>\n <Input\n size=\"sm\"\n value={activeFieldsetConfig.description ?? ''}\n onChange={(event) => handleFieldsetPatch(activeFieldsetConfig.code, { description: event.target.value })}\n />\n </FormField>\n </div>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <CheckboxField\n size=\"sm\"\n disabled={!canToggleSingleFieldset}\n checked={singleFieldsetChecked}\n onCheckedChange={(checked) => onSingleFieldsetPerRecordChange?.(checked === true)}\n label={t('entities.customFields.editor.singleFieldsetPerEntity', 'Single fieldset per entity')}\n containerClassName=\"text-xs\"\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n {!canToggleSingleFieldset ? (\n <span className=\"text-xs text-muted-foreground\">{t('entities.customFields.editor.singleFieldsetToggleHint', '(add at least two fieldsets to toggle)')}</span>\n ) : null}\n </div>\n </div>\n ) : (\n <div className=\"rounded border border-dashed bg-muted/30 p-4 text-sm text-muted-foreground flex flex-col gap-3\">\n <div>{t('entities.customFields.editor.noFieldsets', 'No fieldsets defined yet. Fieldsets let you group custom fields for different variants of the same entity (e.g., Fashion vs. Sport products).')}</div>\n <div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAddFieldset}\n >\n <Plus className=\"h-4 w-4\" />\n {t('entities.customFields.editor.addFirstFieldset', 'Add first fieldset')}\n </Button>\n </div>\n </div>\n )}\n {orderNotice?.dirty && (\n <div className=\"sticky top-0 z-sticky -mt-1 -mb-1\">\n <div className=\"inline-flex items-center gap-2 text-xs px-2 py-1 rounded border border-status-warning-border bg-status-warning-bg text-status-warning-text shadow-sm\">\n {orderNotice?.saving\n ? t('entities.customFields.editor.savingOrder', 'Saving order\u2026')\n : (orderNotice?.message ?? t('entities.customFields.editor.reorderedSavingSoon', 'Reordered \u2014 saving soon'))}\n </div>\n </div>\n )}\n {filteredDefinitions.map(({ definition, index }) => {\n const assignedFieldset = typeof definition.configJson?.fieldset === 'string' ? definition.configJson.fieldset : null\n const groupOptions = assignedFieldset\n ? fieldsets.find((fs) => fs.code === assignedFieldset)?.groups ?? []\n : availableGroups\n return (\n <div\n key={definition.key || `def-${index}`}\n className=\"group\"\n draggable\n onDragStart={() => { dragIndex.current = index }}\n onDragOver={(event) => { event.preventDefault() }}\n onDrop={() => {\n const from = dragIndex.current\n if (from == null) return\n dragIndex.current = null\n handleReorder(from, index)\n }}\n onDragEnd={() => { dragIndex.current = null }}\n tabIndex={0}\n onKeyDown={(event) => {\n if (!event.altKey) return\n if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault()\n handleReorder(index, Math.max(0, index - 1))\n }\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault()\n handleReorder(index, Math.min(definitions.length - 1, index + 1))\n }\n }}\n >\n <FieldDefinitionCard\n definition={definition}\n error={errors?.[index]}\n kindOptions={resolvedKindOptions}\n onChange={(next) => onDefinitionChange(index, next)}\n onRemove={() => onRemoveField(index)}\n allowFieldsetSelection={hasFieldsets}\n fieldsets={fieldsets}\n activeFieldset={resolvedActiveFieldset}\n availableGroups={groupOptions}\n onRegisterGroup={registerGroup}\n onRemoveGroup={removeGroup}\n onTranslate={onTranslate ? () => onTranslate(definition, index) : undefined}\n translate={t}\n />\n </div>\n )})}\n <div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={onAddField}\n >\n <Plus className=\"h-4 w-4\" /> {resolvedAddButtonLabel}\n </Button>\n {resolvedInfoNote}\n {deletedKeys && deletedKeys.length > 0 && onRestoreField ? (\n <div className=\"text-xs text-muted-foreground mt-2\">\n {t('entities.customFields.editor.restoreDeletedFields', 'Restore deleted fields:')}{' '}\n {deletedKeys.map((key, idx) => (\n <span key={key}>\n <Button\n variant=\"link\"\n className=\"h-auto p-0\"\n onClick={() => onRestoreField(key)}\n >\n {key}\n </Button>\n {idx < deletedKeys.length - 1 ? ', ' : ''}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n {ConfirmDialogElement}\n </div>\n )\n}\n\ntype FieldDefinitionCardProps = {\n definition: FieldDefinition\n error?: FieldDefinitionError\n kindOptions: Array<{ value: string; label: string }>\n onChange: (next: FieldDefinition) => void\n onRemove: () => void\n allowFieldsetSelection?: boolean\n fieldsets?: FieldsetConfig[]\n activeFieldset?: string | null\n availableGroups?: FieldsetGroup[]\n onRegisterGroup?: (fieldsetCode: string, group: FieldsetGroup) => void\n onRemoveGroup?: (fieldsetCode: string, groupCode: string) => void\n onTranslate?: () => void\n translate?: TranslateFn\n}\n\nconst FieldDefinitionCard = React.memo(function FieldDefinitionCard({\n definition,\n error,\n kindOptions,\n onChange,\n onRemove,\n allowFieldsetSelection = false,\n fieldsets = [],\n activeFieldset,\n availableGroups = [],\n onRegisterGroup,\n onRemoveGroup,\n onTranslate,\n translate,\n}: FieldDefinitionCardProps) {\n const [local, setLocal] = React.useState<FieldDefinition>(definition)\n const localRef = React.useRef<FieldDefinition>(definition)\n const [optionValueDraft, setOptionValueDraft] = React.useState('')\n const [optionLabelDraft, setOptionLabelDraft] = React.useState('')\n const [optionDialogOpen, setOptionDialogOpen] = React.useState(false)\n const [optionFormError, setOptionFormError] = React.useState<string | null>(null)\n const [groupDialogOpen, setGroupDialogOpen] = React.useState(false)\n const [groupDraft, setGroupDraft] = React.useState({ code: '', title: '', hint: '' })\n const [editingGroupCode, setEditingGroupCode] = React.useState<string | null>(null)\n const [groupError, setGroupError] = React.useState<string | null>(null)\n const currentFieldsetValue = React.useMemo(\n () => (typeof local.configJson?.fieldset === 'string' ? local.configJson.fieldset : ''),\n [local.configJson?.fieldset],\n )\n const t = React.useCallback<TranslateFn>(\n (key, fallbackOrParams, params) => {\n if (translate) return translate(key, fallbackOrParams, params)\n return typeof fallbackOrParams === 'string'\n ? formatFallback(fallbackOrParams, params)\n : key\n },\n [translate],\n )\n React.useEffect(() => {\n localRef.current = definition\n setLocal(definition)\n }, [definition.key])\n React.useEffect(() => {\n setOptionValueDraft('')\n setOptionLabelDraft('')\n setGroupDialogOpen(false)\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n setGroupError(null)\n }, [definition.key])\n React.useEffect(() => {\n if (!currentFieldsetValue) {\n setGroupDialogOpen(false)\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n setGroupError(null)\n }\n }, [currentFieldsetValue])\n const currentGroup = React.useMemo(() => normalizeGroupValue(local.configJson?.group), [local])\n const groupOptions = React.useMemo(() => {\n const list = Array.isArray(availableGroups) ? [...availableGroups] : []\n if (currentGroup && !list.some((entry) => entry.code === currentGroup.code)) {\n list.push(currentGroup)\n }\n return list\n }, [availableGroups, currentGroup])\n const resolvedOptions = React.useMemo<CustomFieldOptionDto[]>(\n () => normalizeCustomFieldOptions(local.configJson?.options),\n [local.configJson?.options],\n )\n\n const sanitize = (def: FieldDefinition): FieldDefinition => {\n if (!def.configJson || !Array.isArray(def.configJson.options)) return def\n const normalizedOptions = normalizeCustomFieldOptions(def.configJson.options)\n return {\n ...def,\n configJson: {\n ...def.configJson,\n options: normalizedOptions,\n },\n }\n }\n\n const replaceLocal = React.useCallback((next: FieldDefinition) => {\n localRef.current = next\n setLocal(next)\n return next\n }, [])\n\n const apply = (patch: Partial<FieldDefinition> | ((current: FieldDefinition) => Partial<FieldDefinition>), propagateNow = false) => {\n const current = localRef.current\n const resolvedPatch = typeof patch === 'function' ? patch(current) : patch\n const next = { ...current, ...resolvedPatch }\n const resolvedNext = propagateNow ? sanitize(next) : next\n replaceLocal(resolvedNext)\n if (propagateNow) {\n onChange(resolvedNext)\n }\n }\n\n const commit = () => {\n const sanitized = sanitize(localRef.current)\n replaceLocal(sanitized)\n onChange(sanitized)\n }\n\n const handleFieldsetSelect = (value: string) => {\n const nextConfig = { ...(localRef.current.configJson || {}) }\n if (value) nextConfig.fieldset = value\n else delete nextConfig.fieldset\n delete nextConfig.group\n const next = { ...localRef.current, configJson: nextConfig }\n replaceLocal(next)\n onChange(next)\n }\n\n const handleGroupSelect = (value: string) => {\n if (!currentFieldsetValue) return\n if (!value) {\n const nextConfig = { ...(local.configJson || {}) }\n delete nextConfig.group\n apply({ configJson: nextConfig }, true)\n return\n }\n const match = groupOptions.find((group) => group.code === value)\n const nextGroup = match ?? { code: value }\n const nextConfig = { ...(local.configJson || {}) }\n nextConfig.group = nextGroup\n apply({ configJson: nextConfig }, true)\n onRegisterGroup?.(currentFieldsetValue, nextGroup)\n }\n\n const handleOpenGroupDialog = (group?: FieldsetGroup) => {\n if (!currentFieldsetValue) return\n if (group) {\n setGroupDraft({\n code: group.code,\n title: group.title ?? '',\n hint: group.hint ?? '',\n })\n setEditingGroupCode(group.code)\n } else {\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n }\n setGroupError(null)\n setGroupDialogOpen(true)\n }\n\n const handleGroupDialogSubmit = () => {\n if (!currentFieldsetValue) return\n const code = slugifyFieldsetCode(groupDraft.code || '')\n if (!code) {\n setGroupError(t('entities.customFields.editor.groupCodeRequired', 'Group code is required.'))\n return\n }\n const group: FieldsetGroup = {\n code,\n title: groupDraft.title.trim() || undefined,\n hint: groupDraft.hint.trim() || undefined,\n }\n onRegisterGroup?.(currentFieldsetValue, group)\n const shouldAttachToField = !editingGroupCode || currentGroup?.code === editingGroupCode\n if (shouldAttachToField) {\n const nextConfig = { ...(local.configJson || {}) }\n nextConfig.group = group\n apply({ configJson: nextConfig }, true)\n }\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n setGroupDialogOpen(false)\n }\n\n const handleRemoveGroupEntry = (code: string) => {\n if (!currentFieldsetValue) return\n onRemoveGroup?.(currentFieldsetValue, code)\n if (currentGroup?.code === code) {\n handleGroupSelect('')\n }\n if (editingGroupCode === code) {\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n }\n }\n\n const handleEditGroupEntry = (group: FieldsetGroup) => {\n handleOpenGroupDialog(group)\n }\n\n const resetOptionDialog = () => {\n setOptionValueDraft('')\n setOptionLabelDraft('')\n setOptionFormError(null)\n }\n\n const handleOpenOptionDialog = () => {\n resetOptionDialog()\n setOptionDialogOpen(true)\n }\n\n const handleCloseOptionDialog = () => {\n resetOptionDialog()\n setOptionDialogOpen(false)\n }\n\n const handleAddOption = () => {\n const value = optionValueDraft.trim()\n const label = optionLabelDraft.trim()\n if (!value) {\n setOptionFormError(t('entities.customFields.editor.valueRequired', 'Value is required'))\n return\n }\n setOptionFormError(null)\n const nextOptions = Array.isArray(local.configJson?.options) ? [...local.configJson!.options] : []\n nextOptions.push({ value, label: label || value })\n apply({ configJson: { ...(local.configJson || {}), options: nextOptions } }, true)\n handleCloseOptionDialog()\n }\n\n const handleRemoveOption = (index: number) => {\n const nextOptions = Array.isArray(local.configJson?.options) ? [...local.configJson!.options] : []\n nextOptions.splice(index, 1)\n apply({ configJson: { ...(local.configJson || {}), options: nextOptions } }, true)\n }\n\n return (\n <>\n <div className=\"rounded border p-3 bg-card transition-colors hover:border-muted-foreground/60\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center justify-center h-5 w-5 rounded hover:bg-muted cursor-grab active:cursor-grabbing\">\n <GripVertical className=\"h-4 w-4 opacity-70\" />\n </span>\n {t('entities.customFields.editor.dragToReorder', 'Drag to reorder')}\n </div>\n <div className=\"flex items-center gap-3\">\n <CheckboxField\n size=\"sm\"\n checked={local.isActive !== false}\n onCheckedChange={(checked) => { apply({ isActive: checked === true }, true) }}\n label={t('entities.customFields.editor.active', 'Active')}\n containerClassName=\"text-sm\"\n contentClassName=\"gap-1 [&_label]:text-sm [&_label]:font-normal\"\n />\n {onTranslate && (\n <IconButton variant=\"outline\" size=\"sm\" onClick={onTranslate} aria-label={t('entities.customFields.editor.translateField', 'Translate field')}>\n <Languages className=\"h-4 w-4\" />\n </IconButton>\n )}\n <IconButton variant=\"outline\" size=\"sm\" onClick={onRemove} aria-label={t('entities.customFields.editor.removeField', 'Remove field')}>\n <Trash2 className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n\n <div className=\"mt-3 grid grid-cols-1 md:grid-cols-12 gap-3 items-center\">\n <FormField label={t('entities.customFields.editor.key', 'Key')} error={error?.key} className=\"md:col-span-6\">\n <Input\n inputClassName=\"font-mono\"\n placeholder=\"snake_case\"\n value={local.key}\n onChange={(event) => apply({ key: event.target.value })}\n onBlur={commit}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.kind', 'Kind')} error={error?.kind} className=\"md:col-span-6\">\n <Select\n value={local.kind || undefined}\n onValueChange={(value) => { apply({ kind: value ?? '' }, true) }}\n >\n <SelectTrigger aria-invalid={!!error?.kind}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {kindOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n </div>\n\n {allowFieldsetSelection ? (\n <div className=\"mt-3 grid grid-cols-1 md:grid-cols-2 gap-3\">\n <div>\n <label className=\"text-xs\">{t('entities.customFields.editor.assignToFieldset', 'Assign to fieldset')}</label>\n <Select\n value={currentFieldsetValue || undefined}\n onValueChange={(value) => handleFieldsetSelect(value ?? '')}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.customFields.editor.unassigned', 'Unassigned')} />\n </SelectTrigger>\n <SelectContent>\n {(fieldsets || []).map((fs) => (\n <SelectItem key={fs.code} value={fs.code}>\n {fs.label || fs.code}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {currentFieldsetValue ? (\n <div>\n <div className=\"flex items-center justify-between\">\n <label className=\"text-xs\">{t('entities.customFields.editor.group', 'Group')}</label>\n </div>\n <div className=\"flex items-center gap-2 mt-1\">\n <Select\n value={currentGroup?.code || undefined}\n onValueChange={(value) => handleGroupSelect(value ?? '')}\n >\n <SelectTrigger className=\"flex-1\">\n <SelectValue placeholder={t('entities.customFields.editor.noGroup', 'No group')} />\n </SelectTrigger>\n <SelectContent>\n {groupOptions.map((group) => (\n <SelectItem key={group.code} value={group.code}>\n {group.title || group.code}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <IconButton\n variant=\"outline\"\n className=\"text-muted-foreground\"\n onClick={() => handleOpenGroupDialog()}\n aria-label={t('entities.customFields.editor.createGroup', 'Create group')}\n >\n <Plus className=\"h-4 w-4\" />\n </IconButton>\n <IconButton\n variant=\"outline\"\n className=\"text-muted-foreground\"\n onClick={() => handleOpenGroupDialog()}\n aria-label={t('entities.customFields.editor.editGroups', 'Edit groups')}\n >\n <Cog className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"mt-3 grid grid-cols-1 md:grid-cols-2 gap-3\">\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n value={typeof local.configJson?.label === 'string' ? local.configJson.label : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), label: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.description', 'Description')}>\n <Input\n value={typeof local.configJson?.description === 'string' ? local.configJson.description : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), description: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n\n {(local.kind === 'text' || local.kind === 'multiline') && (\n <>\n <div>\n <label className=\"text-xs\">{t('entities.customFields.editor.editor', 'Editor')}</label>\n <Select\n value={typeof local.configJson?.editor === 'string' && local.configJson.editor ? local.configJson.editor : undefined}\n onValueChange={(value) => { apply({ configJson: { ...(local.configJson || {}), editor: value || undefined } }, true) }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.customFields.editor.defaultOption', 'Default')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"markdown\">{t('entities.customFields.editor.editorMarkdown', 'Markdown (UIW)')}</SelectItem>\n <SelectItem value=\"simpleMarkdown\">{t('entities.customFields.editor.editorSimpleMarkdown', 'Simple Markdown')}</SelectItem>\n <SelectItem value=\"htmlRichText\">{t('entities.customFields.editor.editorHtmlRichText', 'HTML Rich Text')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n {local.kind === 'text' && (\n <>\n <CheckboxField\n size=\"sm\"\n checked={!!local.configJson?.multi}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), multi: checked === true } }, true) }}\n label={t('entities.customFields.editor.multiple', 'Multiple')}\n containerClassName=\"md:col-span-2\"\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n {!!local.configJson?.multi && (\n <div className=\"md:col-span-2\">\n <label className=\"text-xs\">{t('entities.customFields.editor.multiSelectInputStyle', 'Multi-select input style')}</label>\n <Select\n value={local.configJson?.input === 'listbox' ? 'listbox' : 'default'}\n onValueChange={(value) => {\n const nextConfig = { ...(local.configJson || {}) }\n if (value === 'listbox') nextConfig.input = 'listbox'\n else delete nextConfig.input\n apply({ configJson: nextConfig }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"default\">{t('entities.customFields.editor.defaultOption', 'Default')}</SelectItem>\n <SelectItem value=\"listbox\">{t('entities.customFields.editor.listboxSearchable', 'Listbox (searchable)')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </>\n )}\n </>\n )}\n\n {local.kind === 'select' && (\n <div className=\"md:col-span-6 space-y-3\">\n <label className=\"text-xs\">{t('entities.customFields.editor.options', 'Options')}</label>\n <div className=\"space-y-2\">\n {resolvedOptions.length > 0 ? (\n resolvedOptions.map((option, idx) => (\n <div\n key={`${option.value}-${idx}`}\n className=\"flex items-center justify-between rounded border px-3 py-2 text-xs bg-muted\"\n >\n <div>\n <div className=\"font-medium text-foreground\">{option.label}</div>\n <div className=\"text-muted-foreground font-mono text-overline\">{option.value}</div>\n </div>\n <IconButton\n variant=\"ghost\"\n size=\"xs\"\n className=\"text-destructive hover:text-destructive/80\"\n onClick={() => handleRemoveOption(idx)}\n aria-label={t('entities.customFields.editor.removeOption', 'Remove option')}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </IconButton>\n </div>\n ))\n ) : (\n <span className=\"text-xs text-muted-foreground\">{t('entities.customFields.editor.noOptionsDefined', 'No options defined.')}</span>\n )}\n </div>\n <div className=\"flex justify-end\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={handleOpenOptionDialog}\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t('entities.customFields.editor.addOption', 'Add option')}\n </Button>\n </div>\n </div>\n )}\n\n {(local.kind === 'select' || local.kind === 'relation') && (\n <>\n <FormField label={t('entities.customFields.editor.optionsUrl', 'Options URL')}>\n <Input\n placeholder=\"/api/...\"\n value={typeof local.configJson?.optionsUrl === 'string' ? local.configJson.optionsUrl : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), optionsUrl: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n {local.kind === 'relation' && (\n <FormField label={t('entities.customFields.editor.relatedEntityId', 'Related Entity ID')}>\n <Input\n inputClassName=\"font-mono\"\n placeholder=\"module:entity\"\n value={typeof local.configJson?.relatedEntityId === 'string' ? local.configJson.relatedEntityId : ''}\n onChange={(event) => {\n const relatedEntityId = event.target.value\n const defOptionsUrl = relatedEntityId\n ? `/api/entities/relations/options?entityId=${encodeURIComponent(relatedEntityId)}`\n : ''\n apply({\n configJson: {\n ...(local.configJson || {}),\n relatedEntityId,\n optionsUrl: local.configJson?.optionsUrl || defOptionsUrl,\n },\n })\n }}\n onBlur={commit}\n />\n </FormField>\n )}\n </>\n )}\n\n {local.kind === 'currency' && (\n <div className=\"md:col-span-2\">\n <label className=\"text-xs\">{t('entities.customFields.editor.optionsSource', 'Options source')}</label>\n <div className=\"rounded border bg-muted px-2 py-1 text-xs text-muted-foreground\">\n /api/currencies/options\n </div>\n </div>\n )}\n\n {(local.kind === 'integer' || local.kind === 'float') && (\n <FormField label={t('entities.customFields.editor.unitsOptional', 'Units (optional)')} className=\"md:col-span-2\">\n <Input\n placeholder={t('entities.customFields.editor.unitsPlaceholder', 'kg, cm, etc.')}\n value={typeof local.configJson?.unit === 'string' ? local.configJson.unit : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), unit: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n )}\n </div>\n\n <div className=\"mt-3 pt-3 border-t\">\n <div className=\"flex items-center justify-between mb-2\">\n <label className=\"text-sm font-medium\">{t('entities.customFields.editor.validationRules', 'Validation rules')}</label>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => {\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n list.push({ rule: 'required', message: t('entities.customFields.editor.ruleRequiredMessage', 'This field is required') } as any)\n return { configJson: { ...(current.configJson || {}), validation: list } }\n }, true)\n }}\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t('entities.customFields.editor.addRule', 'Add rule')}\n </Button>\n </div>\n <div className=\"space-y-2\">\n {(Array.isArray(local.configJson?.validation) ? local.configJson!.validation : []).map((rule: any, index: number) => (\n <div key={index} className=\"grid grid-cols-1 md:grid-cols-12 gap-2 items-center\">\n <div className=\"md:col-span-3\">\n <Select\n value={rule?.rule || 'required'}\n onValueChange={(value) => {\n const nextRule = value\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n const existing = (list[index] as any) || {}\n list[index] = { ...existing, rule: nextRule, message: existing.message || rule?.message || '' }\n return { configJson: { ...(current.configJson || {}), validation: list } }\n }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"required\">{t('entities.customFields.editor.validation.required', 'required')}</SelectItem>\n <SelectItem value=\"date\">{t('entities.customFields.editor.validation.date', 'date')}</SelectItem>\n <SelectItem value=\"integer\">{t('entities.customFields.editor.validation.integer', 'integer')}</SelectItem>\n <SelectItem value=\"float\">{t('entities.customFields.editor.validation.float', 'float')}</SelectItem>\n <SelectItem value=\"lt\">{t('entities.customFields.editor.validation.lt', 'lt')}</SelectItem>\n <SelectItem value=\"lte\">{t('entities.customFields.editor.validation.lte', 'lte')}</SelectItem>\n <SelectItem value=\"gt\">{t('entities.customFields.editor.validation.gt', 'gt')}</SelectItem>\n <SelectItem value=\"gte\">{t('entities.customFields.editor.validation.gte', 'gte')}</SelectItem>\n <SelectItem value=\"eq\">{t('entities.customFields.editor.validation.eq', 'eq')}</SelectItem>\n <SelectItem value=\"ne\">{t('entities.customFields.editor.validation.ne', 'ne')}</SelectItem>\n <SelectItem value=\"regex\">{t('entities.customFields.editor.validation.regex', 'regex')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"md:col-span-4\">\n <Input\n placeholder={\n rule?.rule === 'regex'\n ? t('entities.customFields.editor.rulePatternPlaceholder', 'Pattern (e.g. ^[a-z]+$)')\n : (['lt','lte','gt','gte'].includes(rule?.rule)\n ? t('entities.customFields.editor.ruleNumberPlaceholder', 'Number')\n : t('entities.customFields.editor.noParameterPlaceholder', '\u2014'))\n }\n value={rule?.param ?? ''}\n onChange={(event) => {\n const value = ['lt','lte','gt','gte'].includes(rule?.rule) ? Number(event.target.value) : event.target.value\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n const existing = (list[index] as any) || {}\n list[index] = { ...existing, ...rule, param: value }\n return { configJson: { ...(current.configJson || {}), validation: list } }\n })\n }}\n onBlur={commit}\n disabled={rule?.rule === 'required' || rule?.rule === 'date' || rule?.rule === 'integer' || rule?.rule === 'float'}\n />\n </div>\n <div className=\"md:col-span-4\">\n <Input\n placeholder={t('entities.customFields.editor.ruleErrorMessagePlaceholder', 'Error message')}\n value={rule?.message || ''}\n onChange={(event) => {\n const message = event.target.value\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n const existing = (list[index] as any) || {}\n list[index] = { ...existing, ...rule, message }\n return { configJson: { ...(current.configJson || {}), validation: list } }\n })\n }}\n onBlur={commit}\n />\n </div>\n <div className=\"md:col-span-1 flex justify-end\">\n <IconButton\n variant=\"outline\"\n size=\"sm\"\n aria-label={t('entities.customFields.editor.removeRule', 'Remove rule')}\n onClick={() => {\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n list.splice(index, 1)\n return { configJson: { ...(current.configJson || {}), validation: list } }\n }, true)\n }}\n >\n <Trash2 className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n ))}\n {(!Array.isArray(local.configJson?.validation) || local.configJson!.validation.length === 0) && (\n <div className=\"text-xs text-muted-foreground\">{t('entities.customFields.editor.noValidationRules', 'No validation rules defined.')}</div>\n )}\n </div>\n </div>\n\n <div className=\"mt-3\">\n {(() => {\n const Editor = FieldRegistry.getDefEditor(local.kind)\n if (!Editor) return null\n return (\n <Editor\n def={{ key: local.key, kind: local.kind, configJson: local.configJson }}\n onChange={(patch) => apply({ configJson: { ...(local.configJson || {}), ...(patch || {}) } }, true)}\n />\n )\n })()}\n </div>\n\n {/* Default value control \u2014 shown for kinds without a dedicated FieldRegistry defEditor default section */}\n {(() => {\n // Dictionary kind handles defaults in its own defEditor; skip here\n if (local.kind === 'dictionary') return null\n // Relation and attachment kinds do not support defaults\n if (local.kind === 'relation' || local.kind === 'attachment') return null\n const currentDefault = local.configJson?.defaultValue\n if (local.kind === 'boolean') {\n const boolDefault = currentDefault === true ? 'true' : currentDefault === false ? 'false' : ''\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Select\n value={boolDefault || DEFAULT_VALUE_NONE}\n onValueChange={(raw) => {\n const value = raw === 'true' ? true : raw === 'false' ? false : undefined\n apply({ configJson: { ...(local.configJson || {}), defaultValue: value } }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={DEFAULT_VALUE_NONE}>{t('entities.customFields.fields.defaultValueNone', 'No default')}</SelectItem>\n <SelectItem value=\"true\">{t('entities.customFields.fields.defaultValueTrue', 'Checked (true)')}</SelectItem>\n <SelectItem value=\"false\">{t('entities.customFields.fields.defaultValueFalse', 'Unchecked (false)')}</SelectItem>\n </SelectContent>\n </Select>\n </FormField>\n )\n }\n // select with static options \u2014 picker\n if (local.kind === 'select' && !local.configJson?.multi) {\n const opts = normalizeCustomFieldOptions(local.configJson?.options || [])\n if (opts.length > 0) {\n const noneValue = getDefaultValueNoneOptionValue(opts)\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Select\n value={typeof currentDefault === 'string' || typeof currentDefault === 'number' ? String(currentDefault) : ''}\n onValueChange={(raw) => {\n if (raw === noneValue) {\n apply({ configJson: { ...(local.configJson || {}), defaultValue: undefined } }, true)\n return\n }\n // Preserve the original option type (string or number) instead of coercing to string\n const matched = opts.find((o) => String(o.value) === raw)\n const typed = matched ? matched.value : raw\n apply({ configJson: { ...(local.configJson || {}), defaultValue: typed } }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.customFields.fields.defaultValueNone', 'No default')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={noneValue}>{t('entities.customFields.fields.defaultValueNone', 'No default')}</SelectItem>\n {opts.map((option) => (\n <SelectItem key={String(option.value)} value={String(option.value)}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n )\n }\n }\n // Numeric kinds\n if (local.kind === 'integer' || local.kind === 'float') {\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Input\n type=\"number\"\n step={local.kind === 'integer' ? '1' : 'any'}\n value={typeof currentDefault === 'number' ? String(currentDefault) : ''}\n onChange={(event) => {\n const raw = event.target.value\n const parsed = raw === '' ? undefined : (local.kind === 'integer' ? parseInt(raw, 10) : parseFloat(raw))\n const value = parsed !== undefined && !isNaN(parsed) ? parsed : undefined\n apply({ configJson: { ...(local.configJson || {}), defaultValue: value } })\n }}\n onBlur={commit}\n placeholder={t('entities.customFields.fields.defaultValuePlaceholder', 'No default')}\n />\n </FormField>\n )\n }\n // Text-like kinds (text, multiline, date, datetime, currency)\n if (['text', 'multiline', 'date', 'datetime', 'currency'].includes(local.kind)) {\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Input\n value={typeof currentDefault === 'string' ? currentDefault : ''}\n onChange={(event) => {\n const value = event.target.value\n apply({ configJson: { ...(local.configJson || {}), defaultValue: value || undefined } })\n }}\n onBlur={commit}\n placeholder={t('entities.customFields.fields.defaultValuePlaceholder', 'No default')}\n />\n </FormField>\n )\n }\n return null\n })()}\n\n <div className=\"mt-3 pt-2 border-t flex flex-wrap items-center gap-4\">\n <span className=\"text-xs text-muted-foreground\">{t('entities.customFields.fields.visibility', 'Visibility:')}</span>\n <CheckboxField\n size=\"sm\"\n checked={local.configJson?.listVisible !== false}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), listVisible: checked === true } }, true) }}\n label={t('entities.customFields.fields.listVisible', 'List')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n <CheckboxField\n size=\"sm\"\n checked={!!local.configJson?.filterable}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), filterable: checked === true } }, true) }}\n label={t('entities.customFields.fields.filterable', 'Filter')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n <CheckboxField\n size=\"sm\"\n checked={local.configJson?.formEditable !== false}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), formEditable: checked === true } }, true) }}\n label={t('entities.customFields.fields.formEditable', 'Form')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n <CheckboxField\n size=\"sm\"\n checked={!!local.configJson?.encrypted}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), encrypted: checked === true } }, true) }}\n label={t('entities.customFields.fields.encrypted', 'Encrypted')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n </div>\n </div>\n <Dialog\n open={optionDialogOpen}\n onOpenChange={(open) => {\n setOptionDialogOpen(open)\n if (!open) resetOptionDialog()\n }}\n >\n <DialogContent className=\"max-w-sm\">\n <DialogHeader>\n <DialogTitle>{t('entities.customFields.editor.addOption', 'Add option')}</DialogTitle>\n <DialogDescription>{t('entities.customFields.editor.addOptionDescription', 'Provide the stored value and optional label shown to users.')}</DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4 py-2\">\n <FormField label={t('entities.customFields.editor.value', 'Value')} error={optionFormError ?? undefined}>\n <Input\n inputClassName=\"font-mono\"\n placeholder=\"unique_value\"\n value={optionValueDraft}\n onChange={(event) => {\n setOptionFormError(null)\n setOptionValueDraft(event.target.value)\n }}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n placeholder={t('entities.customFields.editor.optionLabelPlaceholder', 'Label shown to users (optional)')}\n value={optionLabelDraft}\n onChange={(event) => setOptionLabelDraft(event.target.value)}\n />\n </FormField>\n </div>\n <DialogFooter>\n <Button variant=\"outline\" size=\"sm\" onClick={handleCloseOptionDialog}>\n {t('entities.customFields.editor.cancel', 'Cancel')}\n </Button>\n <Button size=\"sm\" onClick={handleAddOption}>\n {t('entities.customFields.editor.addOption', 'Add option')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <Dialog\n open={groupDialogOpen}\n onOpenChange={(open) => {\n setGroupDialogOpen(open)\n if (!open) {\n setGroupError(null)\n setEditingGroupCode(null)\n setGroupDraft({ code: '', title: '', hint: '' })\n }\n }}\n >\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>\n {editingGroupCode\n ? t('entities.customFields.editor.editGroup', 'Edit group')\n : t('entities.customFields.editor.newGroup', 'New group')}\n </DialogTitle>\n <DialogDescription>\n {editingGroupCode\n ? t('entities.customFields.editor.editGroupDescription', 'Update the selected group for this fieldset.')\n : t('entities.customFields.editor.newGroupDescription', 'Add a reusable group for this fieldset.')}\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-3\">\n <FormField label={t('entities.customFields.editor.groupCode', 'Group code')} error={groupError ?? undefined} disabled={!!editingGroupCode}>\n <Input\n inputClassName=\"font-mono\"\n value={groupDraft.code}\n onChange={(event) => {\n setGroupDraft((prev) => ({ ...prev, code: event.target.value }))\n if (groupError) setGroupError(null)\n }}\n disabled={!!editingGroupCode}\n placeholder={t('entities.customFields.editor.groupCodePlaceholder', 'e.g. buying_committee')}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n value={groupDraft.title}\n onChange={(event) => setGroupDraft((prev) => ({ ...prev, title: event.target.value }))}\n placeholder={t('entities.customFields.editor.groupLabelPlaceholder', 'Buying committee')}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.hint', 'Hint')}>\n <Input\n value={groupDraft.hint}\n onChange={(event) => setGroupDraft((prev) => ({ ...prev, hint: event.target.value }))}\n placeholder={t('entities.customFields.editor.groupHintPlaceholder', 'Visible to merchandisers')}\n />\n </FormField>\n {currentFieldsetValue && groupOptions.length > 0 ? (\n <div>\n <div className=\"text-xs font-medium mb-1\">{t('entities.customFields.editor.existingGroups', 'Existing groups')}</div>\n <div className=\"space-y-2 max-h-40 overflow-y-auto\">\n {groupOptions.map((group) => (\n <div key={group.code} className=\"flex items-center justify-between rounded border px-3 py-2 text-sm\">\n <div>\n <div className=\"font-medium\">{group.title || group.code}</div>\n <div className=\"text-xs text-muted-foreground font-mono\">{group.code}</div>\n {group.hint ? (\n <div className=\"text-xs text-muted-foreground\">{group.hint}</div>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <IconButton\n variant=\"ghost\"\n size=\"xs\"\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={() => handleEditGroupEntry(group)}\n aria-label={t('entities.customFields.editor.editGroupAria', 'Edit {code}', { code: group.code })}\n >\n <Pencil className=\"h-4 w-4\" />\n </IconButton>\n <IconButton\n variant=\"ghost\"\n size=\"xs\"\n className=\"text-destructive hover:text-destructive/80\"\n onClick={() => handleRemoveGroupEntry(group.code)}\n aria-label={t('entities.customFields.editor.deleteGroupAria', 'Delete {code}', { code: group.code })}\n >\n <Trash2 className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n <DialogFooter>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setGroupDialogOpen(false)}>\n {t('entities.customFields.editor.cancel', 'Cancel')}\n </Button>\n <Button size=\"sm\" onClick={handleGroupDialogSubmit}>\n {t('entities.customFields.editor.saveGroup', 'Save group')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n})\n\nFieldDefinitionCard.displayName = 'FieldDefinitionCard'\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Cog, GripVertical, Languages, Pencil, Plus, Trash2, X } from 'lucide-react'\nimport { Button } from '../../primitives/button'\nimport { CheckboxField } from '../../primitives/checkbox-field'\nimport { FormField } from '../../primitives/form-field'\nimport { IconButton } from '../../primitives/icon-button'\nimport { Input } from '../../primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../primitives/select'\nimport { CUSTOM_FIELD_KINDS } from '@open-mercato/shared/modules/entities/kinds'\nimport { useOptionalT } from '@open-mercato/shared/lib/i18n/context'\nimport { FieldRegistry } from '../fields/registry'\nimport { slugify } from '@open-mercato/shared/lib/slugify'\nimport { useConfirmDialog } from '../confirm-dialog'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../../primitives/dialog'\nimport {\n normalizeCustomFieldOptions,\n type CustomFieldOptionDto,\n} from '@open-mercato/shared/modules/entities/options'\n\ntype FieldsetGroup = { code: string; title?: string; hint?: string }\ntype FieldsetConfig = { code: string; label: string; icon?: string; description?: string; groups?: FieldsetGroup[] }\n\nexport type FieldDefinition = {\n key: string\n kind: string\n configJson?: Record<string, unknown>\n isActive?: boolean\n}\n\nexport type FieldDefinitionError = { key?: string; kind?: string }\n\nexport type FieldDefinitionsEditorProps = {\n definitions: FieldDefinition[]\n errors?: Record<number, FieldDefinitionError>\n deletedKeys?: string[]\n kindOptions?: Array<{ value: string; label: string }>\n orderNotice?: { dirty: boolean; saving?: boolean; message?: string }\n infoNote?: React.ReactNode\n addButtonLabel?: string\n fieldsets?: FieldsetConfig[]\n activeFieldset?: string | null\n onActiveFieldsetChange?: (code: string | null) => void\n onFieldsetsChange?: (next: FieldsetConfig[]) => void\n onFieldsetCodeChange?: (previousCode: string, nextCode: string) => void\n onFieldsetRemoved?: (code: string) => void\n onAddField: () => void\n onRemoveField: (index: number) => void\n onDefinitionChange: (index: number, next: FieldDefinition) => void\n onRestoreField?: (key: string) => void\n onReorder?: (from: number, to: number) => void\n onTranslate?: (definition: FieldDefinition, index: number) => void\n listRef?: React.Ref<HTMLDivElement>\n listProps?: React.HTMLAttributes<HTMLDivElement>\n singleFieldsetPerRecord?: boolean\n onSingleFieldsetPerRecordChange?: (value: boolean) => void\n translate?: (key: string, fallback: string) => string\n}\n\nconst DEFAULT_VALUE_NONE = '__open_mercato_no_default__'\n\nfunction getDefaultValueNoneOptionValue(options: CustomFieldOptionDto[]): string {\n const optionValues = new Set(options.map((option) => String(option.value)))\n let candidate = DEFAULT_VALUE_NONE\n while (optionValues.has(candidate)) {\n candidate = `${candidate}_`\n }\n return candidate\n}\n\nconst FIELDSET_ICON_OPTIONS = [\n { value: 'layers', label: 'Layers' },\n { value: 'tag', label: 'Tag' },\n { value: 'sparkles', label: 'Sparkles' },\n { value: 'package', label: 'Package' },\n { value: 'shirt', label: 'Shirt' },\n { value: 'grid', label: 'Grid' },\n { value: 'shoppingBag', label: 'Shopping bag' },\n { value: 'shoppingCart', label: 'Shopping cart' },\n { value: 'store', label: 'Store' },\n { value: 'users', label: 'Users' },\n { value: 'briefcase', label: 'Briefcase' },\n { value: 'building', label: 'Building' },\n { value: 'bookOpen', label: 'Book open' },\n { value: 'bookmark', label: 'Bookmark' },\n { value: 'camera', label: 'Camera' },\n { value: 'car', label: 'Car' },\n { value: 'clock', label: 'Clock' },\n { value: 'cloud', label: 'Cloud' },\n { value: 'compass', label: 'Compass' },\n { value: 'creditCard', label: 'Credit card' },\n { value: 'database', label: 'Database' },\n { value: 'flame', label: 'Flame' },\n { value: 'gift', label: 'Gift' },\n { value: 'globe', label: 'Globe' },\n { value: 'heart', label: 'Heart' },\n { value: 'key', label: 'Key' },\n { value: 'map', label: 'Map' },\n { value: 'palette', label: 'Palette' },\n { value: 'shield', label: 'Shield' },\n { value: 'star', label: 'Star' },\n { value: 'truck', label: 'Truck' },\n { value: 'zap', label: 'Zap' },\n { value: 'coins', label: 'Coins' },\n]\n\nfunction slugifyFieldsetCode(value: string): string {\n return slugify(value, { replacement: '', allowedChars: '_-' })\n}\n\nfunction ensureUniqueFieldsetCode(base: string, existing: FieldsetConfig[]): string {\n const sanitizedBase = slugifyFieldsetCode(base) || 'fieldset'\n let candidate = sanitizedBase\n let counter = 1\n const existingCodes = new Set(existing.map((fs) => fs.code))\n while (existingCodes.has(candidate)) {\n counter += 1\n candidate = `${sanitizedBase}_${counter}`\n }\n return candidate\n}\n\nfunction normalizeGroupValue(raw: unknown): FieldsetGroup | null {\n if (!raw) return null\n if (typeof raw === 'string') {\n const code = raw.trim()\n return code ? { code } : null\n }\n if (typeof raw !== 'object') return null\n const entry = raw as Record<string, unknown>\n const code = typeof entry.code === 'string' ? entry.code.trim() : ''\n if (!code) return null\n const group: FieldsetGroup = { code }\n if (typeof entry.title === 'string' && entry.title.trim()) group.title = entry.title.trim()\n if (typeof entry.hint === 'string' && entry.hint.trim()) group.hint = entry.hint.trim()\n return group\n}\n\nexport function FieldDefinitionsEditor({\n definitions,\n errors,\n deletedKeys,\n kindOptions,\n orderNotice,\n infoNote,\n addButtonLabel,\n fieldsets = [],\n activeFieldset = null,\n onActiveFieldsetChange,\n onFieldsetsChange,\n onFieldsetCodeChange,\n onFieldsetRemoved,\n singleFieldsetPerRecord,\n onSingleFieldsetPerRecordChange,\n onAddField,\n onRemoveField,\n onDefinitionChange,\n onRestoreField,\n onReorder,\n onTranslate,\n listRef,\n listProps,\n translate,\n}: FieldDefinitionsEditorProps) {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const dragIndex = React.useRef<number | null>(null)\n const hasFieldsets = fieldsets.length > 0\n const contextT = useOptionalT()\n const t = React.useCallback(\n (key: string, fallback: string) => {\n if (translate) return translate(key, fallback)\n if (contextT) return contextT(key, fallback)\n return fallback\n },\n [translate, contextT],\n )\n const resolvedKindOptions = React.useMemo(\n () =>\n kindOptions ??\n CUSTOM_FIELD_KINDS.map((kind) => ({\n value: kind,\n label: t(`entities.customFields.editor.kindOption.${kind}`, kind.charAt(0).toUpperCase() + kind.slice(1)),\n })),\n [kindOptions, t],\n )\n const resolvedInfoNote = infoNote !== undefined ? infoNote : (\n <div className=\"text-xs text-muted-foreground mt-2\">\n {t(\n 'entities.customFields.editor.supportedKindsNote',\n 'Supported kinds: text, multiline, integer, float, boolean, select (with options/optionsUrl), currency (fixed currencies list), relation (with related entity and options URL).',\n )}\n </div>\n )\n const resolvedAddButtonLabel = addButtonLabel ?? t('entities.customFields.editor.addField', 'Add Field')\n const resolvedActiveFieldset = React.useMemo(() => {\n if (!hasFieldsets) return activeFieldset ?? null\n if (activeFieldset === null) return null\n return fieldsets.some((fs) => fs.code === activeFieldset) ? activeFieldset : (fieldsets[0]?.code ?? null)\n }, [activeFieldset, fieldsets, hasFieldsets])\n\n const filteredDefinitions = React.useMemo(\n () =>\n definitions\n .map((definition, index) => ({ definition, index }))\n .filter(({ definition }) => {\n if (!hasFieldsets) return true\n const assigned = typeof definition.configJson?.fieldset === 'string' ? definition.configJson.fieldset : undefined\n if (!resolvedActiveFieldset) return !assigned\n return assigned === resolvedActiveFieldset\n }),\n [definitions, hasFieldsets, resolvedActiveFieldset],\n )\n\n const activeFieldsetConfig = hasFieldsets && resolvedActiveFieldset\n ? fieldsets.find((fs) => fs.code === resolvedActiveFieldset) ?? null\n : null\n\n const handleActiveFieldsetChange = (value: string) => {\n if (!onActiveFieldsetChange) return\n onActiveFieldsetChange(value ? value : null)\n }\n\n const handleFieldsetPatch = (code: string, patch: Partial<FieldsetConfig>) => {\n if (!onFieldsetsChange) return\n const next = fieldsets.map((fs) => (fs.code === code ? { ...fs, ...patch } : fs))\n onFieldsetsChange(next)\n }\n\n const handleFieldsetCodeInput = (code: string, nextValue: string) => {\n if (!onFieldsetsChange) return\n const target = fieldsets.find((fs) => fs.code === code)\n if (!target) return\n const sanitized = slugifyFieldsetCode(nextValue)\n if (!sanitized) return\n const next = fieldsets.map((fs) => (fs.code === code ? { ...fs, code: sanitized } : fs))\n onFieldsetsChange(next)\n onFieldsetCodeChange?.(code, sanitized)\n onActiveFieldsetChange?.(sanitized)\n }\n\n const handleAddFieldset = () => {\n if (!onFieldsetsChange) return\n const code = ensureUniqueFieldsetCode(`fieldset_${fieldsets.length + 1}`, fieldsets)\n const nextFieldsets = [...fieldsets, { code, label: t('entities.customFields.editor.newFieldsetLabel', 'New fieldset'), icon: 'layers' }]\n onFieldsetsChange(nextFieldsets)\n onActiveFieldsetChange?.(code)\n }\n\n const handleRemoveFieldset = async () => {\n if (!onFieldsetsChange) return\n if (!resolvedActiveFieldset) return\n const confirmed = await confirm({\n title: t('entities.customFields.editor.deleteFieldsetTitle', 'Delete fieldset \"{code}\"?').replace('{code}', resolvedActiveFieldset),\n text: t('entities.customFields.editor.deleteFieldsetText', 'This will move its fields to Unassigned.'),\n variant: 'destructive',\n })\n if (!confirmed) return\n const next = fieldsets.filter((fs) => fs.code !== resolvedActiveFieldset)\n onFieldsetsChange(next)\n onFieldsetRemoved?.(resolvedActiveFieldset)\n const fallback = next[0]?.code ?? null\n onActiveFieldsetChange?.(fallback)\n }\n\n const registerGroup = React.useCallback(\n (fieldsetCode: string, group: FieldsetGroup) => {\n if (!onFieldsetsChange || !fieldsetCode) return\n const next = fieldsets.map((fs) => {\n if (fs.code !== fieldsetCode) return fs\n const list = Array.isArray(fs.groups) ? fs.groups : []\n const existingIndex = list.findIndex((entry) => entry.code === group.code)\n if (existingIndex >= 0) {\n const updated = [...list]\n updated[existingIndex] = { ...list[existingIndex], ...group }\n return { ...fs, groups: updated }\n }\n return { ...fs, groups: [...list, group] }\n })\n onFieldsetsChange(next)\n },\n [fieldsets, onFieldsetsChange],\n )\n const removeGroup = React.useCallback(\n (fieldsetCode: string, groupCode: string) => {\n if (!onFieldsetsChange || !fieldsetCode || !groupCode) return\n const next = fieldsets.map((fs) => {\n if (fs.code !== fieldsetCode) return fs\n const list = Array.isArray(fs.groups) ? fs.groups : []\n return { ...fs, groups: list.filter((entry) => entry.code !== groupCode) }\n })\n onFieldsetsChange(next)\n },\n [fieldsets, onFieldsetsChange],\n )\n const availableGroups = activeFieldsetConfig?.groups ?? []\n const canToggleSingleFieldset = hasFieldsets && fieldsets.length > 1\n const singleFieldsetChecked = singleFieldsetPerRecord !== false\n\n const handleReorder = React.useCallback(\n (from: number, to: number) => {\n if (from === to) return\n onReorder?.(from, to)\n },\n [onReorder],\n )\n\n return (\n <div\n ref={listRef}\n className=\"space-y-3\"\n {...listProps}\n >\n {hasFieldsets ? (\n <div className=\"rounded border bg-card p-3 space-y-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <label className=\"text-xs font-medium text-muted-foreground\">{t('entities.customFields.fieldsetSelectorLabel', 'Fieldset')}</label>\n <Select\n value={resolvedActiveFieldset || undefined}\n onValueChange={(value) => handleActiveFieldsetChange(value ?? '')}\n >\n <SelectTrigger size=\"sm\" className=\"w-auto min-w-[10rem]\">\n <SelectValue placeholder={t('entities.customFields.editor.unassignedFields', 'Unassigned fields')} />\n </SelectTrigger>\n <SelectContent>\n {fieldsets.map((fs) => (\n <SelectItem key={fs.code} value={fs.code}>\n {fs.label || fs.code}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAddFieldset}\n className=\"text-xs\"\n >\n <Plus className=\"h-3.5 w-3.5\" /> {t('entities.customFields.editor.add', 'Add')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleRemoveFieldset}\n disabled={!resolvedActiveFieldset}\n className=\"text-xs\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" /> {t('entities.customFields.editor.delete', 'Delete')}\n </Button>\n </div>\n {resolvedActiveFieldset && activeFieldsetConfig ? (\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-3\">\n <FormField label={t('entities.customFields.editor.code', 'Code')}>\n <Input\n size=\"sm\"\n inputClassName=\"font-mono\"\n value={activeFieldsetConfig.code}\n onChange={(event) => handleFieldsetCodeInput(activeFieldsetConfig.code, event.target.value)}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n size=\"sm\"\n value={activeFieldsetConfig.label}\n onChange={(event) => handleFieldsetPatch(activeFieldsetConfig.code, { label: event.target.value })}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.icon', 'Icon')}>\n <Select\n value={activeFieldsetConfig.icon || undefined}\n onValueChange={(value) =>\n handleFieldsetPatch(activeFieldsetConfig.code, {\n icon: value || undefined,\n })\n }\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('entities.customFields.editor.defaultOption', 'Default')} />\n </SelectTrigger>\n <SelectContent>\n {FIELDSET_ICON_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {t(`entities.customFields.editor.iconOption.${option.value}`, option.label)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n <FormField label={t('entities.customFields.editor.description', 'Description')}>\n <Input\n size=\"sm\"\n value={activeFieldsetConfig.description ?? ''}\n onChange={(event) => handleFieldsetPatch(activeFieldsetConfig.code, { description: event.target.value })}\n />\n </FormField>\n </div>\n ) : null}\n <div className=\"flex items-center gap-2\">\n <CheckboxField\n size=\"sm\"\n disabled={!canToggleSingleFieldset}\n checked={singleFieldsetChecked}\n onCheckedChange={(checked) => onSingleFieldsetPerRecordChange?.(checked === true)}\n label={t('entities.customFields.editor.singleFieldsetPerEntity', 'Single fieldset per entity')}\n containerClassName=\"text-xs\"\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n {!canToggleSingleFieldset ? (\n <span className=\"text-xs text-muted-foreground\">{t('entities.customFields.editor.singleFieldsetToggleHint', '(add at least two fieldsets to toggle)')}</span>\n ) : null}\n </div>\n </div>\n ) : (\n <div className=\"rounded border border-dashed bg-muted/30 p-4 text-sm text-muted-foreground flex flex-col gap-3\">\n <div>{t('entities.customFields.editor.noFieldsets', 'No fieldsets defined yet. Fieldsets let you group custom fields for different variants of the same entity (e.g., Fashion vs. Sport products).')}</div>\n <div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAddFieldset}\n >\n <Plus className=\"h-4 w-4\" />\n {t('entities.customFields.editor.addFirstFieldset', 'Add first fieldset')}\n </Button>\n </div>\n </div>\n )}\n {orderNotice?.dirty && (\n <div className=\"sticky top-0 z-sticky -mt-1 -mb-1\">\n <div className=\"inline-flex items-center gap-2 text-xs px-2 py-1 rounded border border-status-warning-border bg-status-warning-bg text-status-warning-text shadow-sm\">\n {orderNotice?.saving\n ? t('entities.customFields.editor.savingOrder', 'Saving order\u2026')\n : (orderNotice?.message ?? t('entities.customFields.editor.reorderedSavingSoon', 'Reordered \u2014 saving soon'))}\n </div>\n </div>\n )}\n {filteredDefinitions.map(({ definition, index }) => {\n const assignedFieldset = typeof definition.configJson?.fieldset === 'string' ? definition.configJson.fieldset : null\n const groupOptions = assignedFieldset\n ? fieldsets.find((fs) => fs.code === assignedFieldset)?.groups ?? []\n : availableGroups\n return (\n <div\n key={definition.key || `def-${index}`}\n className=\"group\"\n draggable\n onDragStart={() => { dragIndex.current = index }}\n onDragOver={(event) => { event.preventDefault() }}\n onDrop={() => {\n const from = dragIndex.current\n if (from == null) return\n dragIndex.current = null\n handleReorder(from, index)\n }}\n onDragEnd={() => { dragIndex.current = null }}\n tabIndex={0}\n onKeyDown={(event) => {\n if (!event.altKey) return\n if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault()\n handleReorder(index, Math.max(0, index - 1))\n }\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault()\n handleReorder(index, Math.min(definitions.length - 1, index + 1))\n }\n }}\n >\n <FieldDefinitionCard\n definition={definition}\n error={errors?.[index]}\n kindOptions={resolvedKindOptions}\n onChange={(next) => onDefinitionChange(index, next)}\n onRemove={() => onRemoveField(index)}\n allowFieldsetSelection={hasFieldsets}\n fieldsets={fieldsets}\n activeFieldset={resolvedActiveFieldset}\n availableGroups={groupOptions}\n onRegisterGroup={registerGroup}\n onRemoveGroup={removeGroup}\n onTranslate={onTranslate ? () => onTranslate(definition, index) : undefined}\n translate={t}\n />\n </div>\n )})}\n <div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={onAddField}\n >\n <Plus className=\"h-4 w-4\" /> {resolvedAddButtonLabel}\n </Button>\n {resolvedInfoNote}\n {deletedKeys && deletedKeys.length > 0 && onRestoreField ? (\n <div className=\"text-xs text-muted-foreground mt-2\">\n {t('entities.customFields.editor.restoreDeletedFields', 'Restore deleted fields:')}{' '}\n {deletedKeys.map((key, idx) => (\n <span key={key}>\n <Button\n variant=\"link\"\n className=\"h-auto p-0\"\n onClick={() => onRestoreField(key)}\n >\n {key}\n </Button>\n {idx < deletedKeys.length - 1 ? ', ' : ''}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n {ConfirmDialogElement}\n </div>\n )\n}\n\ntype FieldDefinitionCardProps = {\n definition: FieldDefinition\n error?: FieldDefinitionError\n kindOptions: Array<{ value: string; label: string }>\n onChange: (next: FieldDefinition) => void\n onRemove: () => void\n allowFieldsetSelection?: boolean\n fieldsets?: FieldsetConfig[]\n activeFieldset?: string | null\n availableGroups?: FieldsetGroup[]\n onRegisterGroup?: (fieldsetCode: string, group: FieldsetGroup) => void\n onRemoveGroup?: (fieldsetCode: string, groupCode: string) => void\n onTranslate?: () => void\n translate?: (key: string, fallback: string) => string\n}\n\nconst FieldDefinitionCard = React.memo(function FieldDefinitionCard({\n definition,\n error,\n kindOptions,\n onChange,\n onRemove,\n allowFieldsetSelection = false,\n fieldsets = [],\n activeFieldset,\n availableGroups = [],\n onRegisterGroup,\n onRemoveGroup,\n onTranslate,\n translate,\n}: FieldDefinitionCardProps) {\n const [local, setLocal] = React.useState<FieldDefinition>(definition)\n const localRef = React.useRef<FieldDefinition>(definition)\n const [optionValueDraft, setOptionValueDraft] = React.useState('')\n const [optionLabelDraft, setOptionLabelDraft] = React.useState('')\n const [optionDialogOpen, setOptionDialogOpen] = React.useState(false)\n const [optionFormError, setOptionFormError] = React.useState<string | null>(null)\n const [groupDialogOpen, setGroupDialogOpen] = React.useState(false)\n const [groupDraft, setGroupDraft] = React.useState({ code: '', title: '', hint: '' })\n const [editingGroupCode, setEditingGroupCode] = React.useState<string | null>(null)\n const [groupError, setGroupError] = React.useState<string | null>(null)\n const currentFieldsetValue = React.useMemo(\n () => (typeof local.configJson?.fieldset === 'string' ? local.configJson.fieldset : ''),\n [local.configJson?.fieldset],\n )\n const t = React.useCallback((key: string, fallback: string) => (translate ? translate(key, fallback) : fallback), [translate])\n React.useEffect(() => {\n localRef.current = definition\n setLocal(definition)\n }, [definition.key])\n React.useEffect(() => {\n setOptionValueDraft('')\n setOptionLabelDraft('')\n setGroupDialogOpen(false)\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n setGroupError(null)\n }, [definition.key])\n React.useEffect(() => {\n if (!currentFieldsetValue) {\n setGroupDialogOpen(false)\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n setGroupError(null)\n }\n }, [currentFieldsetValue])\n const currentGroup = React.useMemo(() => normalizeGroupValue(local.configJson?.group), [local])\n const groupOptions = React.useMemo(() => {\n const list = Array.isArray(availableGroups) ? [...availableGroups] : []\n if (currentGroup && !list.some((entry) => entry.code === currentGroup.code)) {\n list.push(currentGroup)\n }\n return list\n }, [availableGroups, currentGroup])\n const resolvedOptions = React.useMemo<CustomFieldOptionDto[]>(\n () => normalizeCustomFieldOptions(local.configJson?.options),\n [local.configJson?.options],\n )\n\n const sanitize = (def: FieldDefinition): FieldDefinition => {\n if (!def.configJson || !Array.isArray(def.configJson.options)) return def\n const normalizedOptions = normalizeCustomFieldOptions(def.configJson.options)\n return {\n ...def,\n configJson: {\n ...def.configJson,\n options: normalizedOptions,\n },\n }\n }\n\n const replaceLocal = React.useCallback((next: FieldDefinition) => {\n localRef.current = next\n setLocal(next)\n return next\n }, [])\n\n const apply = (patch: Partial<FieldDefinition> | ((current: FieldDefinition) => Partial<FieldDefinition>), propagateNow = false) => {\n const current = localRef.current\n const resolvedPatch = typeof patch === 'function' ? patch(current) : patch\n const next = { ...current, ...resolvedPatch }\n const resolvedNext = propagateNow ? sanitize(next) : next\n replaceLocal(resolvedNext)\n if (propagateNow) {\n onChange(resolvedNext)\n }\n }\n\n const commit = () => {\n const sanitized = sanitize(localRef.current)\n replaceLocal(sanitized)\n onChange(sanitized)\n }\n\n const handleFieldsetSelect = (value: string) => {\n const nextConfig = { ...(localRef.current.configJson || {}) }\n if (value) nextConfig.fieldset = value\n else delete nextConfig.fieldset\n delete nextConfig.group\n const next = { ...localRef.current, configJson: nextConfig }\n replaceLocal(next)\n onChange(next)\n }\n\n const handleGroupSelect = (value: string) => {\n if (!currentFieldsetValue) return\n if (!value) {\n const nextConfig = { ...(local.configJson || {}) }\n delete nextConfig.group\n apply({ configJson: nextConfig }, true)\n return\n }\n const match = groupOptions.find((group) => group.code === value)\n const nextGroup = match ?? { code: value }\n const nextConfig = { ...(local.configJson || {}) }\n nextConfig.group = nextGroup\n apply({ configJson: nextConfig }, true)\n onRegisterGroup?.(currentFieldsetValue, nextGroup)\n }\n\n const handleOpenGroupDialog = (group?: FieldsetGroup) => {\n if (!currentFieldsetValue) return\n if (group) {\n setGroupDraft({\n code: group.code,\n title: group.title ?? '',\n hint: group.hint ?? '',\n })\n setEditingGroupCode(group.code)\n } else {\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n }\n setGroupError(null)\n setGroupDialogOpen(true)\n }\n\n const handleGroupDialogSubmit = () => {\n if (!currentFieldsetValue) return\n const code = slugifyFieldsetCode(groupDraft.code || '')\n if (!code) {\n setGroupError(t('entities.customFields.editor.groupCodeRequired', 'Group code is required.'))\n return\n }\n const group: FieldsetGroup = {\n code,\n title: groupDraft.title.trim() || undefined,\n hint: groupDraft.hint.trim() || undefined,\n }\n onRegisterGroup?.(currentFieldsetValue, group)\n const shouldAttachToField = !editingGroupCode || currentGroup?.code === editingGroupCode\n if (shouldAttachToField) {\n const nextConfig = { ...(local.configJson || {}) }\n nextConfig.group = group\n apply({ configJson: nextConfig }, true)\n }\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n setGroupDialogOpen(false)\n }\n\n const handleRemoveGroupEntry = (code: string) => {\n if (!currentFieldsetValue) return\n onRemoveGroup?.(currentFieldsetValue, code)\n if (currentGroup?.code === code) {\n handleGroupSelect('')\n }\n if (editingGroupCode === code) {\n setGroupDraft({ code: '', title: '', hint: '' })\n setEditingGroupCode(null)\n }\n }\n\n const handleEditGroupEntry = (group: FieldsetGroup) => {\n handleOpenGroupDialog(group)\n }\n\n const resetOptionDialog = () => {\n setOptionValueDraft('')\n setOptionLabelDraft('')\n setOptionFormError(null)\n }\n\n const handleOpenOptionDialog = () => {\n resetOptionDialog()\n setOptionDialogOpen(true)\n }\n\n const handleCloseOptionDialog = () => {\n resetOptionDialog()\n setOptionDialogOpen(false)\n }\n\n const handleAddOption = () => {\n const value = optionValueDraft.trim()\n const label = optionLabelDraft.trim()\n if (!value) {\n setOptionFormError(t('entities.customFields.editor.valueRequired', 'Value is required'))\n return\n }\n setOptionFormError(null)\n const nextOptions = Array.isArray(local.configJson?.options) ? [...local.configJson!.options] : []\n nextOptions.push({ value, label: label || value })\n apply({ configJson: { ...(local.configJson || {}), options: nextOptions } }, true)\n handleCloseOptionDialog()\n }\n\n const handleRemoveOption = (index: number) => {\n const nextOptions = Array.isArray(local.configJson?.options) ? [...local.configJson!.options] : []\n nextOptions.splice(index, 1)\n apply({ configJson: { ...(local.configJson || {}), options: nextOptions } }, true)\n }\n\n return (\n <>\n <div className=\"rounded border p-3 bg-card transition-colors hover:border-muted-foreground/60\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"inline-flex items-center justify-center h-5 w-5 rounded hover:bg-muted cursor-grab active:cursor-grabbing\">\n <GripVertical className=\"h-4 w-4 opacity-70\" />\n </span>\n {t('entities.customFields.editor.dragToReorder', 'Drag to reorder')}\n </div>\n <div className=\"flex items-center gap-3\">\n <CheckboxField\n size=\"sm\"\n checked={local.isActive !== false}\n onCheckedChange={(checked) => { apply({ isActive: checked === true }, true) }}\n label={t('entities.customFields.editor.active', 'Active')}\n containerClassName=\"text-sm\"\n contentClassName=\"gap-1 [&_label]:text-sm [&_label]:font-normal\"\n />\n {onTranslate && (\n <IconButton variant=\"outline\" size=\"sm\" onClick={onTranslate} aria-label={t('entities.customFields.editor.translateField', 'Translate field')}>\n <Languages className=\"h-4 w-4\" />\n </IconButton>\n )}\n <IconButton variant=\"outline\" size=\"sm\" onClick={onRemove} aria-label={t('entities.customFields.editor.removeField', 'Remove field')}>\n <Trash2 className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n\n <div className=\"mt-3 grid grid-cols-1 md:grid-cols-12 gap-3 items-center\">\n <FormField label={t('entities.customFields.editor.key', 'Key')} error={error?.key} className=\"md:col-span-6\">\n <Input\n inputClassName=\"font-mono\"\n placeholder=\"snake_case\"\n value={local.key}\n onChange={(event) => apply({ key: event.target.value })}\n onBlur={commit}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.kind', 'Kind')} error={error?.kind} className=\"md:col-span-6\">\n <Select\n value={local.kind || undefined}\n onValueChange={(value) => { apply({ kind: value ?? '' }, true) }}\n >\n <SelectTrigger aria-invalid={!!error?.kind}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {kindOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n </div>\n\n {allowFieldsetSelection ? (\n <div className=\"mt-3 grid grid-cols-1 md:grid-cols-2 gap-3\">\n <div>\n <label className=\"text-xs\">{t('entities.customFields.editor.assignToFieldset', 'Assign to fieldset')}</label>\n <Select\n value={currentFieldsetValue || undefined}\n onValueChange={(value) => handleFieldsetSelect(value ?? '')}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.customFields.editor.unassigned', 'Unassigned')} />\n </SelectTrigger>\n <SelectContent>\n {(fieldsets || []).map((fs) => (\n <SelectItem key={fs.code} value={fs.code}>\n {fs.label || fs.code}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {currentFieldsetValue ? (\n <div>\n <div className=\"flex items-center justify-between\">\n <label className=\"text-xs\">{t('entities.customFields.editor.group', 'Group')}</label>\n </div>\n <div className=\"flex items-center gap-2 mt-1\">\n <Select\n value={currentGroup?.code || undefined}\n onValueChange={(value) => handleGroupSelect(value ?? '')}\n >\n <SelectTrigger className=\"flex-1\">\n <SelectValue placeholder={t('entities.customFields.editor.noGroup', 'No group')} />\n </SelectTrigger>\n <SelectContent>\n {groupOptions.map((group) => (\n <SelectItem key={group.code} value={group.code}>\n {group.title || group.code}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <IconButton\n variant=\"outline\"\n className=\"text-muted-foreground\"\n onClick={() => handleOpenGroupDialog()}\n aria-label={t('entities.customFields.editor.createGroup', 'Create group')}\n >\n <Plus className=\"h-4 w-4\" />\n </IconButton>\n <IconButton\n variant=\"outline\"\n className=\"text-muted-foreground\"\n onClick={() => handleOpenGroupDialog()}\n aria-label={t('entities.customFields.editor.editGroups', 'Edit groups')}\n >\n <Cog className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n ) : null}\n </div>\n ) : null}\n\n <div className=\"mt-3 grid grid-cols-1 md:grid-cols-2 gap-3\">\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n value={typeof local.configJson?.label === 'string' ? local.configJson.label : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), label: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.description', 'Description')}>\n <Input\n value={typeof local.configJson?.description === 'string' ? local.configJson.description : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), description: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n\n {(local.kind === 'text' || local.kind === 'multiline') && (\n <>\n <div>\n <label className=\"text-xs\">{t('entities.customFields.editor.editor', 'Editor')}</label>\n <Select\n value={typeof local.configJson?.editor === 'string' && local.configJson.editor ? local.configJson.editor : undefined}\n onValueChange={(value) => { apply({ configJson: { ...(local.configJson || {}), editor: value || undefined } }, true) }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.customFields.editor.defaultOption', 'Default')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"markdown\">{t('entities.customFields.editor.editorMarkdown', 'Markdown (UIW)')}</SelectItem>\n <SelectItem value=\"simpleMarkdown\">{t('entities.customFields.editor.editorSimpleMarkdown', 'Simple Markdown')}</SelectItem>\n <SelectItem value=\"htmlRichText\">{t('entities.customFields.editor.editorHtmlRichText', 'HTML Rich Text')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n {local.kind === 'text' && (\n <>\n <CheckboxField\n size=\"sm\"\n checked={!!local.configJson?.multi}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), multi: checked === true } }, true) }}\n label={t('entities.customFields.editor.multiple', 'Multiple')}\n containerClassName=\"md:col-span-2\"\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n {!!local.configJson?.multi && (\n <div className=\"md:col-span-2\">\n <label className=\"text-xs\">{t('entities.customFields.editor.multiSelectInputStyle', 'Multi-select input style')}</label>\n <Select\n value={local.configJson?.input === 'listbox' ? 'listbox' : 'default'}\n onValueChange={(value) => {\n const nextConfig = { ...(local.configJson || {}) }\n if (value === 'listbox') nextConfig.input = 'listbox'\n else delete nextConfig.input\n apply({ configJson: nextConfig }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"default\">{t('entities.customFields.editor.defaultOption', 'Default')}</SelectItem>\n <SelectItem value=\"listbox\">{t('entities.customFields.editor.listboxSearchable', 'Listbox (searchable)')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </>\n )}\n </>\n )}\n\n {local.kind === 'select' && (\n <div className=\"md:col-span-6 space-y-3\">\n <label className=\"text-xs\">{t('entities.customFields.editor.options', 'Options')}</label>\n <div className=\"space-y-2\">\n {resolvedOptions.length > 0 ? (\n resolvedOptions.map((option, idx) => (\n <div\n key={`${option.value}-${idx}`}\n className=\"flex items-center justify-between rounded border px-3 py-2 text-xs bg-muted\"\n >\n <div>\n <div className=\"font-medium text-foreground\">{option.label}</div>\n <div className=\"text-muted-foreground font-mono text-overline\">{option.value}</div>\n </div>\n <IconButton\n variant=\"ghost\"\n size=\"xs\"\n className=\"text-destructive hover:text-destructive/80\"\n onClick={() => handleRemoveOption(idx)}\n aria-label={t('entities.customFields.editor.removeOption', 'Remove option')}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </IconButton>\n </div>\n ))\n ) : (\n <span className=\"text-xs text-muted-foreground\">{t('entities.customFields.editor.noOptionsDefined', 'No options defined.')}</span>\n )}\n </div>\n <div className=\"flex justify-end\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={handleOpenOptionDialog}\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t('entities.customFields.editor.addOption', 'Add option')}\n </Button>\n </div>\n </div>\n )}\n\n {(local.kind === 'select' || local.kind === 'relation') && (\n <>\n <FormField label={t('entities.customFields.editor.optionsUrl', 'Options URL')}>\n <Input\n placeholder=\"/api/...\"\n value={typeof local.configJson?.optionsUrl === 'string' ? local.configJson.optionsUrl : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), optionsUrl: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n {local.kind === 'relation' && (\n <FormField label={t('entities.customFields.editor.relatedEntityId', 'Related Entity ID')}>\n <Input\n inputClassName=\"font-mono\"\n placeholder=\"module:entity\"\n value={typeof local.configJson?.relatedEntityId === 'string' ? local.configJson.relatedEntityId : ''}\n onChange={(event) => {\n const relatedEntityId = event.target.value\n const defOptionsUrl = relatedEntityId\n ? `/api/entities/relations/options?entityId=${encodeURIComponent(relatedEntityId)}`\n : ''\n apply({\n configJson: {\n ...(local.configJson || {}),\n relatedEntityId,\n optionsUrl: local.configJson?.optionsUrl || defOptionsUrl,\n },\n })\n }}\n onBlur={commit}\n />\n </FormField>\n )}\n </>\n )}\n\n {local.kind === 'currency' && (\n <div className=\"md:col-span-2\">\n <label className=\"text-xs\">{t('entities.customFields.editor.optionsSource', 'Options source')}</label>\n <div className=\"rounded border bg-muted px-2 py-1 text-xs text-muted-foreground\">\n /api/currencies/options\n </div>\n </div>\n )}\n\n {(local.kind === 'integer' || local.kind === 'float') && (\n <FormField label={t('entities.customFields.editor.unitsOptional', 'Units (optional)')} className=\"md:col-span-2\">\n <Input\n placeholder={t('entities.customFields.editor.unitsPlaceholder', 'kg, cm, etc.')}\n value={typeof local.configJson?.unit === 'string' ? local.configJson.unit : ''}\n onChange={(event) => apply({ configJson: { ...(local.configJson || {}), unit: event.target.value } })}\n onBlur={commit}\n />\n </FormField>\n )}\n </div>\n\n <div className=\"mt-3 pt-3 border-t\">\n <div className=\"flex items-center justify-between mb-2\">\n <label className=\"text-sm font-medium\">{t('entities.customFields.editor.validationRules', 'Validation rules')}</label>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs\"\n onClick={() => {\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n list.push({ rule: 'required', message: t('entities.customFields.editor.ruleRequiredMessage', 'This field is required') } as any)\n return { configJson: { ...(current.configJson || {}), validation: list } }\n }, true)\n }}\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t('entities.customFields.editor.addRule', 'Add rule')}\n </Button>\n </div>\n <div className=\"space-y-2\">\n {(Array.isArray(local.configJson?.validation) ? local.configJson!.validation : []).map((rule: any, index: number) => (\n <div key={index} className=\"grid grid-cols-1 md:grid-cols-12 gap-2 items-center\">\n <div className=\"md:col-span-3\">\n <Select\n value={rule?.rule || 'required'}\n onValueChange={(value) => {\n const nextRule = value\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n const existing = (list[index] as any) || {}\n list[index] = { ...existing, rule: nextRule, message: existing.message || rule?.message || '' }\n return { configJson: { ...(current.configJson || {}), validation: list } }\n }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"required\">required</SelectItem>\n <SelectItem value=\"date\">date</SelectItem>\n <SelectItem value=\"integer\">integer</SelectItem>\n <SelectItem value=\"float\">float</SelectItem>\n <SelectItem value=\"lt\">lt</SelectItem>\n <SelectItem value=\"lte\">lte</SelectItem>\n <SelectItem value=\"gt\">gt</SelectItem>\n <SelectItem value=\"gte\">gte</SelectItem>\n <SelectItem value=\"eq\">eq</SelectItem>\n <SelectItem value=\"ne\">ne</SelectItem>\n <SelectItem value=\"regex\">regex</SelectItem>\n </SelectContent>\n </Select>\n </div>\n <div className=\"md:col-span-4\">\n <Input\n placeholder={rule?.rule === 'regex' ? t('entities.customFields.editor.rulePatternPlaceholder', 'Pattern (e.g. ^[a-z]+$)') : (['lt','lte','gt','gte'].includes(rule?.rule) ? t('entities.customFields.editor.ruleNumberPlaceholder', 'Number') : '\u2014')}\n value={rule?.param ?? ''}\n onChange={(event) => {\n const value = ['lt','lte','gt','gte'].includes(rule?.rule) ? Number(event.target.value) : event.target.value\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n const existing = (list[index] as any) || {}\n list[index] = { ...existing, ...rule, param: value }\n return { configJson: { ...(current.configJson || {}), validation: list } }\n })\n }}\n onBlur={commit}\n disabled={rule?.rule === 'required' || rule?.rule === 'date' || rule?.rule === 'integer' || rule?.rule === 'float'}\n />\n </div>\n <div className=\"md:col-span-4\">\n <Input\n placeholder={t('entities.customFields.editor.ruleErrorMessagePlaceholder', 'Error message')}\n value={rule?.message || ''}\n onChange={(event) => {\n const message = event.target.value\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n const existing = (list[index] as any) || {}\n list[index] = { ...existing, ...rule, message }\n return { configJson: { ...(current.configJson || {}), validation: list } }\n })\n }}\n onBlur={commit}\n />\n </div>\n <div className=\"md:col-span-1 flex justify-end\">\n <IconButton\n variant=\"outline\"\n size=\"sm\"\n aria-label={t('entities.customFields.editor.removeRule', 'Remove rule')}\n onClick={() => {\n apply((current) => {\n const list = Array.isArray(current.configJson?.validation) ? [...current.configJson.validation] : []\n list.splice(index, 1)\n return { configJson: { ...(current.configJson || {}), validation: list } }\n }, true)\n }}\n >\n <Trash2 className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n ))}\n {(!Array.isArray(local.configJson?.validation) || local.configJson!.validation.length === 0) && (\n <div className=\"text-xs text-muted-foreground\">{t('entities.customFields.editor.noValidationRules', 'No validation rules defined.')}</div>\n )}\n </div>\n </div>\n\n <div className=\"mt-3\">\n {(() => {\n const Editor = FieldRegistry.getDefEditor(local.kind)\n if (!Editor) return null\n return (\n <Editor\n def={{ key: local.key, kind: local.kind, configJson: local.configJson }}\n onChange={(patch) => apply({ configJson: { ...(local.configJson || {}), ...(patch || {}) } }, true)}\n />\n )\n })()}\n </div>\n\n {/* Default value control \u2014 shown for kinds without a dedicated FieldRegistry defEditor default section */}\n {(() => {\n // Dictionary kind handles defaults in its own defEditor; skip here\n if (local.kind === 'dictionary') return null\n // Relation and attachment kinds do not support defaults\n if (local.kind === 'relation' || local.kind === 'attachment') return null\n const currentDefault = local.configJson?.defaultValue\n if (local.kind === 'boolean') {\n const boolDefault = currentDefault === true ? 'true' : currentDefault === false ? 'false' : ''\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Select\n value={boolDefault || DEFAULT_VALUE_NONE}\n onValueChange={(raw) => {\n const value = raw === 'true' ? true : raw === 'false' ? false : undefined\n apply({ configJson: { ...(local.configJson || {}), defaultValue: value } }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={DEFAULT_VALUE_NONE}>{t('entities.customFields.fields.defaultValueNone', 'No default')}</SelectItem>\n <SelectItem value=\"true\">{t('entities.customFields.fields.defaultValueTrue', 'Checked (true)')}</SelectItem>\n <SelectItem value=\"false\">{t('entities.customFields.fields.defaultValueFalse', 'Unchecked (false)')}</SelectItem>\n </SelectContent>\n </Select>\n </FormField>\n )\n }\n // select with static options \u2014 picker\n if (local.kind === 'select' && !local.configJson?.multi) {\n const opts = normalizeCustomFieldOptions(local.configJson?.options || [])\n if (opts.length > 0) {\n const noneValue = getDefaultValueNoneOptionValue(opts)\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Select\n value={typeof currentDefault === 'string' || typeof currentDefault === 'number' ? String(currentDefault) : ''}\n onValueChange={(raw) => {\n if (raw === noneValue) {\n apply({ configJson: { ...(local.configJson || {}), defaultValue: undefined } }, true)\n return\n }\n // Preserve the original option type (string or number) instead of coercing to string\n const matched = opts.find((o) => String(o.value) === raw)\n const typed = matched ? matched.value : raw\n apply({ configJson: { ...(local.configJson || {}), defaultValue: typed } }, true)\n }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.customFields.fields.defaultValueNone', 'No default')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={noneValue}>{t('entities.customFields.fields.defaultValueNone', 'No default')}</SelectItem>\n {opts.map((option) => (\n <SelectItem key={String(option.value)} value={String(option.value)}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </FormField>\n )\n }\n }\n // Numeric kinds\n if (local.kind === 'integer' || local.kind === 'float') {\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Input\n type=\"number\"\n step={local.kind === 'integer' ? '1' : 'any'}\n value={typeof currentDefault === 'number' ? String(currentDefault) : ''}\n onChange={(event) => {\n const raw = event.target.value\n const parsed = raw === '' ? undefined : (local.kind === 'integer' ? parseInt(raw, 10) : parseFloat(raw))\n const value = parsed !== undefined && !isNaN(parsed) ? parsed : undefined\n apply({ configJson: { ...(local.configJson || {}), defaultValue: value } })\n }}\n onBlur={commit}\n placeholder={t('entities.customFields.fields.defaultValuePlaceholder', 'No default')}\n />\n </FormField>\n )\n }\n // Text-like kinds (text, multiline, date, datetime, currency)\n if (['text', 'multiline', 'date', 'datetime', 'currency'].includes(local.kind)) {\n return (\n <FormField label={t('entities.customFields.fields.defaultValue', 'Default value')} className=\"mt-3\">\n <Input\n value={typeof currentDefault === 'string' ? currentDefault : ''}\n onChange={(event) => {\n const value = event.target.value\n apply({ configJson: { ...(local.configJson || {}), defaultValue: value || undefined } })\n }}\n onBlur={commit}\n placeholder={t('entities.customFields.fields.defaultValuePlaceholder', 'No default')}\n />\n </FormField>\n )\n }\n return null\n })()}\n\n <div className=\"mt-3 pt-2 border-t flex flex-wrap items-center gap-4\">\n <span className=\"text-xs text-muted-foreground\">{t('entities.customFields.fields.visibility', 'Visibility:')}</span>\n <CheckboxField\n size=\"sm\"\n checked={local.configJson?.listVisible !== false}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), listVisible: checked === true } }, true) }}\n label={t('entities.customFields.fields.listVisible', 'List')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n <CheckboxField\n size=\"sm\"\n checked={!!local.configJson?.filterable}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), filterable: checked === true } }, true) }}\n label={t('entities.customFields.fields.filterable', 'Filter')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n <CheckboxField\n size=\"sm\"\n checked={local.configJson?.formEditable !== false}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), formEditable: checked === true } }, true) }}\n label={t('entities.customFields.fields.formEditable', 'Form')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n <CheckboxField\n size=\"sm\"\n checked={!!local.configJson?.encrypted}\n onCheckedChange={(checked) => { apply({ configJson: { ...(local.configJson || {}), encrypted: checked === true } }, true) }}\n label={t('entities.customFields.fields.encrypted', 'Encrypted')}\n contentClassName=\"gap-1 [&_label]:text-xs [&_label]:font-normal\"\n />\n </div>\n </div>\n <Dialog\n open={optionDialogOpen}\n onOpenChange={(open) => {\n setOptionDialogOpen(open)\n if (!open) resetOptionDialog()\n }}\n >\n <DialogContent className=\"max-w-sm\">\n <DialogHeader>\n <DialogTitle>{t('entities.customFields.editor.addOption', 'Add option')}</DialogTitle>\n <DialogDescription>{t('entities.customFields.editor.addOptionDescription', 'Provide the stored value and optional label shown to users.')}</DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4 py-2\">\n <FormField label={t('entities.customFields.editor.value', 'Value')} error={optionFormError ?? undefined}>\n <Input\n inputClassName=\"font-mono\"\n placeholder=\"unique_value\"\n value={optionValueDraft}\n onChange={(event) => {\n setOptionFormError(null)\n setOptionValueDraft(event.target.value)\n }}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n placeholder={t('entities.customFields.editor.optionLabelPlaceholder', 'Label shown to users (optional)')}\n value={optionLabelDraft}\n onChange={(event) => setOptionLabelDraft(event.target.value)}\n />\n </FormField>\n </div>\n <DialogFooter>\n <Button variant=\"outline\" size=\"sm\" onClick={handleCloseOptionDialog}>\n {t('entities.customFields.editor.cancel', 'Cancel')}\n </Button>\n <Button size=\"sm\" onClick={handleAddOption}>\n {t('entities.customFields.editor.addOption', 'Add option')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <Dialog\n open={groupDialogOpen}\n onOpenChange={(open) => {\n setGroupDialogOpen(open)\n if (!open) {\n setGroupError(null)\n setEditingGroupCode(null)\n setGroupDraft({ code: '', title: '', hint: '' })\n }\n }}\n >\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>\n {editingGroupCode\n ? t('entities.customFields.editor.editGroup', 'Edit group')\n : t('entities.customFields.editor.newGroup', 'New group')}\n </DialogTitle>\n <DialogDescription>\n {editingGroupCode\n ? t('entities.customFields.editor.editGroupDescription', 'Update the selected group for this fieldset.')\n : t('entities.customFields.editor.newGroupDescription', 'Add a reusable group for this fieldset.')}\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-3\">\n <FormField label={t('entities.customFields.editor.groupCode', 'Group code')} error={groupError ?? undefined} disabled={!!editingGroupCode}>\n <Input\n inputClassName=\"font-mono\"\n value={groupDraft.code}\n onChange={(event) => {\n setGroupDraft((prev) => ({ ...prev, code: event.target.value }))\n if (groupError) setGroupError(null)\n }}\n disabled={!!editingGroupCode}\n placeholder={t('entities.customFields.editor.groupCodePlaceholder', 'e.g. buying_committee')}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.label', 'Label')}>\n <Input\n value={groupDraft.title}\n onChange={(event) => setGroupDraft((prev) => ({ ...prev, title: event.target.value }))}\n placeholder={t('entities.customFields.editor.groupLabelPlaceholder', 'Buying committee')}\n />\n </FormField>\n <FormField label={t('entities.customFields.editor.hint', 'Hint')}>\n <Input\n value={groupDraft.hint}\n onChange={(event) => setGroupDraft((prev) => ({ ...prev, hint: event.target.value }))}\n placeholder={t('entities.customFields.editor.groupHintPlaceholder', 'Visible to merchandisers')}\n />\n </FormField>\n {currentFieldsetValue && groupOptions.length > 0 ? (\n <div>\n <div className=\"text-xs font-medium mb-1\">{t('entities.customFields.editor.existingGroups', 'Existing groups')}</div>\n <div className=\"space-y-2 max-h-40 overflow-y-auto\">\n {groupOptions.map((group) => (\n <div key={group.code} className=\"flex items-center justify-between rounded border px-3 py-2 text-sm\">\n <div>\n <div className=\"font-medium\">{group.title || group.code}</div>\n <div className=\"text-xs text-muted-foreground font-mono\">{group.code}</div>\n {group.hint ? (\n <div className=\"text-xs text-muted-foreground\">{group.hint}</div>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <IconButton\n variant=\"ghost\"\n size=\"xs\"\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={() => handleEditGroupEntry(group)}\n aria-label={t('entities.customFields.editor.editGroupAria', 'Edit {code}').replace('{code}', group.code)}\n >\n <Pencil className=\"h-4 w-4\" />\n </IconButton>\n <IconButton\n variant=\"ghost\"\n size=\"xs\"\n className=\"text-destructive hover:text-destructive/80\"\n onClick={() => handleRemoveGroupEntry(group.code)}\n aria-label={t('entities.customFields.editor.deleteGroupAria', 'Delete {code}').replace('{code}', group.code)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </IconButton>\n </div>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n <DialogFooter>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setGroupDialogOpen(false)}>\n {t('entities.customFields.editor.cancel', 'Cancel')}\n </Button>\n <Button size=\"sm\" onClick={handleGroupDialogSubmit}>\n {t('entities.customFields.editor.saveGroup', 'Save group')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n})\n\nFieldDefinitionCard.displayName = 'FieldDefinitionCard'\n"],
|
|
5
|
+
"mappings": ";AAwMI,SAgtBU,UAhtBV,KAkIQ,YAlIR;AAtMJ,YAAY,WAAW;AACvB,SAAS,KAAK,cAAc,WAAW,QAAQ,MAAM,cAAiB;AACtE,SAAS,cAAc;AACvB,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,OAEK;AAyCP,MAAM,qBAAqB;AAE3B,SAAS,+BAA+B,SAAyC;AAC/E,QAAM,eAAe,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,OAAO,OAAO,KAAK,CAAC,CAAC;AAC1E,MAAI,YAAY;AAChB,SAAO,aAAa,IAAI,SAAS,GAAG;AAClC,gBAAY,GAAG,SAAS;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,MAAM,wBAAwB;AAAA,EAC5B,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,EACnC,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,EAC7B,EAAE,OAAO,YAAY,OAAO,WAAW;AAAA,EACvC,EAAE,OAAO,WAAW,OAAO,UAAU;AAAA,EACrC,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B,EAAE,OAAO,eAAe,OAAO,eAAe;AAAA,EAC9C,EAAE,OAAO,gBAAgB,OAAO,gBAAgB;AAAA,EAChD,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,aAAa,OAAO,YAAY;AAAA,EACzC,EAAE,OAAO,YAAY,OAAO,WAAW;AAAA,EACvC,EAAE,OAAO,YAAY,OAAO,YAAY;AAAA,EACxC,EAAE,OAAO,YAAY,OAAO,WAAW;AAAA,EACvC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,EACnC,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,EAC7B,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,WAAW,OAAO,UAAU;AAAA,EACrC,EAAE,OAAO,cAAc,OAAO,cAAc;AAAA,EAC5C,EAAE,OAAO,YAAY,OAAO,WAAW;AAAA,EACvC,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,EAC7B,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,EAC7B,EAAE,OAAO,WAAW,OAAO,UAAU;AAAA,EACrC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,EACnC,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,EACjC,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,EAC7B,EAAE,OAAO,SAAS,OAAO,QAAQ;AACnC;AAEA,SAAS,oBAAoB,OAAuB;AAClD,SAAO,QAAQ,OAAO,EAAE,aAAa,IAAI,cAAc,KAAK,CAAC;AAC/D;AAEA,SAAS,yBAAyB,MAAc,UAAoC;AAClF,QAAM,gBAAgB,oBAAoB,IAAI,KAAK;AACnD,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,QAAM,gBAAgB,IAAI,IAAI,SAAS,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;AAC3D,SAAO,cAAc,IAAI,SAAS,GAAG;AACnC,eAAW;AACX,gBAAY,GAAG,aAAa,IAAI,OAAO;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,KAAoC;AAC/D,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAMA,QAAO,IAAI,KAAK;AACtB,WAAOA,QAAO,EAAE,MAAAA,MAAK,IAAI;AAAA,EAC3B;AACA,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAM,QAAQ;AACd,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI;AAClE,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,QAAuB,EAAE,KAAK;AACpC,MAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,KAAK,EAAG,OAAM,QAAQ,MAAM,MAAM,KAAK;AAC1F,MAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAG,OAAM,OAAO,MAAM,KAAK,KAAK;AACtF,SAAO;AACT;AAEO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,CAAC;AAAA,EACb,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgC;AAC9B,QAAM,EAAE,SAAS,qBAAqB,IAAI,iBAAiB;AAC3D,QAAM,YAAY,MAAM,OAAsB,IAAI;AAClD,QAAM,eAAe,UAAU,SAAS;AACxC,QAAM,WAAW,aAAa;AAC9B,QAAM,IAAI,MAAM;AAAA,IACd,CAAC,KAAa,aAAqB;AACjC,UAAI,UAAW,QAAO,UAAU,KAAK,QAAQ;AAC7C,UAAI,SAAU,QAAO,SAAS,KAAK,QAAQ;AAC3C,aAAO;AAAA,IACT;AAAA,IACA,CAAC,WAAW,QAAQ;AAAA,EACtB;AACA,QAAM,sBAAsB,MAAM;AAAA,IAChC,MACE,eACA,mBAAmB,IAAI,CAAC,UAAU;AAAA,MAChC,OAAO;AAAA,MACP,OAAO,EAAE,2CAA2C,IAAI,IAAI,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC;AAAA,IAC1G,EAAE;AAAA,IACJ,CAAC,aAAa,CAAC;AAAA,EACjB;AACA,QAAM,mBAAmB,aAAa,SAAY,WAChD,oBAAC,SAAI,WAAU,sCACZ;AAAA,IACC;AAAA,IACA;AAAA,EACF,GACF;AAEF,QAAM,yBAAyB,kBAAkB,EAAE,yCAAyC,WAAW;AACvG,QAAM,yBAAyB,MAAM,QAAQ,MAAM;AACjD,QAAI,CAAC,aAAc,QAAO,kBAAkB;AAC5C,QAAI,mBAAmB,KAAM,QAAO;AACpC,WAAO,UAAU,KAAK,CAAC,OAAO,GAAG,SAAS,cAAc,IAAI,iBAAkB,UAAU,CAAC,GAAG,QAAQ;AAAA,EACtG,GAAG,CAAC,gBAAgB,WAAW,YAAY,CAAC;AAE5C,QAAM,sBAAsB,MAAM;AAAA,IAChC,MACE,YACG,IAAI,CAAC,YAAY,WAAW,EAAE,YAAY,MAAM,EAAE,EAClD,OAAO,CAAC,EAAE,WAAW,MAAM;AAC1B,UAAI,CAAC,aAAc,QAAO;AAC1B,YAAM,WAAW,OAAO,WAAW,YAAY,aAAa,WAAW,WAAW,WAAW,WAAW;AACxG,UAAI,CAAC,uBAAwB,QAAO,CAAC;AACrC,aAAO,aAAa;AAAA,IACtB,CAAC;AAAA,IACL,CAAC,aAAa,cAAc,sBAAsB;AAAA,EACpD;AAEA,QAAM,uBAAuB,gBAAgB,yBACzC,UAAU,KAAK,CAAC,OAAO,GAAG,SAAS,sBAAsB,KAAK,OAC9D;AAEJ,QAAM,6BAA6B,CAAC,UAAkB;AACpD,QAAI,CAAC,uBAAwB;AAC7B,2BAAuB,QAAQ,QAAQ,IAAI;AAAA,EAC7C;AAEA,QAAM,sBAAsB,CAAC,MAAc,UAAmC;AAC5E,QAAI,CAAC,kBAAmB;AACxB,UAAM,OAAO,UAAU,IAAI,CAAC,OAAQ,GAAG,SAAS,OAAO,EAAE,GAAG,IAAI,GAAG,MAAM,IAAI,EAAG;AAChF,sBAAkB,IAAI;AAAA,EACxB;AAEA,QAAM,0BAA0B,CAAC,MAAc,cAAsB;AACnE,QAAI,CAAC,kBAAmB;AACxB,UAAM,SAAS,UAAU,KAAK,CAAC,OAAO,GAAG,SAAS,IAAI;AACtD,QAAI,CAAC,OAAQ;AACb,UAAM,YAAY,oBAAoB,SAAS;AAC/C,QAAI,CAAC,UAAW;AAChB,UAAM,OAAO,UAAU,IAAI,CAAC,OAAQ,GAAG,SAAS,OAAO,EAAE,GAAG,IAAI,MAAM,UAAU,IAAI,EAAG;AACvF,sBAAkB,IAAI;AACtB,2BAAuB,MAAM,SAAS;AACtC,6BAAyB,SAAS;AAAA,EACpC;AAEA,QAAM,oBAAoB,MAAM;AAC9B,QAAI,CAAC,kBAAmB;AACxB,UAAM,OAAO,yBAAyB,YAAY,UAAU,SAAS,CAAC,IAAI,SAAS;AACnF,UAAM,gBAAgB,CAAC,GAAG,WAAW,EAAE,MAAM,OAAO,EAAE,iDAAiD,cAAc,GAAG,MAAM,SAAS,CAAC;AACxI,sBAAkB,aAAa;AAC/B,6BAAyB,IAAI;AAAA,EAC/B;AAEA,QAAM,uBAAuB,YAAY;AACvC,QAAI,CAAC,kBAAmB;AACxB,QAAI,CAAC,uBAAwB;AAC7B,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,EAAE,oDAAoD,2BAA2B,EAAE,QAAQ,UAAU,sBAAsB;AAAA,MAClI,MAAM,EAAE,mDAAmD,0CAA0C;AAAA,MACrG,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,UAAW;AAChB,UAAM,OAAO,UAAU,OAAO,CAAC,OAAO,GAAG,SAAS,sBAAsB;AACxE,sBAAkB,IAAI;AACtB,wBAAoB,sBAAsB;AAC1C,UAAM,WAAW,KAAK,CAAC,GAAG,QAAQ;AAClC,6BAAyB,QAAQ;AAAA,EACnC;AAEA,QAAM,gBAAgB,MAAM;AAAA,IAC1B,CAAC,cAAsB,UAAyB;AAC9C,UAAI,CAAC,qBAAqB,CAAC,aAAc;AACzC,YAAM,OAAO,UAAU,IAAI,CAAC,OAAO;AACjC,YAAI,GAAG,SAAS,aAAc,QAAO;AACrC,cAAM,OAAO,MAAM,QAAQ,GAAG,MAAM,IAAI,GAAG,SAAS,CAAC;AACrD,cAAM,gBAAgB,KAAK,UAAU,CAAC,UAAU,MAAM,SAAS,MAAM,IAAI;AACzE,YAAI,iBAAiB,GAAG;AACtB,gBAAM,UAAU,CAAC,GAAG,IAAI;AACxB,kBAAQ,aAAa,IAAI,EAAE,GAAG,KAAK,aAAa,GAAG,GAAG,MAAM;AAC5D,iBAAO,EAAE,GAAG,IAAI,QAAQ,QAAQ;AAAA,QAClC;AACA,eAAO,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,MAAM,KAAK,EAAE;AAAA,MAC3C,CAAC;AACD,wBAAkB,IAAI;AAAA,IACxB;AAAA,IACA,CAAC,WAAW,iBAAiB;AAAA,EAC/B;AACA,QAAM,cAAc,MAAM;AAAA,IACxB,CAAC,cAAsB,cAAsB;AAC3C,UAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,UAAW;AACvD,YAAM,OAAO,UAAU,IAAI,CAAC,OAAO;AACjC,YAAI,GAAG,SAAS,aAAc,QAAO;AACrC,cAAM,OAAO,MAAM,QAAQ,GAAG,MAAM,IAAI,GAAG,SAAS,CAAC;AACrD,eAAO,EAAE,GAAG,IAAI,QAAQ,KAAK,OAAO,CAAC,UAAU,MAAM,SAAS,SAAS,EAAE;AAAA,MAC3E,CAAC;AACD,wBAAkB,IAAI;AAAA,IACxB;AAAA,IACA,CAAC,WAAW,iBAAiB;AAAA,EAC/B;AACA,QAAM,kBAAkB,sBAAsB,UAAU,CAAC;AACzD,QAAM,0BAA0B,gBAAgB,UAAU,SAAS;AACnE,QAAM,wBAAwB,4BAA4B;AAE1D,QAAM,gBAAgB,MAAM;AAAA,IAC1B,CAAC,MAAc,OAAe;AAC5B,UAAI,SAAS,GAAI;AACjB,kBAAY,MAAM,EAAE;AAAA,IACtB;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAU;AAAA,MACT,GAAG;AAAA,MAEH;AAAA,uBACC,qBAAC,SAAI,WAAU,wCACb;AAAA,+BAAC,SAAI,WAAU,qCACb;AAAA,gCAAC,WAAM,WAAU,6CAA6C,YAAE,+CAA+C,UAAU,GAAE;AAAA,YAC3H;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,0BAA0B;AAAA,gBACjC,eAAe,CAAC,UAAU,2BAA2B,SAAS,EAAE;AAAA,gBAEhE;AAAA,sCAAC,iBAAc,MAAK,MAAK,WAAU,wBACjC,8BAAC,eAAY,aAAa,EAAE,iDAAiD,mBAAmB,GAAG,GACrG;AAAA,kBACA,oBAAC,iBACE,oBAAU,IAAI,CAAC,OACd,oBAAC,cAAyB,OAAO,GAAG,MACjC,aAAG,SAAS,GAAG,QADD,GAAG,IAEpB,CACD,GACH;AAAA;AAAA;AAAA,YACF;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,WAAU;AAAA,gBAEV;AAAA,sCAAC,QAAK,WAAU,eAAc;AAAA,kBAAE;AAAA,kBAAE,EAAE,oCAAoC,KAAK;AAAA;AAAA;AAAA,YAC/E;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS;AAAA,gBACT,UAAU,CAAC;AAAA,gBACX,WAAU;AAAA,gBAEV;AAAA,sCAAC,UAAO,WAAU,eAAc;AAAA,kBAAE;AAAA,kBAAE,EAAE,uCAAuC,QAAQ;AAAA;AAAA;AAAA,YACvF;AAAA,aACF;AAAA,UACC,0BAA0B,uBACzB,qBAAC,SAAI,WAAU,yCACb;AAAA,gCAAC,aAAU,OAAO,EAAE,qCAAqC,MAAM,GAC7D;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,gBAAe;AAAA,gBACf,OAAO,qBAAqB;AAAA,gBAC5B,UAAU,CAAC,UAAU,wBAAwB,qBAAqB,MAAM,MAAM,OAAO,KAAK;AAAA;AAAA,YAC5F,GACF;AAAA,YACA,oBAAC,aAAU,OAAO,EAAE,sCAAsC,OAAO,GAC/D;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO,qBAAqB;AAAA,gBAC5B,UAAU,CAAC,UAAU,oBAAoB,qBAAqB,MAAM,EAAE,OAAO,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,YACnG,GACF;AAAA,YACA,oBAAC,aAAU,OAAO,EAAE,qCAAqC,MAAM,GAC7D;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,qBAAqB,QAAQ;AAAA,gBACpC,eAAe,CAAC,UACd,oBAAoB,qBAAqB,MAAM;AAAA,kBAC7C,MAAM,SAAS;AAAA,gBACjB,CAAC;AAAA,gBAGH;AAAA,sCAAC,iBAAc,MAAK,MAClB,8BAAC,eAAY,aAAa,EAAE,8CAA8C,SAAS,GAAG,GACxF;AAAA,kBACA,oBAAC,iBACE,gCAAsB,IAAI,CAAC,WAC1B,oBAAC,cAA8B,OAAO,OAAO,OAC1C,YAAE,2CAA2C,OAAO,KAAK,IAAI,OAAO,KAAK,KAD3D,OAAO,KAExB,CACD,GACH;AAAA;AAAA;AAAA,YACF,GACF;AAAA,YACA,oBAAC,aAAU,OAAO,EAAE,4CAA4C,aAAa,GAC3E;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAO,qBAAqB,eAAe;AAAA,gBAC3C,UAAU,CAAC,UAAU,oBAAoB,qBAAqB,MAAM,EAAE,aAAa,MAAM,OAAO,MAAM,CAAC;AAAA;AAAA,YACzG,GACF;AAAA,aACF,IACE;AAAA,UACJ,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,UAAU,CAAC;AAAA,gBACX,SAAS;AAAA,gBACT,iBAAiB,CAAC,YAAY,kCAAkC,YAAY,IAAI;AAAA,gBAChF,OAAO,EAAE,wDAAwD,4BAA4B;AAAA,gBAC7F,oBAAmB;AAAA,gBACnB,kBAAiB;AAAA;AAAA,YACnB;AAAA,YACC,CAAC,0BACA,oBAAC,UAAK,WAAU,iCAAiC,YAAE,yDAAyD,wCAAwC,GAAE,IACpJ;AAAA,aACN;AAAA,WACF,IAEA,qBAAC,SAAI,WAAU,kGACb;AAAA,8BAAC,SAAK,YAAE,4CAA4C,+IAA+I,GAAE;AAAA,UACrM,oBAAC,SACC;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS;AAAA,cAET;AAAA,oCAAC,QAAK,WAAU,WAAU;AAAA,gBACzB,EAAE,iDAAiD,oBAAoB;AAAA;AAAA;AAAA,UAC1E,GACF;AAAA,WACF;AAAA,QAED,aAAa,SACZ,oBAAC,SAAI,WAAU,qCACb,8BAAC,SAAI,WAAU,wJACZ,uBAAa,SACV,EAAE,4CAA4C,oBAAe,IAC5D,aAAa,WAAW,EAAE,oDAAoD,8BAAyB,GAC9G,GACF;AAAA,QAED,oBAAoB,IAAI,CAAC,EAAE,YAAY,MAAM,MAAM;AAClD,gBAAM,mBAAmB,OAAO,WAAW,YAAY,aAAa,WAAW,WAAW,WAAW,WAAW;AAChH,gBAAM,eAAe,mBACjB,UAAU,KAAK,CAAC,OAAO,GAAG,SAAS,gBAAgB,GAAG,UAAU,CAAC,IACjE;AACJ,iBACA;AAAA,YAAC;AAAA;AAAA,cAEC,WAAU;AAAA,cACV,WAAS;AAAA,cACT,aAAa,MAAM;AAAE,0BAAU,UAAU;AAAA,cAAM;AAAA,cAC/C,YAAY,CAAC,UAAU;AAAE,sBAAM,eAAe;AAAA,cAAE;AAAA,cAChD,QAAQ,MAAM;AACZ,sBAAM,OAAO,UAAU;AACvB,oBAAI,QAAQ,KAAM;AAClB,0BAAU,UAAU;AACpB,8BAAc,MAAM,KAAK;AAAA,cAC3B;AAAA,cACA,WAAW,MAAM;AAAE,0BAAU,UAAU;AAAA,cAAK;AAAA,cAC5C,UAAU;AAAA,cACV,WAAW,CAAC,UAAU;AACpB,oBAAI,CAAC,MAAM,OAAQ;AACnB,oBAAI,MAAM,QAAQ,aAAa,MAAM,QAAQ,MAAM;AACjD,wBAAM,eAAe;AACrB,gCAAc,OAAO,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAC;AAAA,gBAC7C;AACA,oBAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,QAAQ;AACrD,wBAAM,eAAe;AACrB,gCAAc,OAAO,KAAK,IAAI,YAAY,SAAS,GAAG,QAAQ,CAAC,CAAC;AAAA,gBAClE;AAAA,cACF;AAAA,cAEA;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA,OAAO,SAAS,KAAK;AAAA,kBACrB,aAAa;AAAA,kBACb,UAAU,CAAC,SAAS,mBAAmB,OAAO,IAAI;AAAA,kBAClD,UAAU,MAAM,cAAc,KAAK;AAAA,kBACnC,wBAAwB;AAAA,kBACxB;AAAA,kBACA,gBAAgB;AAAA,kBAChB,iBAAiB;AAAA,kBACjB,iBAAiB;AAAA,kBACjB,eAAe;AAAA,kBACf,aAAa,cAAc,MAAM,YAAY,YAAY,KAAK,IAAI;AAAA,kBAClE,WAAW;AAAA;AAAA,cACb;AAAA;AAAA,YAvCK,WAAW,OAAO,OAAO,KAAK;AAAA,UAwCrC;AAAA,QACD,CAAC;AAAA,QACF,qBAAC,SACC;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS;AAAA,cAET;AAAA,oCAAC,QAAK,WAAU,WAAU;AAAA,gBAAE;AAAA,gBAAE;AAAA;AAAA;AAAA,UAChC;AAAA,UACC;AAAA,UACA,eAAe,YAAY,SAAS,KAAK,iBACxC,qBAAC,SAAI,WAAU,sCACZ;AAAA,cAAE,qDAAqD,yBAAyB;AAAA,YAAG;AAAA,YACnF,YAAY,IAAI,CAAC,KAAK,QACrB,qBAAC,UACC;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,WAAU;AAAA,kBACV,SAAS,MAAM,eAAe,GAAG;AAAA,kBAEhC;AAAA;AAAA,cACH;AAAA,cACC,MAAM,YAAY,SAAS,IAAI,OAAO;AAAA,iBAR9B,GASX,CACD;AAAA,aACH,IACE;AAAA,WACN;AAAA,QACC;AAAA;AAAA;AAAA,EACH;AAEJ;AAkBA,MAAM,sBAAsB,MAAM,KAAK,SAASC,qBAAoB;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,yBAAyB;AAAA,EACzB,YAAY,CAAC;AAAA,EACb;AAAA,EACA,kBAAkB,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA6B;AAC3B,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAA0B,UAAU;AACpE,QAAM,WAAW,MAAM,OAAwB,UAAU;AACzD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAS,EAAE;AACjE,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAS,EAAE;AACjE,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAS,KAAK;AACpE,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAwB,IAAI;AAChF,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAS,KAAK;AAClE,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,EAAE,MAAM,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;AACpF,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAwB,IAAI;AAClF,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAwB,IAAI;AACtE,QAAM,uBAAuB,MAAM;AAAA,IACjC,MAAO,OAAO,MAAM,YAAY,aAAa,WAAW,MAAM,WAAW,WAAW;AAAA,IACpF,CAAC,MAAM,YAAY,QAAQ;AAAA,EAC7B;AACA,QAAM,IAAI,MAAM,YAAY,CAAC,KAAa,aAAsB,YAAY,UAAU,KAAK,QAAQ,IAAI,UAAW,CAAC,SAAS,CAAC;AAC7H,QAAM,UAAU,MAAM;AACpB,aAAS,UAAU;AACnB,aAAS,UAAU;AAAA,EACrB,GAAG,CAAC,WAAW,GAAG,CAAC;AACnB,QAAM,UAAU,MAAM;AACpB,wBAAoB,EAAE;AACtB,wBAAoB,EAAE;AACtB,uBAAmB,KAAK;AACxB,kBAAc,EAAE,MAAM,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;AAC/C,wBAAoB,IAAI;AACxB,kBAAc,IAAI;AAAA,EACpB,GAAG,CAAC,WAAW,GAAG,CAAC;AACnB,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,sBAAsB;AACzB,yBAAmB,KAAK;AACxB,oBAAc,EAAE,MAAM,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;AAC/C,0BAAoB,IAAI;AACxB,oBAAc,IAAI;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,oBAAoB,CAAC;AACzB,QAAM,eAAe,MAAM,QAAQ,MAAM,oBAAoB,MAAM,YAAY,KAAK,GAAG,CAAC,KAAK,CAAC;AAC9F,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,UAAM,OAAO,MAAM,QAAQ,eAAe,IAAI,CAAC,GAAG,eAAe,IAAI,CAAC;AACtE,QAAI,gBAAgB,CAAC,KAAK,KAAK,CAAC,UAAU,MAAM,SAAS,aAAa,IAAI,GAAG;AAC3E,WAAK,KAAK,YAAY;AAAA,IACxB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,iBAAiB,YAAY,CAAC;AAClC,QAAM,kBAAkB,MAAM;AAAA,IAC5B,MAAM,4BAA4B,MAAM,YAAY,OAAO;AAAA,IAC3D,CAAC,MAAM,YAAY,OAAO;AAAA,EAC5B;AAEA,QAAM,WAAW,CAAC,QAA0C;AAC1D,QAAI,CAAC,IAAI,cAAc,CAAC,MAAM,QAAQ,IAAI,WAAW,OAAO,EAAG,QAAO;AACtE,UAAM,oBAAoB,4BAA4B,IAAI,WAAW,OAAO;AAC5E,WAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY;AAAA,QACV,GAAG,IAAI;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,YAAY,CAAC,SAA0B;AAChE,aAAS,UAAU;AACnB,aAAS,IAAI;AACb,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,CAAC,OAA4F,eAAe,UAAU;AAClI,UAAM,UAAU,SAAS;AACzB,UAAM,gBAAgB,OAAO,UAAU,aAAa,MAAM,OAAO,IAAI;AACrE,UAAM,OAAO,EAAE,GAAG,SAAS,GAAG,cAAc;AAC5C,UAAM,eAAe,eAAe,SAAS,IAAI,IAAI;AACrD,iBAAa,YAAY;AACzB,QAAI,cAAc;AAChB,eAAS,YAAY;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,SAAS,MAAM;AACnB,UAAM,YAAY,SAAS,SAAS,OAAO;AAC3C,iBAAa,SAAS;AACtB,aAAS,SAAS;AAAA,EACpB;AAEA,QAAM,uBAAuB,CAAC,UAAkB;AAC9C,UAAM,aAAa,EAAE,GAAI,SAAS,QAAQ,cAAc,CAAC,EAAG;AAC5D,QAAI,MAAO,YAAW,WAAW;AAAA,QAC5B,QAAO,WAAW;AACvB,WAAO,WAAW;AAClB,UAAM,OAAO,EAAE,GAAG,SAAS,SAAS,YAAY,WAAW;AAC3D,iBAAa,IAAI;AACjB,aAAS,IAAI;AAAA,EACf;AAEA,QAAM,oBAAoB,CAAC,UAAkB;AAC3C,QAAI,CAAC,qBAAsB;AAC3B,QAAI,CAAC,OAAO;AACV,YAAMC,cAAa,EAAE,GAAI,MAAM,cAAc,CAAC,EAAG;AACjD,aAAOA,YAAW;AAClB,YAAM,EAAE,YAAYA,YAAW,GAAG,IAAI;AACtC;AAAA,IACF;AACA,UAAM,QAAQ,aAAa,KAAK,CAAC,UAAU,MAAM,SAAS,KAAK;AAC/D,UAAM,YAAY,SAAS,EAAE,MAAM,MAAM;AACzC,UAAM,aAAa,EAAE,GAAI,MAAM,cAAc,CAAC,EAAG;AACjD,eAAW,QAAQ;AACnB,UAAM,EAAE,YAAY,WAAW,GAAG,IAAI;AACtC,sBAAkB,sBAAsB,SAAS;AAAA,EACnD;AAEA,QAAM,wBAAwB,CAAC,UAA0B;AACvD,QAAI,CAAC,qBAAsB;AAC3B,QAAI,OAAO;AACT,oBAAc;AAAA,QACZ,MAAM,MAAM;AAAA,QACZ,OAAO,MAAM,SAAS;AAAA,QACtB,MAAM,MAAM,QAAQ;AAAA,MACtB,CAAC;AACD,0BAAoB,MAAM,IAAI;AAAA,IAChC,OAAO;AACL,oBAAc,EAAE,MAAM,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;AAC/C,0BAAoB,IAAI;AAAA,IAC1B;AACA,kBAAc,IAAI;AAClB,uBAAmB,IAAI;AAAA,EACzB;AAEA,QAAM,0BAA0B,MAAM;AACpC,QAAI,CAAC,qBAAsB;AAC3B,UAAM,OAAO,oBAAoB,WAAW,QAAQ,EAAE;AACtD,QAAI,CAAC,MAAM;AACT,oBAAc,EAAE,kDAAkD,yBAAyB,CAAC;AAC5F;AAAA,IACF;AACA,UAAM,QAAuB;AAAA,MAC3B;AAAA,MACA,OAAO,WAAW,MAAM,KAAK,KAAK;AAAA,MAClC,MAAM,WAAW,KAAK,KAAK,KAAK;AAAA,IAClC;AACA,sBAAkB,sBAAsB,KAAK;AAC7C,UAAM,sBAAsB,CAAC,oBAAoB,cAAc,SAAS;AACxE,QAAI,qBAAqB;AACvB,YAAM,aAAa,EAAE,GAAI,MAAM,cAAc,CAAC,EAAG;AACjD,iBAAW,QAAQ;AACnB,YAAM,EAAE,YAAY,WAAW,GAAG,IAAI;AAAA,IACxC;AACA,kBAAc,EAAE,MAAM,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;AAC/C,wBAAoB,IAAI;AACxB,uBAAmB,KAAK;AAAA,EAC1B;AAEA,QAAM,yBAAyB,CAAC,SAAiB;AAC/C,QAAI,CAAC,qBAAsB;AAC3B,oBAAgB,sBAAsB,IAAI;AAC1C,QAAI,cAAc,SAAS,MAAM;AAC/B,wBAAkB,EAAE;AAAA,IACtB;AACA,QAAI,qBAAqB,MAAM;AAC7B,oBAAc,EAAE,MAAM,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;AAC/C,0BAAoB,IAAI;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,uBAAuB,CAAC,UAAyB;AACrD,0BAAsB,KAAK;AAAA,EAC7B;AAEA,QAAM,oBAAoB,MAAM;AAC9B,wBAAoB,EAAE;AACtB,wBAAoB,EAAE;AACtB,uBAAmB,IAAI;AAAA,EACzB;AAEA,QAAM,yBAAyB,MAAM;AACnC,sBAAkB;AAClB,wBAAoB,IAAI;AAAA,EAC1B;AAEA,QAAM,0BAA0B,MAAM;AACpC,sBAAkB;AAClB,wBAAoB,KAAK;AAAA,EAC3B;AAEA,QAAM,kBAAkB,MAAM;AAC5B,UAAM,QAAQ,iBAAiB,KAAK;AACpC,UAAM,QAAQ,iBAAiB,KAAK;AACpC,QAAI,CAAC,OAAO;AACV,yBAAmB,EAAE,8CAA8C,mBAAmB,CAAC;AACvF;AAAA,IACF;AACA,uBAAmB,IAAI;AACvB,UAAM,cAAc,MAAM,QAAQ,MAAM,YAAY,OAAO,IAAI,CAAC,GAAG,MAAM,WAAY,OAAO,IAAI,CAAC;AACjG,gBAAY,KAAK,EAAE,OAAO,OAAO,SAAS,MAAM,CAAC;AACjD,UAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,SAAS,YAAY,EAAE,GAAG,IAAI;AACjF,4BAAwB;AAAA,EAC1B;AAEA,QAAM,qBAAqB,CAAC,UAAkB;AAC5C,UAAM,cAAc,MAAM,QAAQ,MAAM,YAAY,OAAO,IAAI,CAAC,GAAG,MAAM,WAAY,OAAO,IAAI,CAAC;AACjG,gBAAY,OAAO,OAAO,CAAC;AAC3B,UAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,SAAS,YAAY,EAAE,GAAG,IAAI;AAAA,EACnF;AAEA,SACE,iCACA;AAAA,yBAAC,SAAI,WAAU,iFACb;AAAA,2BAAC,SAAI,WAAU,qCACb;AAAA,6BAAC,SAAI,WAAU,yDACb;AAAA,8BAAC,UAAK,WAAU,6GACd,8BAAC,gBAAa,WAAU,sBAAqB,GAC/C;AAAA,UACC,EAAE,8CAA8C,iBAAiB;AAAA,WACpE;AAAA,QACA,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,aAAa;AAAA,cAC5B,iBAAiB,CAAC,YAAY;AAAE,sBAAM,EAAE,UAAU,YAAY,KAAK,GAAG,IAAI;AAAA,cAAE;AAAA,cAC5E,OAAO,EAAE,uCAAuC,QAAQ;AAAA,cACxD,oBAAmB;AAAA,cACnB,kBAAiB;AAAA;AAAA,UACnB;AAAA,UACC,eACC,oBAAC,cAAW,SAAQ,WAAU,MAAK,MAAK,SAAS,aAAa,cAAY,EAAE,+CAA+C,iBAAiB,GAC1I,8BAAC,aAAU,WAAU,WAAU,GACjC;AAAA,UAEF,oBAAC,cAAW,SAAQ,WAAU,MAAK,MAAK,SAAS,UAAU,cAAY,EAAE,4CAA4C,cAAc,GACjI,8BAAC,UAAO,WAAU,WAAU,GAC9B;AAAA,WACF;AAAA,SACF;AAAA,MAEA,qBAAC,SAAI,WAAU,4DACb;AAAA,4BAAC,aAAU,OAAO,EAAE,oCAAoC,KAAK,GAAG,OAAO,OAAO,KAAK,WAAU,iBAC3F;AAAA,UAAC;AAAA;AAAA,YACC,gBAAe;AAAA,YACf,aAAY;AAAA,YACZ,OAAO,MAAM;AAAA,YACb,UAAU,CAAC,UAAU,MAAM,EAAE,KAAK,MAAM,OAAO,MAAM,CAAC;AAAA,YACtD,QAAQ;AAAA;AAAA,QACV,GACF;AAAA,QACA,oBAAC,aAAU,OAAO,EAAE,qCAAqC,MAAM,GAAG,OAAO,OAAO,MAAM,WAAU,iBAC9F;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,MAAM,QAAQ;AAAA,YACrB,eAAe,CAAC,UAAU;AAAE,oBAAM,EAAE,MAAM,SAAS,GAAG,GAAG,IAAI;AAAA,YAAE;AAAA,YAE/D;AAAA,kCAAC,iBAAc,gBAAc,CAAC,CAAC,OAAO,MACpC,8BAAC,eAAY,GACf;AAAA,cACA,oBAAC,iBACE,sBAAY,IAAI,CAAC,WAChB,oBAAC,cAA8B,OAAO,OAAO,OAC1C,iBAAO,SADO,OAAO,KAExB,CACD,GACH;AAAA;AAAA;AAAA,QACF,GACF;AAAA,SACF;AAAA,MAEC,yBACC,qBAAC,SAAI,WAAU,8CACb;AAAA,6BAAC,SACC;AAAA,8BAAC,WAAM,WAAU,WAAW,YAAE,iDAAiD,oBAAoB,GAAE;AAAA,UACrG;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,wBAAwB;AAAA,cAC/B,eAAe,CAAC,UAAU,qBAAqB,SAAS,EAAE;AAAA,cAE1D;AAAA,oCAAC,iBACC,8BAAC,eAAY,aAAa,EAAE,2CAA2C,YAAY,GAAG,GACxF;AAAA,gBACA,oBAAC,iBACG,wBAAa,CAAC,GAAG,IAAI,CAAC,OACtB,oBAAC,cAAyB,OAAO,GAAG,MACjC,aAAG,SAAS,GAAG,QADD,GAAG,IAEpB,CACD,GACH;AAAA;AAAA;AAAA,UACF;AAAA,WACF;AAAA,QACC,uBACC,qBAAC,SACC;AAAA,8BAAC,SAAI,WAAU,qCACb,8BAAC,WAAM,WAAU,WAAW,YAAE,sCAAsC,OAAO,GAAE,GAC/E;AAAA,UACA,qBAAC,SAAI,WAAU,gCACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,cAAc,QAAQ;AAAA,gBAC7B,eAAe,CAAC,UAAU,kBAAkB,SAAS,EAAE;AAAA,gBAEvD;AAAA,sCAAC,iBAAc,WAAU,UACvB,8BAAC,eAAY,aAAa,EAAE,wCAAwC,UAAU,GAAG,GACnF;AAAA,kBACA,oBAAC,iBACE,uBAAa,IAAI,CAAC,UACjB,oBAAC,cAA4B,OAAO,MAAM,MACvC,gBAAM,SAAS,MAAM,QADP,MAAM,IAEvB,CACD,GACH;AAAA;AAAA;AAAA,YACF;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,WAAU;AAAA,gBACV,SAAS,MAAM,sBAAsB;AAAA,gBACrC,cAAY,EAAE,4CAA4C,cAAc;AAAA,gBAExE,8BAAC,QAAK,WAAU,WAAU;AAAA;AAAA,YAC5B;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,WAAU;AAAA,gBACV,SAAS,MAAM,sBAAsB;AAAA,gBACrC,cAAY,EAAE,2CAA2C,aAAa;AAAA,gBAEtE,8BAAC,OAAI,WAAU,WAAU;AAAA;AAAA,YAC3B;AAAA,aACF;AAAA,WACF,IACE;AAAA,SACN,IACE;AAAA,MAEJ,qBAAC,SAAI,WAAU,8CACb;AAAA,4BAAC,aAAU,OAAO,EAAE,sCAAsC,OAAO,GAC/D;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,OAAO,MAAM,YAAY,UAAU,WAAW,MAAM,WAAW,QAAQ;AAAA,YAC9E,UAAU,CAAC,UAAU,MAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,OAAO,MAAM,OAAO,MAAM,EAAE,CAAC;AAAA,YACrG,QAAQ;AAAA;AAAA,QACV,GACF;AAAA,QACA,oBAAC,aAAU,OAAO,EAAE,4CAA4C,aAAa,GAC3E;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,OAAO,MAAM,YAAY,gBAAgB,WAAW,MAAM,WAAW,cAAc;AAAA,YAC1F,UAAU,CAAC,UAAU,MAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,aAAa,MAAM,OAAO,MAAM,EAAE,CAAC;AAAA,YAC3G,QAAQ;AAAA;AAAA,QACV,GACF;AAAA,SAEE,MAAM,SAAS,UAAU,MAAM,SAAS,gBACxC,iCACE;AAAA,+BAAC,SACC;AAAA,gCAAC,WAAM,WAAU,WAAW,YAAE,uCAAuC,QAAQ,GAAE;AAAA,YAC/E;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,OAAO,MAAM,YAAY,WAAW,YAAY,MAAM,WAAW,SAAS,MAAM,WAAW,SAAS;AAAA,gBAC3G,eAAe,CAAC,UAAU;AAAE,wBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,QAAQ,SAAS,OAAU,EAAE,GAAG,IAAI;AAAA,gBAAE;AAAA,gBAErH;AAAA,sCAAC,iBACC,8BAAC,eAAY,aAAa,EAAE,8CAA8C,SAAS,GAAG,GACxF;AAAA,kBACA,qBAAC,iBACC;AAAA,wCAAC,cAAW,OAAM,YAAY,YAAE,+CAA+C,gBAAgB,GAAE;AAAA,oBACjG,oBAAC,cAAW,OAAM,kBAAkB,YAAE,qDAAqD,iBAAiB,GAAE;AAAA,oBAC9G,oBAAC,cAAW,OAAM,gBAAgB,YAAE,mDAAmD,gBAAgB,GAAE;AAAA,qBAC3G;AAAA;AAAA;AAAA,YACF;AAAA,aACF;AAAA,UACC,MAAM,SAAS,UACd,iCACE;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,CAAC,CAAC,MAAM,YAAY;AAAA,gBAC7B,iBAAiB,CAAC,YAAY;AAAE,wBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,OAAO,YAAY,KAAK,EAAE,GAAG,IAAI;AAAA,gBAAE;AAAA,gBACtH,OAAO,EAAE,yCAAyC,UAAU;AAAA,gBAC5D,oBAAmB;AAAA,gBACnB,kBAAiB;AAAA;AAAA,YACnB;AAAA,YACC,CAAC,CAAC,MAAM,YAAY,SACnB,qBAAC,SAAI,WAAU,iBACb;AAAA,kCAAC,WAAM,WAAU,WAAW,YAAE,sDAAsD,0BAA0B,GAAE;AAAA,cAChH;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,MAAM,YAAY,UAAU,YAAY,YAAY;AAAA,kBAC3D,eAAe,CAAC,UAAU;AACxB,0BAAM,aAAa,EAAE,GAAI,MAAM,cAAc,CAAC,EAAG;AACjD,wBAAI,UAAU,UAAW,YAAW,QAAQ;AAAA,wBACvC,QAAO,WAAW;AACvB,0BAAM,EAAE,YAAY,WAAW,GAAG,IAAI;AAAA,kBACxC;AAAA,kBAEA;AAAA,wCAAC,iBACC,8BAAC,eAAY,GACf;AAAA,oBACA,qBAAC,iBACC;AAAA,0CAAC,cAAW,OAAM,WAAW,YAAE,8CAA8C,SAAS,GAAE;AAAA,sBACxF,oBAAC,cAAW,OAAM,WAAW,YAAE,kDAAkD,sBAAsB,GAAE;AAAA,uBAC3G;AAAA;AAAA;AAAA,cACF;AAAA,eACF;AAAA,aAEJ;AAAA,WAEJ;AAAA,QAGD,MAAM,SAAS,YACd,qBAAC,SAAI,WAAU,2BACb;AAAA,8BAAC,WAAM,WAAU,WAAW,YAAE,wCAAwC,SAAS,GAAE;AAAA,UACjF,oBAAC,SAAI,WAAU,aACZ,0BAAgB,SAAS,IACxB,gBAAgB,IAAI,CAAC,QAAQ,QAC3B;AAAA,YAAC;AAAA;AAAA,cAEC,WAAU;AAAA,cAEV;AAAA,qCAAC,SACC;AAAA,sCAAC,SAAI,WAAU,+BAA+B,iBAAO,OAAM;AAAA,kBAC3D,oBAAC,SAAI,WAAU,iDAAiD,iBAAO,OAAM;AAAA,mBAC/E;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,WAAU;AAAA,oBACV,SAAS,MAAM,mBAAmB,GAAG;AAAA,oBACrC,cAAY,EAAE,6CAA6C,eAAe;AAAA,oBAE1E,8BAAC,UAAO,WAAU,eAAc;AAAA;AAAA,gBAClC;AAAA;AAAA;AAAA,YAfK,GAAG,OAAO,KAAK,IAAI,GAAG;AAAA,UAgB7B,CACD,IAED,oBAAC,UAAK,WAAU,iCAAiC,YAAE,iDAAiD,qBAAqB,GAAE,GAE/H;AAAA,UACA,oBAAC,SAAI,WAAU,oBACb;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS;AAAA,cAET;AAAA,oCAAC,QAAK,WAAU,eAAc;AAAA,gBAC7B,EAAE,0CAA0C,YAAY;AAAA;AAAA;AAAA,UAC3D,GACF;AAAA,WACF;AAAA,SAGA,MAAM,SAAS,YAAY,MAAM,SAAS,eAC1C,iCACE;AAAA,8BAAC,aAAU,OAAO,EAAE,2CAA2C,aAAa,GAC1E;AAAA,YAAC;AAAA;AAAA,cACC,aAAY;AAAA,cACZ,OAAO,OAAO,MAAM,YAAY,eAAe,WAAW,MAAM,WAAW,aAAa;AAAA,cACxF,UAAU,CAAC,UAAU,MAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,YAAY,MAAM,OAAO,MAAM,EAAE,CAAC;AAAA,cAC1G,QAAQ;AAAA;AAAA,UACV,GACF;AAAA,UACC,MAAM,SAAS,cACd,oBAAC,aAAU,OAAO,EAAE,gDAAgD,mBAAmB,GACrF;AAAA,YAAC;AAAA;AAAA,cACC,gBAAe;AAAA,cACf,aAAY;AAAA,cACZ,OAAO,OAAO,MAAM,YAAY,oBAAoB,WAAW,MAAM,WAAW,kBAAkB;AAAA,cAClG,UAAU,CAAC,UAAU;AACnB,sBAAM,kBAAkB,MAAM,OAAO;AACrC,sBAAM,gBAAgB,kBAClB,4CAA4C,mBAAmB,eAAe,CAAC,KAC/E;AACJ,sBAAM;AAAA,kBACJ,YAAY;AAAA,oBACV,GAAI,MAAM,cAAc,CAAC;AAAA,oBACzB;AAAA,oBACA,YAAY,MAAM,YAAY,cAAc;AAAA,kBAC9C;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,cACA,QAAQ;AAAA;AAAA,UACV,GACF;AAAA,WAEJ;AAAA,QAGD,MAAM,SAAS,cACd,qBAAC,SAAI,WAAU,iBACb;AAAA,8BAAC,WAAM,WAAU,WAAW,YAAE,8CAA8C,gBAAgB,GAAE;AAAA,UAC9F,oBAAC,SAAI,WAAU,mEAAkE,qCAEjF;AAAA,WACF;AAAA,SAGA,MAAM,SAAS,aAAa,MAAM,SAAS,YAC3C,oBAAC,aAAU,OAAO,EAAE,8CAA8C,kBAAkB,GAAG,WAAU,iBAC/F;AAAA,UAAC;AAAA;AAAA,YACC,aAAa,EAAE,iDAAiD,cAAc;AAAA,YAC9E,OAAO,OAAO,MAAM,YAAY,SAAS,WAAW,MAAM,WAAW,OAAO;AAAA,YAC5E,UAAU,CAAC,UAAU,MAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,MAAM,MAAM,OAAO,MAAM,EAAE,CAAC;AAAA,YACpG,QAAQ;AAAA;AAAA,QACV,GACF;AAAA,SAEJ;AAAA,MAEA,qBAAC,SAAI,WAAU,sBACb;AAAA,6BAAC,SAAI,WAAU,0CACb;AAAA,8BAAC,WAAM,WAAU,uBAAuB,YAAE,gDAAgD,kBAAkB,GAAE;AAAA,UAC9G;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM;AACb,sBAAM,CAAC,YAAY;AACjB,wBAAM,OAAO,MAAM,QAAQ,QAAQ,YAAY,UAAU,IAAI,CAAC,GAAG,QAAQ,WAAW,UAAU,IAAI,CAAC;AACnG,uBAAK,KAAK,EAAE,MAAM,YAAY,SAAS,EAAE,oDAAoD,wBAAwB,EAAE,CAAQ;AAC/H,yBAAO,EAAE,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,GAAI,YAAY,KAAK,EAAE;AAAA,gBAC3E,GAAG,IAAI;AAAA,cACT;AAAA,cAEA;AAAA,oCAAC,QAAK,WAAU,eAAc;AAAA,gBAC7B,EAAE,wCAAwC,UAAU;AAAA;AAAA;AAAA,UACvD;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,aACX;AAAA,iBAAM,QAAQ,MAAM,YAAY,UAAU,IAAI,MAAM,WAAY,aAAa,CAAC,GAAG,IAAI,CAAC,MAAW,UACjG,qBAAC,SAAgB,WAAU,uDACzB;AAAA,gCAAC,SAAI,WAAU,iBACb;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,MAAM,QAAQ;AAAA,gBACrB,eAAe,CAAC,UAAU;AACxB,wBAAM,WAAW;AACjB,wBAAM,CAAC,YAAY;AACjB,0BAAM,OAAO,MAAM,QAAQ,QAAQ,YAAY,UAAU,IAAI,CAAC,GAAG,QAAQ,WAAW,UAAU,IAAI,CAAC;AACnG,0BAAM,WAAY,KAAK,KAAK,KAAa,CAAC;AAC1C,yBAAK,KAAK,IAAI,EAAE,GAAG,UAAU,MAAM,UAAU,SAAS,SAAS,WAAW,MAAM,WAAW,GAAG;AAC9F,2BAAO,EAAE,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,GAAI,YAAY,KAAK,EAAE;AAAA,kBAC3E,GAAG,IAAI;AAAA,gBACT;AAAA,gBAEA;AAAA,sCAAC,iBACC,8BAAC,eAAY,GACf;AAAA,kBACA,qBAAC,iBACC;AAAA,wCAAC,cAAW,OAAM,YAAW,sBAAQ;AAAA,oBACrC,oBAAC,cAAW,OAAM,QAAO,kBAAI;AAAA,oBAC7B,oBAAC,cAAW,OAAM,WAAU,qBAAO;AAAA,oBACnC,oBAAC,cAAW,OAAM,SAAQ,mBAAK;AAAA,oBAC/B,oBAAC,cAAW,OAAM,MAAK,gBAAE;AAAA,oBACzB,oBAAC,cAAW,OAAM,OAAM,iBAAG;AAAA,oBAC3B,oBAAC,cAAW,OAAM,MAAK,gBAAE;AAAA,oBACzB,oBAAC,cAAW,OAAM,OAAM,iBAAG;AAAA,oBAC3B,oBAAC,cAAW,OAAM,MAAK,gBAAE;AAAA,oBACzB,oBAAC,cAAW,OAAM,MAAK,gBAAE;AAAA,oBACzB,oBAAC,cAAW,OAAM,SAAQ,mBAAK;AAAA,qBACjC;AAAA;AAAA;AAAA,YACF,GACF;AAAA,YACA,oBAAC,SAAI,WAAU,iBACb;AAAA,cAAC;AAAA;AAAA,gBACC,aAAa,MAAM,SAAS,UAAU,EAAE,uDAAuD,yBAAyB,IAAK,CAAC,MAAK,OAAM,MAAK,KAAK,EAAE,SAAS,MAAM,IAAI,IAAI,EAAE,sDAAsD,QAAQ,IAAI;AAAA,gBAChP,OAAO,MAAM,SAAS;AAAA,gBACtB,UAAU,CAAC,UAAU;AACnB,wBAAM,QAAQ,CAAC,MAAK,OAAM,MAAK,KAAK,EAAE,SAAS,MAAM,IAAI,IAAI,OAAO,MAAM,OAAO,KAAK,IAAI,MAAM,OAAO;AACvG,wBAAM,CAAC,YAAY;AACjB,0BAAM,OAAO,MAAM,QAAQ,QAAQ,YAAY,UAAU,IAAI,CAAC,GAAG,QAAQ,WAAW,UAAU,IAAI,CAAC;AACnG,0BAAM,WAAY,KAAK,KAAK,KAAa,CAAC;AAC1C,yBAAK,KAAK,IAAI,EAAE,GAAG,UAAU,GAAG,MAAM,OAAO,MAAM;AACnD,2BAAO,EAAE,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,GAAI,YAAY,KAAK,EAAE;AAAA,kBAC3E,CAAC;AAAA,gBACH;AAAA,gBACA,QAAQ;AAAA,gBACR,UAAU,MAAM,SAAS,cAAc,MAAM,SAAS,UAAU,MAAM,SAAS,aAAa,MAAM,SAAS;AAAA;AAAA,YAC7G,GACF;AAAA,YACA,oBAAC,SAAI,WAAU,iBACb;AAAA,cAAC;AAAA;AAAA,gBACC,aAAa,EAAE,4DAA4D,eAAe;AAAA,gBAC1F,OAAO,MAAM,WAAW;AAAA,gBACxB,UAAU,CAAC,UAAU;AACnB,wBAAM,UAAU,MAAM,OAAO;AAC7B,wBAAM,CAAC,YAAY;AACjB,0BAAM,OAAO,MAAM,QAAQ,QAAQ,YAAY,UAAU,IAAI,CAAC,GAAG,QAAQ,WAAW,UAAU,IAAI,CAAC;AACnG,0BAAM,WAAY,KAAK,KAAK,KAAa,CAAC;AAC1C,yBAAK,KAAK,IAAI,EAAE,GAAG,UAAU,GAAG,MAAM,QAAQ;AAC9C,2BAAO,EAAE,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,GAAI,YAAY,KAAK,EAAE;AAAA,kBAC3E,CAAC;AAAA,gBACH;AAAA,gBACA,QAAQ;AAAA;AAAA,YACV,GACF;AAAA,YACA,oBAAC,SAAI,WAAU,kCACb;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,cAAY,EAAE,2CAA2C,aAAa;AAAA,gBACtE,SAAS,MAAM;AACb,wBAAM,CAAC,YAAY;AACjB,0BAAM,OAAO,MAAM,QAAQ,QAAQ,YAAY,UAAU,IAAI,CAAC,GAAG,QAAQ,WAAW,UAAU,IAAI,CAAC;AACnG,yBAAK,OAAO,OAAO,CAAC;AACpB,2BAAO,EAAE,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,GAAI,YAAY,KAAK,EAAE;AAAA,kBAC3E,GAAG,IAAI;AAAA,gBACT;AAAA,gBAEA,8BAAC,UAAO,WAAU,WAAU;AAAA;AAAA,YAC9B,GACF;AAAA,eAhFQ,KAiFV,CACD;AAAA,WACC,CAAC,MAAM,QAAQ,MAAM,YAAY,UAAU,KAAK,MAAM,WAAY,WAAW,WAAW,MACxF,oBAAC,SAAI,WAAU,iCAAiC,YAAE,kDAAkD,8BAA8B,GAAE;AAAA,WAExI;AAAA,SACF;AAAA,MAEA,oBAAC,SAAI,WAAU,QACX,iBAAM;AACN,cAAM,SAAS,cAAc,aAAa,MAAM,IAAI;AACpD,YAAI,CAAC,OAAQ,QAAO;AACpB,eACE;AAAA,UAAC;AAAA;AAAA,YACC,KAAK,EAAE,KAAK,MAAM,KAAK,MAAM,MAAM,MAAM,YAAY,MAAM,WAAW;AAAA,YACtE,UAAU,CAAC,UAAU,MAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,GAAI,SAAS,CAAC,EAAG,EAAE,GAAG,IAAI;AAAA;AAAA,QACpG;AAAA,MAEJ,GAAG,GACL;AAAA,OAGE,MAAM;AAEN,YAAI,MAAM,SAAS,aAAc,QAAO;AAExC,YAAI,MAAM,SAAS,cAAc,MAAM,SAAS,aAAc,QAAO;AACrE,cAAM,iBAAiB,MAAM,YAAY;AACzC,YAAI,MAAM,SAAS,WAAW;AAC5B,gBAAM,cAAc,mBAAmB,OAAO,SAAS,mBAAmB,QAAQ,UAAU;AAC5F,iBACE,oBAAC,aAAU,OAAO,EAAE,6CAA6C,eAAe,GAAG,WAAU,QAC3F;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,eAAe;AAAA,cACtB,eAAe,CAAC,QAAQ;AACtB,sBAAM,QAAQ,QAAQ,SAAS,OAAO,QAAQ,UAAU,QAAQ;AAChE,sBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,cAAc,MAAM,EAAE,GAAG,IAAI;AAAA,cAClF;AAAA,cAEA;AAAA,oCAAC,iBACC,8BAAC,eAAY,GACf;AAAA,gBACA,qBAAC,iBACC;AAAA,sCAAC,cAAW,OAAO,oBAAqB,YAAE,iDAAiD,YAAY,GAAE;AAAA,kBACzG,oBAAC,cAAW,OAAM,QAAQ,YAAE,iDAAiD,gBAAgB,GAAE;AAAA,kBAC/F,oBAAC,cAAW,OAAM,SAAS,YAAE,kDAAkD,mBAAmB,GAAE;AAAA,mBACtG;AAAA;AAAA;AAAA,UACF,GACF;AAAA,QAEJ;AAEA,YAAI,MAAM,SAAS,YAAY,CAAC,MAAM,YAAY,OAAO;AACvD,gBAAM,OAAO,4BAA4B,MAAM,YAAY,WAAW,CAAC,CAAC;AACxE,cAAI,KAAK,SAAS,GAAG;AACnB,kBAAM,YAAY,+BAA+B,IAAI;AACrD,mBACE,oBAAC,aAAU,OAAO,EAAE,6CAA6C,eAAe,GAAG,WAAU,QAC3F;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,OAAO,mBAAmB,YAAY,OAAO,mBAAmB,WAAW,OAAO,cAAc,IAAI;AAAA,gBAC3G,eAAe,CAAC,QAAQ;AACtB,sBAAI,QAAQ,WAAW;AACrB,0BAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,cAAc,OAAU,EAAE,GAAG,IAAI;AACpF;AAAA,kBACF;AAEA,wBAAM,UAAU,KAAK,KAAK,CAAC,MAAM,OAAO,EAAE,KAAK,MAAM,GAAG;AACxD,wBAAM,QAAQ,UAAU,QAAQ,QAAQ;AACxC,wBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,cAAc,MAAM,EAAE,GAAG,IAAI;AAAA,gBAClF;AAAA,gBAEA;AAAA,sCAAC,iBACC,8BAAC,eAAY,aAAa,EAAE,iDAAiD,YAAY,GAAG,GAC9F;AAAA,kBACA,qBAAC,iBACC;AAAA,wCAAC,cAAW,OAAO,WAAY,YAAE,iDAAiD,YAAY,GAAE;AAAA,oBAC/F,KAAK,IAAI,CAAC,WACT,oBAAC,cAAsC,OAAO,OAAO,OAAO,KAAK,GAC9D,iBAAO,SADO,OAAO,OAAO,KAAK,CAEpC,CACD;AAAA,qBACH;AAAA;AAAA;AAAA,YACF,GACF;AAAA,UAEJ;AAAA,QACF;AAEA,YAAI,MAAM,SAAS,aAAa,MAAM,SAAS,SAAS;AACtD,iBACE,oBAAC,aAAU,OAAO,EAAE,6CAA6C,eAAe,GAAG,WAAU,QAC3F;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAM,MAAM,SAAS,YAAY,MAAM;AAAA,cACvC,OAAO,OAAO,mBAAmB,WAAW,OAAO,cAAc,IAAI;AAAA,cACrE,UAAU,CAAC,UAAU;AACnB,sBAAM,MAAM,MAAM,OAAO;AACzB,sBAAM,SAAS,QAAQ,KAAK,SAAa,MAAM,SAAS,YAAY,SAAS,KAAK,EAAE,IAAI,WAAW,GAAG;AACtG,sBAAM,QAAQ,WAAW,UAAa,CAAC,MAAM,MAAM,IAAI,SAAS;AAChE,sBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,cAAc,MAAM,EAAE,CAAC;AAAA,cAC5E;AAAA,cACA,QAAQ;AAAA,cACR,aAAa,EAAE,wDAAwD,YAAY;AAAA;AAAA,UACrF,GACF;AAAA,QAEJ;AAEA,YAAI,CAAC,QAAQ,aAAa,QAAQ,YAAY,UAAU,EAAE,SAAS,MAAM,IAAI,GAAG;AAC9E,iBACE,oBAAC,aAAU,OAAO,EAAE,6CAA6C,eAAe,GAAG,WAAU,QAC3F;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,OAAO,mBAAmB,WAAW,iBAAiB;AAAA,cAC7D,UAAU,CAAC,UAAU;AACnB,sBAAM,QAAQ,MAAM,OAAO;AAC3B,sBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,cAAc,SAAS,OAAU,EAAE,CAAC;AAAA,cACzF;AAAA,cACA,QAAQ;AAAA,cACR,aAAa,EAAE,wDAAwD,YAAY;AAAA;AAAA,UACrF,GACF;AAAA,QAEJ;AACA,eAAO;AAAA,MACT,GAAG;AAAA,MAEH,qBAAC,SAAI,WAAU,wDACb;AAAA,4BAAC,UAAK,WAAU,iCAAiC,YAAE,2CAA2C,aAAa,GAAE;AAAA,QAC7G;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,YAAY,gBAAgB;AAAA,YAC3C,iBAAiB,CAAC,YAAY;AAAE,oBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,aAAa,YAAY,KAAK,EAAE,GAAG,IAAI;AAAA,YAAE;AAAA,YAC5H,OAAO,EAAE,4CAA4C,MAAM;AAAA,YAC3D,kBAAiB;AAAA;AAAA,QACnB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,CAAC,CAAC,MAAM,YAAY;AAAA,YAC7B,iBAAiB,CAAC,YAAY;AAAE,oBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,YAAY,YAAY,KAAK,EAAE,GAAG,IAAI;AAAA,YAAE;AAAA,YAC3H,OAAO,EAAE,2CAA2C,QAAQ;AAAA,YAC5D,kBAAiB;AAAA;AAAA,QACnB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,YAAY,iBAAiB;AAAA,YAC5C,iBAAiB,CAAC,YAAY;AAAE,oBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,cAAc,YAAY,KAAK,EAAE,GAAG,IAAI;AAAA,YAAE;AAAA,YAC7H,OAAO,EAAE,6CAA6C,MAAM;AAAA,YAC5D,kBAAiB;AAAA;AAAA,QACnB;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,CAAC,CAAC,MAAM,YAAY;AAAA,YAC7B,iBAAiB,CAAC,YAAY;AAAE,oBAAM,EAAE,YAAY,EAAE,GAAI,MAAM,cAAc,CAAC,GAAI,WAAW,YAAY,KAAK,EAAE,GAAG,IAAI;AAAA,YAAE;AAAA,YAC1H,OAAO,EAAE,0CAA0C,WAAW;AAAA,YAC9D,kBAAiB;AAAA;AAAA,QACnB;AAAA,SACF;AAAA,OACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc,CAAC,SAAS;AACtB,8BAAoB,IAAI;AACxB,cAAI,CAAC,KAAM,mBAAkB;AAAA,QAC/B;AAAA,QAEA,+BAAC,iBAAc,WAAU,YACvB;AAAA,+BAAC,gBACC;AAAA,gCAAC,eAAa,YAAE,0CAA0C,YAAY,GAAE;AAAA,YACxE,oBAAC,qBAAmB,YAAE,qDAAqD,6DAA6D,GAAE;AAAA,aAC5I;AAAA,UACA,qBAAC,SAAI,WAAU,kBACb;AAAA,gCAAC,aAAU,OAAO,EAAE,sCAAsC,OAAO,GAAG,OAAO,mBAAmB,QAC5F;AAAA,cAAC;AAAA;AAAA,gBACC,gBAAe;AAAA,gBACf,aAAY;AAAA,gBACZ,OAAO;AAAA,gBACP,UAAU,CAAC,UAAU;AACnB,qCAAmB,IAAI;AACvB,sCAAoB,MAAM,OAAO,KAAK;AAAA,gBACxC;AAAA;AAAA,YACF,GACF;AAAA,YACA,oBAAC,aAAU,OAAO,EAAE,sCAAsC,OAAO,GAC/D;AAAA,cAAC;AAAA;AAAA,gBACC,aAAa,EAAE,uDAAuD,iCAAiC;AAAA,gBACvG,OAAO;AAAA,gBACP,UAAU,CAAC,UAAU,oBAAoB,MAAM,OAAO,KAAK;AAAA;AAAA,YAC7D,GACF;AAAA,aACF;AAAA,UACA,qBAAC,gBACC;AAAA,gCAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,yBAC1C,YAAE,uCAAuC,QAAQ,GACpD;AAAA,YACA,oBAAC,UAAO,MAAK,MAAK,SAAS,iBACxB,YAAE,0CAA0C,YAAY,GAC3D;AAAA,aACF;AAAA,WACF;AAAA;AAAA,IACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,cAAc,CAAC,SAAS;AACtB,6BAAmB,IAAI;AACvB,cAAI,CAAC,MAAM;AACT,0BAAc,IAAI;AAClB,gCAAoB,IAAI;AACxB,0BAAc,EAAE,MAAM,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC;AAAA,UACjD;AAAA,QACF;AAAA,QAEA,+BAAC,iBAAc,WAAU,YACvB;AAAA,+BAAC,gBACC;AAAA,gCAAC,eACE,6BACG,EAAE,0CAA0C,YAAY,IACxD,EAAE,yCAAyC,WAAW,GAC5D;AAAA,YACA,oBAAC,qBACE,6BACG,EAAE,qDAAqD,8CAA8C,IACrG,EAAE,oDAAoD,yCAAyC,GACrG;AAAA,aACF;AAAA,UACA,qBAAC,SAAI,WAAU,aACb;AAAA,gCAAC,aAAU,OAAO,EAAE,0CAA0C,YAAY,GAAG,OAAO,cAAc,QAAW,UAAU,CAAC,CAAC,kBACvH;AAAA,cAAC;AAAA;AAAA,gBACC,gBAAe;AAAA,gBACf,OAAO,WAAW;AAAA,gBAClB,UAAU,CAAC,UAAU;AACnB,gCAAc,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,MAAM,OAAO,MAAM,EAAE;AAC/D,sBAAI,WAAY,eAAc,IAAI;AAAA,gBACpC;AAAA,gBACA,UAAU,CAAC,CAAC;AAAA,gBACZ,aAAa,EAAE,qDAAqD,uBAAuB;AAAA;AAAA,YAC7F,GACF;AAAA,YACA,oBAAC,aAAU,OAAO,EAAE,sCAAsC,OAAO,GAC/D;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,WAAW;AAAA,gBAClB,UAAU,CAAC,UAAU,cAAc,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,OAAO,MAAM,EAAE;AAAA,gBACrF,aAAa,EAAE,sDAAsD,kBAAkB;AAAA;AAAA,YACzF,GACF;AAAA,YACA,oBAAC,aAAU,OAAO,EAAE,qCAAqC,MAAM,GAC7D;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,WAAW;AAAA,gBAClB,UAAU,CAAC,UAAU,cAAc,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,MAAM,OAAO,MAAM,EAAE;AAAA,gBACpF,aAAa,EAAE,qDAAqD,0BAA0B;AAAA;AAAA,YAChG,GACF;AAAA,YACC,wBAAwB,aAAa,SAAS,IAC7C,qBAAC,SACC;AAAA,kCAAC,SAAI,WAAU,4BAA4B,YAAE,+CAA+C,iBAAiB,GAAE;AAAA,cAC/G,oBAAC,SAAI,WAAU,sCACZ,uBAAa,IAAI,CAAC,UACjB,qBAAC,SAAqB,WAAU,sEAC9B;AAAA,qCAAC,SACC;AAAA,sCAAC,SAAI,WAAU,eAAe,gBAAM,SAAS,MAAM,MAAK;AAAA,kBACxD,oBAAC,SAAI,WAAU,2CAA2C,gBAAM,MAAK;AAAA,kBACpE,MAAM,OACL,oBAAC,SAAI,WAAU,iCAAiC,gBAAM,MAAK,IACzD;AAAA,mBACN;AAAA,gBACA,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,SAAQ;AAAA,sBACR,MAAK;AAAA,sBACL,WAAU;AAAA,sBACV,SAAS,MAAM,qBAAqB,KAAK;AAAA,sBACzC,cAAY,EAAE,8CAA8C,aAAa,EAAE,QAAQ,UAAU,MAAM,IAAI;AAAA,sBAEvG,8BAAC,UAAO,WAAU,WAAU;AAAA;AAAA,kBAC9B;AAAA,kBACA;AAAA,oBAAC;AAAA;AAAA,sBACC,SAAQ;AAAA,sBACR,MAAK;AAAA,sBACL,WAAU;AAAA,sBACV,SAAS,MAAM,uBAAuB,MAAM,IAAI;AAAA,sBAChD,cAAY,EAAE,gDAAgD,eAAe,EAAE,QAAQ,UAAU,MAAM,IAAI;AAAA,sBAE3G,8BAAC,UAAO,WAAU,WAAU;AAAA;AAAA,kBAC9B;AAAA,mBACF;AAAA,mBA3BQ,MAAM,IA4BhB,CACD,GACH;AAAA,eACF,IACE;AAAA,aACN;AAAA,UACA,qBAAC,gBACC;AAAA,gCAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,MAAM,mBAAmB,KAAK,GACxE,YAAE,uCAAuC,QAAQ,GACpD;AAAA,YACA,oBAAC,UAAO,MAAK,MAAK,SAAS,yBACxB,YAAE,0CAA0C,YAAY,GAC3D;AAAA,aACF;AAAA,WACF;AAAA;AAAA,IACF;AAAA,KACA;AAEJ,CAAC;AAED,oBAAoB,cAAc;",
|
|
6
6
|
"names": ["code", "FieldDefinitionCard", "nextConfig"]
|
|
7
7
|
}
|
|
@@ -269,7 +269,6 @@ function useMessageCompose({
|
|
|
269
269
|
const params = new URLSearchParams();
|
|
270
270
|
params.set("page", "1");
|
|
271
271
|
params.set("pageSize", "100");
|
|
272
|
-
params.set("scopeToActiveOrganization", "1");
|
|
273
272
|
const call = await apiCall(
|
|
274
273
|
`/api/auth/users?${params.toString()}`,
|
|
275
274
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/backend/messages/useMessageCompose.ts"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { flash } from '../FlashMessages'\nimport { apiCall, withScopedApiRequestHeaders } from '../utils/apiCall'\nimport { buildOptimisticLockHeader } from '../utils/optimisticLock'\nimport { surfaceRecordConflict } from '../conflicts'\nimport type {\n AttachmentListResponse,\n MessageComposerProps,\n MessageTypeItem,\n UserListItem,\n} from './message-composer.types'\nimport type { MessagePriority } from './message-priority'\nimport type { TagsInputOption } from '../inputs/TagsInput'\nimport {\n useComposeDraftOperation,\n useComposeSendOperation,\n useForwardSubmitOperation,\n useReplySubmitOperation,\n useSendDraftOperation,\n useUpdateDraftOperation,\n} from './useMessageComposeOperations'\n\nfunction toErrorMessage(payload: unknown): string | null {\n if (!payload) return null\n if (typeof payload === 'string') return payload\n if (Array.isArray(payload)) {\n for (const item of payload) {\n const nested = toErrorMessage(item)\n if (nested) return nested\n }\n return null\n }\n if (typeof payload === 'object') {\n const record = payload as Record<string, unknown>\n return (\n toErrorMessage(record.error)\n ?? toErrorMessage(record.message)\n ?? toErrorMessage(record.detail)\n ?? toErrorMessage(record.details)\n ?? null\n )\n }\n return null\n}\n\nfunction createTemporaryAttachmentRecordId(): string {\n const randomPart =\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`\n return `messages-composer:${randomPart}`\n}\n\nexport type UseMessageComposeParams = MessageComposerProps\n\nexport type UseMessageComposeResult = {\n t: ReturnType<typeof useT>\n variant: NonNullable<MessageComposerProps['variant']>\n messageId?: string\n open?: boolean\n inline: boolean\n contextPreview: React.ReactNode\n isOpen: boolean\n messageTypes: MessageTypeItem[]\n createableMessageTypes: MessageTypeItem[]\n normalizedRequiredActionMode: 'none' | 'optional' | 'required'\n contextActionOptions: Array<{ id: string; label: string }>\n shouldShowContextActions: boolean\n isComposePublicVisibility: boolean\n attachmentEntityId: string\n attachmentRecordId: string\n recipientIds: string[]\n setRecipientIds: React.Dispatch<React.SetStateAction<string[]>>\n messageType: string\n setMessageType: React.Dispatch<React.SetStateAction<string>>\n subject: string\n setSubject: React.Dispatch<React.SetStateAction<string>>\n body: string\n setBody: React.Dispatch<React.SetStateAction<string>>\n bodyFormat: 'text' | 'markdown'\n setBodyFormat: React.Dispatch<React.SetStateAction<'text' | 'markdown'>>\n priority: MessagePriority\n setPriority: React.Dispatch<React.SetStateAction<MessagePriority>>\n visibility: 'public' | 'internal'\n setVisibility: React.Dispatch<React.SetStateAction<'public' | 'internal'>>\n externalEmail: string\n setExternalEmail: React.Dispatch<React.SetStateAction<string>>\n sendViaEmail: boolean\n setSendViaEmail: React.Dispatch<React.SetStateAction<boolean>>\n contextActionRequired: boolean\n setContextActionRequired: React.Dispatch<React.SetStateAction<boolean>>\n contextActionType: string\n setContextActionType: React.Dispatch<React.SetStateAction<string>>\n replyAll: boolean\n setReplyAll: React.Dispatch<React.SetStateAction<boolean>>\n includeAttachments: boolean\n setIncludeAttachments: React.Dispatch<React.SetStateAction<boolean>>\n submitting: boolean\n submitMode: 'send' | 'draft'\n submitError: string | null\n composerTitle: string\n submitLabel: string\n selectedRecipientOptions: TagsInputOption[]\n resolveRecipientLabel: (id: string) => string\n loadRecipientSuggestions: (query?: string) => Promise<TagsInputOption[]>\n loadAttachmentIds: () => Promise<string[]>\n handleSaveDraft: () => void\n handleBack: () => void\n handleSubmit: ({ saveAsDraft }?: { saveAsDraft?: boolean }) => Promise<boolean>\n handleDialogOpenChange: (nextOpen: boolean) => void\n handleKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void\n}\n\ntype ForwardPreviewResponse = {\n subject?: string\n body?: string\n}\n\nexport function useMessageCompose({\n variant: variantProp = 'compose',\n messageId,\n open,\n onOpenChange,\n inline = false,\n lockedType = null,\n contextObject = null,\n requiredActionConfig = null,\n contextPreview = null,\n defaultValues,\n expectedUpdatedAt = null,\n onSuccess,\n onCancel,\n}: UseMessageComposeParams): UseMessageComposeResult {\n const t = useT()\n const variant = variantProp\n const isOpen = inline ? true : Boolean(open)\n const recipientSuggestionsCacheRef = React.useRef<TagsInputOption[] | null>(null)\n\n const [recipientIds, setRecipientIds] = React.useState<string[]>([])\n const [recipientMap, setRecipientMap] = React.useState<Record<string, TagsInputOption>>({})\n const [messageType, setMessageType] = React.useState(lockedType ?? 'default')\n const [subject, setSubject] = React.useState('')\n const [body, setBody] = React.useState('')\n const [bodyFormat, setBodyFormat] = React.useState<'text' | 'markdown'>('text')\n const [priority, setPriority] = React.useState<MessagePriority>('normal')\n const [visibility, setVisibility] = React.useState<'public' | 'internal'>('internal')\n const [externalEmail, setExternalEmail] = React.useState('')\n const [attachmentIds, setAttachmentIds] = React.useState<string[]>([])\n const [sendViaEmail, setSendViaEmail] = React.useState(false)\n const [contextActionRequired, setContextActionRequired] = React.useState(false)\n const [contextActionType, setContextActionType] = React.useState('')\n const [replyAll, setReplyAll] = React.useState(false)\n const [includeAttachments, setIncludeAttachments] = React.useState(true)\n const [temporaryAttachmentRecordId, setTemporaryAttachmentRecordId] = React.useState<string>(() =>\n createTemporaryAttachmentRecordId(),\n )\n const [submitting, setSubmitting] = React.useState(false)\n const [submitMode, setSubmitMode] = React.useState<'send' | 'draft'>('send')\n const [submitError, setSubmitError] = React.useState<string | null>(null)\n // Tracks whether the composer is currently in the \"open\" lifecycle so the init\n // effect below only runs on the closed \u2192 open transition, not on every parent\n // re-render that produces a new `defaultValues` / `contextObject` reference\n // while the user is typing. Without this guard, an inline literal\n // `defaultValues={{...}}` in a re-rendering parent (e.g. message detail page\n // with live notification badges or queue progress) would clear the body /\n // subject mid-keystroke. CI shard 9 surfaced this as TC-MSG-009 timing out\n // because `keyboard.type` characters appeared to \"type nowhere\" \u2014 they were\n // typed correctly, then immediately wiped by the next effect run.\n const isOpenRef = React.useRef(false)\n const wasOpenRef = React.useRef(false)\n const submitLockReleaseRef = React.useRef<(() => void) | null>(null)\n\n const messageTypesQuery = useQuery({\n queryKey: ['messages', 'types'],\n enabled: variant === 'compose' && isOpen,\n staleTime: 5 * 60 * 1000,\n queryFn: async () => {\n const call = await apiCall<{ items?: MessageTypeItem[] }>('/api/messages/types')\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadTypesFailed', 'Failed to load message types.'),\n )\n }\n return Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n },\n })\n\n const messageTypes = React.useMemo(\n () => messageTypesQuery.data ?? [],\n [messageTypesQuery.data],\n )\n const createableMessageTypes = React.useMemo(\n () => messageTypes.filter((item) => item.isCreateableByUser !== false),\n [messageTypes],\n )\n const normalizedRequiredActionMode = requiredActionConfig?.mode ?? 'none'\n const contextActionOptions = React.useMemo(\n () => (requiredActionConfig?.options ?? []).filter((option) => option.id.trim().length > 0),\n [requiredActionConfig?.options],\n )\n const shouldShowContextActions = (\n variant === 'compose'\n && Boolean(contextObject)\n && normalizedRequiredActionMode !== 'none'\n && contextActionOptions.length > 0\n )\n\n const isComposePublicVisibility = variant === 'compose' && visibility === 'public'\n\n const attachmentEntityId = variant === 'compose' && messageId ? 'messages:message' : 'attachments:library'\n const attachmentRecordId = variant === 'compose' && messageId ? messageId : temporaryAttachmentRecordId\n\n const loadAttachmentIds = React.useCallback(async (): Promise<string[]> => {\n const params = new URLSearchParams()\n params.set('entityId', attachmentEntityId)\n params.set('recordId', attachmentRecordId)\n\n const call = await apiCall<AttachmentListResponse>(`/api/attachments?${params.toString()}`)\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadAttachmentOptionsFailed', 'Failed to load attachments.'),\n )\n }\n\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const nextIds = items\n .map((item) => (typeof item?.id === 'string' ? item.id : ''))\n .filter((id) => id.length > 0)\n\n setAttachmentIds(nextIds)\n return nextIds\n }, [attachmentEntityId, attachmentRecordId, t])\n\n React.useEffect(() => {\n if (!isOpen) {\n isOpenRef.current = false\n return\n }\n // Only initialize on the closed \u2192 open transition. Subsequent parent\n // re-renders that change `defaultValues` / `contextObject` references\n // (inline object literals are a new reference on every render) MUST NOT\n // overwrite state the user has typed in.\n if (isOpenRef.current) return\n isOpenRef.current = true\n\n const nextRecipients = defaultValues?.recipients?.filter((value) => typeof value === 'string' && value.trim().length > 0) ?? []\n const dedupedRecipients = Array.from(new Set(nextRecipients))\n\n setRecipientIds(dedupedRecipients)\n setMessageType(lockedType ?? defaultValues?.type ?? 'default')\n setSubject(defaultValues?.subject ?? '')\n setBody(defaultValues?.body ?? '')\n setBodyFormat(defaultValues?.bodyFormat ?? 'text')\n setPriority(defaultValues?.priority ?? 'normal')\n setVisibility(defaultValues?.visibility ?? 'internal')\n setExternalEmail(defaultValues?.externalEmail ?? '')\n setAttachmentIds(\n Array.isArray(defaultValues?.attachmentIds)\n ? defaultValues.attachmentIds.filter((id): id is string => typeof id === 'string' && id.trim().length > 0)\n : [],\n )\n setSendViaEmail(Boolean(defaultValues?.sendViaEmail))\n if (contextObject) {\n const defaultContextActionType = requiredActionConfig?.defaultActionType?.trim() ?? ''\n const fallbackContextActionType = contextObject.actionType?.trim() ?? ''\n const selectedActionType = defaultContextActionType || fallbackContextActionType\n const selectedActionAllowed = contextActionOptions.some((option) => option.id === selectedActionType)\n const nextActionType = selectedActionAllowed ? selectedActionType : ''\n setContextActionType(nextActionType)\n if (normalizedRequiredActionMode === 'required') {\n setContextActionRequired(true)\n } else if (normalizedRequiredActionMode === 'optional') {\n setContextActionRequired(Boolean(nextActionType) || Boolean(contextObject.actionRequired))\n } else {\n setContextActionRequired(Boolean(contextObject.actionRequired))\n }\n } else {\n setContextActionType('')\n setContextActionRequired(false)\n }\n setReplyAll(Boolean(defaultValues?.replyAll))\n setIncludeAttachments(defaultValues?.includeAttachments !== false)\n setTemporaryAttachmentRecordId(createTemporaryAttachmentRecordId())\n setSubmitError(null)\n }, [\n contextActionOptions,\n contextObject,\n defaultValues,\n isOpen,\n lockedType,\n normalizedRequiredActionMode,\n requiredActionConfig?.defaultActionType,\n ])\n\n React.useEffect(() => {\n if (!isOpen) {\n submitLockReleaseRef.current?.()\n submitLockReleaseRef.current = null\n wasOpenRef.current = false\n return\n }\n\n const justOpened = isOpen && !wasOpenRef.current\n wasOpenRef.current = isOpen\n if (!justOpened) return\n submitLockReleaseRef.current?.()\n submitLockReleaseRef.current = null\n setSubmitting(false)\n setSubmitMode('send')\n }, [isOpen])\n\n React.useEffect(() => () => {\n submitLockReleaseRef.current?.()\n submitLockReleaseRef.current = null\n }, [])\n\n React.useEffect(() => {\n if (!isOpen) return\n if (variant !== 'forward') return\n if (!messageId) return\n\n let isActive = true\n\n void (async () => {\n const call = await apiCall<ForwardPreviewResponse>(`/api/messages/${encodeURIComponent(messageId)}/forward-preview`)\n if (!isActive) return\n\n if (!call.ok) {\n const message = toErrorMessage(call.result)\n ?? t('messages.errors.forwardPreviewFailed', 'Failed to load forward preview.')\n setSubmitError(message)\n flash(message, 'error')\n return\n }\n\n if (typeof call.result?.subject === 'string') {\n setSubject((previousValue) => (previousValue.trim().length > 0 ? previousValue : call.result?.subject ?? ''))\n }\n if (typeof call.result?.body === 'string') {\n setBody((previousValue) => (previousValue.trim().length > 0 ? previousValue : call.result?.body ?? ''))\n }\n setBodyFormat('text')\n })().catch((error) => {\n if (!isActive) return\n const message = error instanceof Error\n ? error.message\n : t('messages.errors.forwardPreviewFailed', 'Failed to load forward preview.')\n setSubmitError(message)\n flash(message, 'error')\n })\n\n return () => {\n isActive = false\n }\n }, [isOpen, messageId, t, variant])\n\n React.useEffect(() => {\n if (!isOpen) return\n if (variant !== 'compose' && variant !== 'reply') return\n void loadAttachmentIds().catch(() => null)\n }, [isOpen, loadAttachmentIds, variant])\n\n React.useEffect(() => {\n if (variant !== 'compose') return\n if (!createableMessageTypes.length) return\n\n if (lockedType) {\n if (createableMessageTypes.some((item) => item.type === lockedType)) {\n setMessageType(lockedType)\n return\n }\n const defaultType = createableMessageTypes.find((item) => item.type === 'default')\n setMessageType(defaultType?.type ?? createableMessageTypes[0]?.type ?? 'default')\n return\n }\n\n if (createableMessageTypes.some((item) => item.type === messageType)) return\n\n const defaultType = createableMessageTypes.find((item) => item.type === 'default')\n setMessageType(defaultType?.type ?? createableMessageTypes[0]?.type ?? 'default')\n }, [createableMessageTypes, lockedType, messageType, variant])\n\n React.useEffect(() => {\n if (variant !== 'compose') return\n if (visibility !== 'public') return\n setSendViaEmail(true)\n setRecipientIds([])\n }, [variant, visibility])\n\n React.useEffect(() => {\n if (isOpen) return\n recipientSuggestionsCacheRef.current = null\n }, [isOpen])\n\n const resolveRecipientLabel = React.useCallback((id: string) => {\n return recipientMap[id]?.label ?? id\n }, [recipientMap])\n\n const selectedRecipientOptions = React.useMemo(() => {\n return recipientIds.map((id) => recipientMap[id] ?? { value: id, label: id })\n }, [recipientIds, recipientMap])\n\n const loadRecipientSuggestions = React.useCallback(async (_query?: string) => {\n const cachedOptions = recipientSuggestionsCacheRef.current\n if (cachedOptions) {\n return cachedOptions\n }\n\n const params = new URLSearchParams()\n params.set('page', '1')\n params.set('pageSize', '100')\n // Scope suggestions to the composer's active organization: a message is stamped with\n // that org and its detail endpoint denies cross-org recipients, so a recipient from\n // another org could never open what they were sent.\n params.set('scopeToActiveOrganization', '1')\n // Recipient lookup is filtered in TagsInput because incremental auth user search is unreliable.\n\n const call = await apiCall<{ items?: UserListItem[] }>(\n `/api/auth/users?${params.toString()}`,\n {\n headers: {\n 'x-om-forbidden-redirect': '0',\n },\n },\n ).catch(() => null)\n if (!call) {\n return []\n }\n if (!call.ok) {\n return []\n }\n\n const rawItems = Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n const options: TagsInputOption[] = []\n for (const item of rawItems) {\n if (!item || typeof item !== 'object') continue\n const id = typeof item.id === 'string' ? item.id : ''\n if (!id) continue\n\n const email = typeof item.email === 'string' && item.email.trim().length ? item.email.trim() : id\n const name = typeof item.name === 'string' && item.name.trim().length ? item.name.trim() : undefined\n\n options.push({\n value: id,\n label: email,\n description: name,\n })\n }\n\n if (options.length) {\n setRecipientMap((prev) => {\n const next = { ...prev }\n for (const option of options) {\n next[option.value] = option\n }\n return next\n })\n }\n\n recipientSuggestionsCacheRef.current = options\n return options\n }, [])\n\n const handleCancel = React.useCallback(() => {\n if (submitting) return\n if (!inline) {\n onOpenChange?.(false)\n }\n onCancel?.()\n }, [inline, onCancel, onOpenChange, submitting])\n\n const composeSendOperation = useComposeSendOperation({\n t,\n messageType,\n createableMessageTypes,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const composeDraftOperation = useComposeDraftOperation({\n t,\n messageId,\n messageType,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const replyOperation = useReplySubmitOperation({\n t,\n messageId,\n body,\n bodyFormat,\n replyAll,\n recipientIds,\n sendViaEmail,\n })\n\n const forwardOperation = useForwardSubmitOperation({\n t,\n messageId,\n recipientIds,\n body,\n includeAttachments,\n sendViaEmail,\n })\n\n const sendDraftOperation = useSendDraftOperation({\n t,\n messageId: messageId ?? '',\n messageType,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const updateDraftOperation = useUpdateDraftOperation({\n t,\n messageId: messageId ?? '',\n messageType,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const handleSubmit = React.useCallback(async ({ saveAsDraft = false }: { saveAsDraft?: boolean } = {}) => {\n if (submitting) return false\n\n setSubmitError(null)\n\n const isEditingExistingDraft = variant === 'compose' && Boolean(messageId)\n const isComposeDraftSubmit = saveAsDraft && variant === 'compose'\n const operation = isComposeDraftSubmit\n ? (isEditingExistingDraft ? updateDraftOperation : composeDraftOperation)\n : variant === 'compose'\n ? (isEditingExistingDraft ? sendDraftOperation : composeSendOperation)\n : variant === 'reply'\n ? replyOperation\n : forwardOperation\n\n const validationMessage = operation.validate()\n if (validationMessage) {\n setSubmitError(validationMessage)\n flash(validationMessage, 'error')\n return false\n }\n\n setSubmitMode(isComposeDraftSubmit ? 'draft' : 'send')\n setSubmitting(true)\n let keepSubmitLock = false\n let shouldReturnFalse = false\n\n try {\n let nextAttachmentIds = attachmentIds\n if (operation.requiresAttachmentRefresh) {\n try {\n nextAttachmentIds = await loadAttachmentIds()\n } catch (error) {\n const message = error instanceof Error\n ? error.message\n : t('messages.errors.loadAttachmentOptionsFailed', 'Failed to load attachments.')\n setSubmitError(message)\n flash(message, 'error')\n shouldReturnFalse = true\n }\n }\n\n if (!shouldReturnFalse) {\n const { endpoint, method, payload } = operation.buildRequest({ attachmentIds: nextAttachmentIds })\n\n // Editing an existing draft is a PATCH on the message aggregate, so carry\n // the OSS optimistic-lock header to reject a stale overwrite. New\n // compose/reply/forward writes create fresh records and never lock.\n const lockHeaders = isEditingExistingDraft\n ? buildOptimisticLockHeader(expectedUpdatedAt)\n : {}\n\n const call = await withScopedApiRequestHeaders(lockHeaders, () =>\n apiCall<{ id?: string }>(endpoint, {\n method,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }),\n )\n\n if (!call.ok) {\n if (surfaceRecordConflict({ status: call.status, body: call.result }, t)) {\n setSubmitError(\n t('ui.forms.flash.recordModified', 'This record was modified by someone else. Refresh and try again.'),\n )\n // The shared conflict banner renders at page level, so it is hidden\n // behind the compose modal. Close the dialog to reveal it (with its\n // Refresh action); the stale draft must be reloaded anyway (#3260 QA).\n if (!inline) {\n onOpenChange?.(false)\n }\n } else {\n const message = toErrorMessage(call.result) ?? t('messages.errors.sendFailed', 'Failed to send message.')\n setSubmitError(message)\n flash(message, 'error')\n }\n shouldReturnFalse = true\n } else {\n flash(operation.successMessage, 'success')\n keepSubmitLock = true\n\n onSuccess?.({ id: call.result?.id })\n\n if (!inline) {\n onOpenChange?.(false)\n }\n }\n }\n } catch (error) {\n const message = error instanceof Error\n ? error.message\n : t('messages.errors.sendFailed', 'Failed to send message.')\n setSubmitError(message)\n flash(message, 'error')\n shouldReturnFalse = true\n } finally {\n if (!keepSubmitLock) {\n setSubmitting(false)\n }\n setSubmitMode('send')\n }\n\n if (shouldReturnFalse) {\n return false\n }\n\n if (keepSubmitLock) {\n return await new Promise<boolean>((resolve) => {\n submitLockReleaseRef.current = () => resolve(true)\n })\n }\n\n return true\n }, [\n attachmentIds,\n composeDraftOperation,\n composeSendOperation,\n expectedUpdatedAt,\n forwardOperation,\n inline,\n loadAttachmentIds,\n messageId,\n onOpenChange,\n onSuccess,\n replyOperation,\n sendDraftOperation,\n submitting,\n t,\n updateDraftOperation,\n variant,\n ])\n\n const handleSaveDraft = React.useCallback(() => {\n if (variant !== 'compose') return\n void handleSubmit({ saveAsDraft: true })\n }, [handleSubmit, variant])\n\n const handleBack = React.useCallback(() => {\n if (submitting) return\n handleCancel()\n }, [handleCancel, submitting])\n\n const handleDialogOpenChange = React.useCallback((nextOpen: boolean) => {\n if (nextOpen) {\n onOpenChange?.(true)\n return\n }\n void handleBack()\n }, [handleBack, onOpenChange])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n void handleSubmit()\n return\n }\n\n if (event.key === 'Escape') {\n event.preventDefault()\n handleCancel()\n }\n }, [handleCancel, handleSubmit])\n\n const composerTitle = variant === 'reply'\n ? t('messages.reply', 'Reply')\n : variant === 'forward'\n ? t('messages.forward', 'Forward')\n : t('messages.compose', 'Compose message')\n\n const submitLabel = submitting\n ? submitMode === 'draft'\n ? t('messages.savingDraft', 'Saving draft...')\n : t('messages.sending', 'Sending...')\n : variant === 'reply'\n ? t('messages.reply', 'Reply')\n : variant === 'forward'\n ? t('messages.forward', 'Forward')\n : t('messages.send', 'Send')\n\n return {\n t,\n variant,\n messageId,\n open,\n inline,\n contextPreview,\n isOpen,\n messageTypes,\n createableMessageTypes,\n normalizedRequiredActionMode,\n contextActionOptions,\n shouldShowContextActions,\n isComposePublicVisibility,\n attachmentEntityId,\n attachmentRecordId,\n recipientIds,\n setRecipientIds,\n messageType,\n setMessageType,\n subject,\n setSubject,\n body,\n setBody,\n bodyFormat,\n setBodyFormat,\n priority,\n setPriority,\n visibility,\n setVisibility,\n externalEmail,\n setExternalEmail,\n sendViaEmail,\n setSendViaEmail,\n contextActionRequired,\n setContextActionRequired,\n contextActionType,\n setContextActionType,\n replyAll,\n setReplyAll,\n includeAttachments,\n setIncludeAttachments,\n submitting,\n submitMode,\n submitError,\n composerTitle,\n submitLabel,\n selectedRecipientOptions,\n resolveRecipientLabel,\n loadRecipientSuggestions,\n loadAttachmentIds,\n handleSaveDraft,\n handleBack,\n handleSubmit,\n handleDialogOpenChange,\n handleKeyDown,\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import * as React from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { flash } from '../FlashMessages'\nimport { apiCall, withScopedApiRequestHeaders } from '../utils/apiCall'\nimport { buildOptimisticLockHeader } from '../utils/optimisticLock'\nimport { surfaceRecordConflict } from '../conflicts'\nimport type {\n AttachmentListResponse,\n MessageComposerProps,\n MessageTypeItem,\n UserListItem,\n} from './message-composer.types'\nimport type { MessagePriority } from './message-priority'\nimport type { TagsInputOption } from '../inputs/TagsInput'\nimport {\n useComposeDraftOperation,\n useComposeSendOperation,\n useForwardSubmitOperation,\n useReplySubmitOperation,\n useSendDraftOperation,\n useUpdateDraftOperation,\n} from './useMessageComposeOperations'\n\nfunction toErrorMessage(payload: unknown): string | null {\n if (!payload) return null\n if (typeof payload === 'string') return payload\n if (Array.isArray(payload)) {\n for (const item of payload) {\n const nested = toErrorMessage(item)\n if (nested) return nested\n }\n return null\n }\n if (typeof payload === 'object') {\n const record = payload as Record<string, unknown>\n return (\n toErrorMessage(record.error)\n ?? toErrorMessage(record.message)\n ?? toErrorMessage(record.detail)\n ?? toErrorMessage(record.details)\n ?? null\n )\n }\n return null\n}\n\nfunction createTemporaryAttachmentRecordId(): string {\n const randomPart =\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`\n return `messages-composer:${randomPart}`\n}\n\nexport type UseMessageComposeParams = MessageComposerProps\n\nexport type UseMessageComposeResult = {\n t: ReturnType<typeof useT>\n variant: NonNullable<MessageComposerProps['variant']>\n messageId?: string\n open?: boolean\n inline: boolean\n contextPreview: React.ReactNode\n isOpen: boolean\n messageTypes: MessageTypeItem[]\n createableMessageTypes: MessageTypeItem[]\n normalizedRequiredActionMode: 'none' | 'optional' | 'required'\n contextActionOptions: Array<{ id: string; label: string }>\n shouldShowContextActions: boolean\n isComposePublicVisibility: boolean\n attachmentEntityId: string\n attachmentRecordId: string\n recipientIds: string[]\n setRecipientIds: React.Dispatch<React.SetStateAction<string[]>>\n messageType: string\n setMessageType: React.Dispatch<React.SetStateAction<string>>\n subject: string\n setSubject: React.Dispatch<React.SetStateAction<string>>\n body: string\n setBody: React.Dispatch<React.SetStateAction<string>>\n bodyFormat: 'text' | 'markdown'\n setBodyFormat: React.Dispatch<React.SetStateAction<'text' | 'markdown'>>\n priority: MessagePriority\n setPriority: React.Dispatch<React.SetStateAction<MessagePriority>>\n visibility: 'public' | 'internal'\n setVisibility: React.Dispatch<React.SetStateAction<'public' | 'internal'>>\n externalEmail: string\n setExternalEmail: React.Dispatch<React.SetStateAction<string>>\n sendViaEmail: boolean\n setSendViaEmail: React.Dispatch<React.SetStateAction<boolean>>\n contextActionRequired: boolean\n setContextActionRequired: React.Dispatch<React.SetStateAction<boolean>>\n contextActionType: string\n setContextActionType: React.Dispatch<React.SetStateAction<string>>\n replyAll: boolean\n setReplyAll: React.Dispatch<React.SetStateAction<boolean>>\n includeAttachments: boolean\n setIncludeAttachments: React.Dispatch<React.SetStateAction<boolean>>\n submitting: boolean\n submitMode: 'send' | 'draft'\n submitError: string | null\n composerTitle: string\n submitLabel: string\n selectedRecipientOptions: TagsInputOption[]\n resolveRecipientLabel: (id: string) => string\n loadRecipientSuggestions: (query?: string) => Promise<TagsInputOption[]>\n loadAttachmentIds: () => Promise<string[]>\n handleSaveDraft: () => void\n handleBack: () => void\n handleSubmit: ({ saveAsDraft }?: { saveAsDraft?: boolean }) => Promise<boolean>\n handleDialogOpenChange: (nextOpen: boolean) => void\n handleKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void\n}\n\ntype ForwardPreviewResponse = {\n subject?: string\n body?: string\n}\n\nexport function useMessageCompose({\n variant: variantProp = 'compose',\n messageId,\n open,\n onOpenChange,\n inline = false,\n lockedType = null,\n contextObject = null,\n requiredActionConfig = null,\n contextPreview = null,\n defaultValues,\n expectedUpdatedAt = null,\n onSuccess,\n onCancel,\n}: UseMessageComposeParams): UseMessageComposeResult {\n const t = useT()\n const variant = variantProp\n const isOpen = inline ? true : Boolean(open)\n const recipientSuggestionsCacheRef = React.useRef<TagsInputOption[] | null>(null)\n\n const [recipientIds, setRecipientIds] = React.useState<string[]>([])\n const [recipientMap, setRecipientMap] = React.useState<Record<string, TagsInputOption>>({})\n const [messageType, setMessageType] = React.useState(lockedType ?? 'default')\n const [subject, setSubject] = React.useState('')\n const [body, setBody] = React.useState('')\n const [bodyFormat, setBodyFormat] = React.useState<'text' | 'markdown'>('text')\n const [priority, setPriority] = React.useState<MessagePriority>('normal')\n const [visibility, setVisibility] = React.useState<'public' | 'internal'>('internal')\n const [externalEmail, setExternalEmail] = React.useState('')\n const [attachmentIds, setAttachmentIds] = React.useState<string[]>([])\n const [sendViaEmail, setSendViaEmail] = React.useState(false)\n const [contextActionRequired, setContextActionRequired] = React.useState(false)\n const [contextActionType, setContextActionType] = React.useState('')\n const [replyAll, setReplyAll] = React.useState(false)\n const [includeAttachments, setIncludeAttachments] = React.useState(true)\n const [temporaryAttachmentRecordId, setTemporaryAttachmentRecordId] = React.useState<string>(() =>\n createTemporaryAttachmentRecordId(),\n )\n const [submitting, setSubmitting] = React.useState(false)\n const [submitMode, setSubmitMode] = React.useState<'send' | 'draft'>('send')\n const [submitError, setSubmitError] = React.useState<string | null>(null)\n // Tracks whether the composer is currently in the \"open\" lifecycle so the init\n // effect below only runs on the closed \u2192 open transition, not on every parent\n // re-render that produces a new `defaultValues` / `contextObject` reference\n // while the user is typing. Without this guard, an inline literal\n // `defaultValues={{...}}` in a re-rendering parent (e.g. message detail page\n // with live notification badges or queue progress) would clear the body /\n // subject mid-keystroke. CI shard 9 surfaced this as TC-MSG-009 timing out\n // because `keyboard.type` characters appeared to \"type nowhere\" \u2014 they were\n // typed correctly, then immediately wiped by the next effect run.\n const isOpenRef = React.useRef(false)\n const wasOpenRef = React.useRef(false)\n const submitLockReleaseRef = React.useRef<(() => void) | null>(null)\n\n const messageTypesQuery = useQuery({\n queryKey: ['messages', 'types'],\n enabled: variant === 'compose' && isOpen,\n staleTime: 5 * 60 * 1000,\n queryFn: async () => {\n const call = await apiCall<{ items?: MessageTypeItem[] }>('/api/messages/types')\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadTypesFailed', 'Failed to load message types.'),\n )\n }\n return Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n },\n })\n\n const messageTypes = React.useMemo(\n () => messageTypesQuery.data ?? [],\n [messageTypesQuery.data],\n )\n const createableMessageTypes = React.useMemo(\n () => messageTypes.filter((item) => item.isCreateableByUser !== false),\n [messageTypes],\n )\n const normalizedRequiredActionMode = requiredActionConfig?.mode ?? 'none'\n const contextActionOptions = React.useMemo(\n () => (requiredActionConfig?.options ?? []).filter((option) => option.id.trim().length > 0),\n [requiredActionConfig?.options],\n )\n const shouldShowContextActions = (\n variant === 'compose'\n && Boolean(contextObject)\n && normalizedRequiredActionMode !== 'none'\n && contextActionOptions.length > 0\n )\n\n const isComposePublicVisibility = variant === 'compose' && visibility === 'public'\n\n const attachmentEntityId = variant === 'compose' && messageId ? 'messages:message' : 'attachments:library'\n const attachmentRecordId = variant === 'compose' && messageId ? messageId : temporaryAttachmentRecordId\n\n const loadAttachmentIds = React.useCallback(async (): Promise<string[]> => {\n const params = new URLSearchParams()\n params.set('entityId', attachmentEntityId)\n params.set('recordId', attachmentRecordId)\n\n const call = await apiCall<AttachmentListResponse>(`/api/attachments?${params.toString()}`)\n if (!call.ok) {\n throw new Error(\n toErrorMessage(call.result)\n ?? t('messages.errors.loadAttachmentOptionsFailed', 'Failed to load attachments.'),\n )\n }\n\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const nextIds = items\n .map((item) => (typeof item?.id === 'string' ? item.id : ''))\n .filter((id) => id.length > 0)\n\n setAttachmentIds(nextIds)\n return nextIds\n }, [attachmentEntityId, attachmentRecordId, t])\n\n React.useEffect(() => {\n if (!isOpen) {\n isOpenRef.current = false\n return\n }\n // Only initialize on the closed \u2192 open transition. Subsequent parent\n // re-renders that change `defaultValues` / `contextObject` references\n // (inline object literals are a new reference on every render) MUST NOT\n // overwrite state the user has typed in.\n if (isOpenRef.current) return\n isOpenRef.current = true\n\n const nextRecipients = defaultValues?.recipients?.filter((value) => typeof value === 'string' && value.trim().length > 0) ?? []\n const dedupedRecipients = Array.from(new Set(nextRecipients))\n\n setRecipientIds(dedupedRecipients)\n setMessageType(lockedType ?? defaultValues?.type ?? 'default')\n setSubject(defaultValues?.subject ?? '')\n setBody(defaultValues?.body ?? '')\n setBodyFormat(defaultValues?.bodyFormat ?? 'text')\n setPriority(defaultValues?.priority ?? 'normal')\n setVisibility(defaultValues?.visibility ?? 'internal')\n setExternalEmail(defaultValues?.externalEmail ?? '')\n setAttachmentIds(\n Array.isArray(defaultValues?.attachmentIds)\n ? defaultValues.attachmentIds.filter((id): id is string => typeof id === 'string' && id.trim().length > 0)\n : [],\n )\n setSendViaEmail(Boolean(defaultValues?.sendViaEmail))\n if (contextObject) {\n const defaultContextActionType = requiredActionConfig?.defaultActionType?.trim() ?? ''\n const fallbackContextActionType = contextObject.actionType?.trim() ?? ''\n const selectedActionType = defaultContextActionType || fallbackContextActionType\n const selectedActionAllowed = contextActionOptions.some((option) => option.id === selectedActionType)\n const nextActionType = selectedActionAllowed ? selectedActionType : ''\n setContextActionType(nextActionType)\n if (normalizedRequiredActionMode === 'required') {\n setContextActionRequired(true)\n } else if (normalizedRequiredActionMode === 'optional') {\n setContextActionRequired(Boolean(nextActionType) || Boolean(contextObject.actionRequired))\n } else {\n setContextActionRequired(Boolean(contextObject.actionRequired))\n }\n } else {\n setContextActionType('')\n setContextActionRequired(false)\n }\n setReplyAll(Boolean(defaultValues?.replyAll))\n setIncludeAttachments(defaultValues?.includeAttachments !== false)\n setTemporaryAttachmentRecordId(createTemporaryAttachmentRecordId())\n setSubmitError(null)\n }, [\n contextActionOptions,\n contextObject,\n defaultValues,\n isOpen,\n lockedType,\n normalizedRequiredActionMode,\n requiredActionConfig?.defaultActionType,\n ])\n\n React.useEffect(() => {\n if (!isOpen) {\n submitLockReleaseRef.current?.()\n submitLockReleaseRef.current = null\n wasOpenRef.current = false\n return\n }\n\n const justOpened = isOpen && !wasOpenRef.current\n wasOpenRef.current = isOpen\n if (!justOpened) return\n submitLockReleaseRef.current?.()\n submitLockReleaseRef.current = null\n setSubmitting(false)\n setSubmitMode('send')\n }, [isOpen])\n\n React.useEffect(() => () => {\n submitLockReleaseRef.current?.()\n submitLockReleaseRef.current = null\n }, [])\n\n React.useEffect(() => {\n if (!isOpen) return\n if (variant !== 'forward') return\n if (!messageId) return\n\n let isActive = true\n\n void (async () => {\n const call = await apiCall<ForwardPreviewResponse>(`/api/messages/${encodeURIComponent(messageId)}/forward-preview`)\n if (!isActive) return\n\n if (!call.ok) {\n const message = toErrorMessage(call.result)\n ?? t('messages.errors.forwardPreviewFailed', 'Failed to load forward preview.')\n setSubmitError(message)\n flash(message, 'error')\n return\n }\n\n if (typeof call.result?.subject === 'string') {\n setSubject((previousValue) => (previousValue.trim().length > 0 ? previousValue : call.result?.subject ?? ''))\n }\n if (typeof call.result?.body === 'string') {\n setBody((previousValue) => (previousValue.trim().length > 0 ? previousValue : call.result?.body ?? ''))\n }\n setBodyFormat('text')\n })().catch((error) => {\n if (!isActive) return\n const message = error instanceof Error\n ? error.message\n : t('messages.errors.forwardPreviewFailed', 'Failed to load forward preview.')\n setSubmitError(message)\n flash(message, 'error')\n })\n\n return () => {\n isActive = false\n }\n }, [isOpen, messageId, t, variant])\n\n React.useEffect(() => {\n if (!isOpen) return\n if (variant !== 'compose' && variant !== 'reply') return\n void loadAttachmentIds().catch(() => null)\n }, [isOpen, loadAttachmentIds, variant])\n\n React.useEffect(() => {\n if (variant !== 'compose') return\n if (!createableMessageTypes.length) return\n\n if (lockedType) {\n if (createableMessageTypes.some((item) => item.type === lockedType)) {\n setMessageType(lockedType)\n return\n }\n const defaultType = createableMessageTypes.find((item) => item.type === 'default')\n setMessageType(defaultType?.type ?? createableMessageTypes[0]?.type ?? 'default')\n return\n }\n\n if (createableMessageTypes.some((item) => item.type === messageType)) return\n\n const defaultType = createableMessageTypes.find((item) => item.type === 'default')\n setMessageType(defaultType?.type ?? createableMessageTypes[0]?.type ?? 'default')\n }, [createableMessageTypes, lockedType, messageType, variant])\n\n React.useEffect(() => {\n if (variant !== 'compose') return\n if (visibility !== 'public') return\n setSendViaEmail(true)\n setRecipientIds([])\n }, [variant, visibility])\n\n React.useEffect(() => {\n if (isOpen) return\n recipientSuggestionsCacheRef.current = null\n }, [isOpen])\n\n const resolveRecipientLabel = React.useCallback((id: string) => {\n return recipientMap[id]?.label ?? id\n }, [recipientMap])\n\n const selectedRecipientOptions = React.useMemo(() => {\n return recipientIds.map((id) => recipientMap[id] ?? { value: id, label: id })\n }, [recipientIds, recipientMap])\n\n const loadRecipientSuggestions = React.useCallback(async (_query?: string) => {\n const cachedOptions = recipientSuggestionsCacheRef.current\n if (cachedOptions) {\n return cachedOptions\n }\n\n const params = new URLSearchParams()\n params.set('page', '1')\n params.set('pageSize', '100')\n // Recipient lookup is filtered in TagsInput because incremental auth user search is unreliable.\n\n const call = await apiCall<{ items?: UserListItem[] }>(\n `/api/auth/users?${params.toString()}`,\n {\n headers: {\n 'x-om-forbidden-redirect': '0',\n },\n },\n ).catch(() => null)\n if (!call) {\n return []\n }\n if (!call.ok) {\n return []\n }\n\n const rawItems = Array.isArray(call.result?.items) ? call.result?.items ?? [] : []\n const options: TagsInputOption[] = []\n for (const item of rawItems) {\n if (!item || typeof item !== 'object') continue\n const id = typeof item.id === 'string' ? item.id : ''\n if (!id) continue\n\n const email = typeof item.email === 'string' && item.email.trim().length ? item.email.trim() : id\n const name = typeof item.name === 'string' && item.name.trim().length ? item.name.trim() : undefined\n\n options.push({\n value: id,\n label: email,\n description: name,\n })\n }\n\n if (options.length) {\n setRecipientMap((prev) => {\n const next = { ...prev }\n for (const option of options) {\n next[option.value] = option\n }\n return next\n })\n }\n\n recipientSuggestionsCacheRef.current = options\n return options\n }, [])\n\n const handleCancel = React.useCallback(() => {\n if (submitting) return\n if (!inline) {\n onOpenChange?.(false)\n }\n onCancel?.()\n }, [inline, onCancel, onOpenChange, submitting])\n\n const composeSendOperation = useComposeSendOperation({\n t,\n messageType,\n createableMessageTypes,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const composeDraftOperation = useComposeDraftOperation({\n t,\n messageId,\n messageType,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const replyOperation = useReplySubmitOperation({\n t,\n messageId,\n body,\n bodyFormat,\n replyAll,\n recipientIds,\n sendViaEmail,\n })\n\n const forwardOperation = useForwardSubmitOperation({\n t,\n messageId,\n recipientIds,\n body,\n includeAttachments,\n sendViaEmail,\n })\n\n const sendDraftOperation = useSendDraftOperation({\n t,\n messageId: messageId ?? '',\n messageType,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const updateDraftOperation = useUpdateDraftOperation({\n t,\n messageId: messageId ?? '',\n messageType,\n priority,\n visibility,\n externalEmail,\n recipientIds,\n subject,\n body,\n bodyFormat,\n sendViaEmail,\n contextObject,\n defaultValues,\n contextActionOptions,\n normalizedRequiredActionMode,\n shouldShowContextActions,\n contextActionRequired,\n contextActionType,\n })\n\n const handleSubmit = React.useCallback(async ({ saveAsDraft = false }: { saveAsDraft?: boolean } = {}) => {\n if (submitting) return false\n\n setSubmitError(null)\n\n const isEditingExistingDraft = variant === 'compose' && Boolean(messageId)\n const isComposeDraftSubmit = saveAsDraft && variant === 'compose'\n const operation = isComposeDraftSubmit\n ? (isEditingExistingDraft ? updateDraftOperation : composeDraftOperation)\n : variant === 'compose'\n ? (isEditingExistingDraft ? sendDraftOperation : composeSendOperation)\n : variant === 'reply'\n ? replyOperation\n : forwardOperation\n\n const validationMessage = operation.validate()\n if (validationMessage) {\n setSubmitError(validationMessage)\n flash(validationMessage, 'error')\n return false\n }\n\n setSubmitMode(isComposeDraftSubmit ? 'draft' : 'send')\n setSubmitting(true)\n let keepSubmitLock = false\n let shouldReturnFalse = false\n\n try {\n let nextAttachmentIds = attachmentIds\n if (operation.requiresAttachmentRefresh) {\n try {\n nextAttachmentIds = await loadAttachmentIds()\n } catch (error) {\n const message = error instanceof Error\n ? error.message\n : t('messages.errors.loadAttachmentOptionsFailed', 'Failed to load attachments.')\n setSubmitError(message)\n flash(message, 'error')\n shouldReturnFalse = true\n }\n }\n\n if (!shouldReturnFalse) {\n const { endpoint, method, payload } = operation.buildRequest({ attachmentIds: nextAttachmentIds })\n\n // Editing an existing draft is a PATCH on the message aggregate, so carry\n // the OSS optimistic-lock header to reject a stale overwrite. New\n // compose/reply/forward writes create fresh records and never lock.\n const lockHeaders = isEditingExistingDraft\n ? buildOptimisticLockHeader(expectedUpdatedAt)\n : {}\n\n const call = await withScopedApiRequestHeaders(lockHeaders, () =>\n apiCall<{ id?: string }>(endpoint, {\n method,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }),\n )\n\n if (!call.ok) {\n if (surfaceRecordConflict({ status: call.status, body: call.result }, t)) {\n setSubmitError(\n t('ui.forms.flash.recordModified', 'This record was modified by someone else. Refresh and try again.'),\n )\n // The shared conflict banner renders at page level, so it is hidden\n // behind the compose modal. Close the dialog to reveal it (with its\n // Refresh action); the stale draft must be reloaded anyway (#3260 QA).\n if (!inline) {\n onOpenChange?.(false)\n }\n } else {\n const message = toErrorMessage(call.result) ?? t('messages.errors.sendFailed', 'Failed to send message.')\n setSubmitError(message)\n flash(message, 'error')\n }\n shouldReturnFalse = true\n } else {\n flash(operation.successMessage, 'success')\n keepSubmitLock = true\n\n onSuccess?.({ id: call.result?.id })\n\n if (!inline) {\n onOpenChange?.(false)\n }\n }\n }\n } catch (error) {\n const message = error instanceof Error\n ? error.message\n : t('messages.errors.sendFailed', 'Failed to send message.')\n setSubmitError(message)\n flash(message, 'error')\n shouldReturnFalse = true\n } finally {\n if (!keepSubmitLock) {\n setSubmitting(false)\n }\n setSubmitMode('send')\n }\n\n if (shouldReturnFalse) {\n return false\n }\n\n if (keepSubmitLock) {\n return await new Promise<boolean>((resolve) => {\n submitLockReleaseRef.current = () => resolve(true)\n })\n }\n\n return true\n }, [\n attachmentIds,\n composeDraftOperation,\n composeSendOperation,\n expectedUpdatedAt,\n forwardOperation,\n inline,\n loadAttachmentIds,\n messageId,\n onOpenChange,\n onSuccess,\n replyOperation,\n sendDraftOperation,\n submitting,\n t,\n updateDraftOperation,\n variant,\n ])\n\n const handleSaveDraft = React.useCallback(() => {\n if (variant !== 'compose') return\n void handleSubmit({ saveAsDraft: true })\n }, [handleSubmit, variant])\n\n const handleBack = React.useCallback(() => {\n if (submitting) return\n handleCancel()\n }, [handleCancel, submitting])\n\n const handleDialogOpenChange = React.useCallback((nextOpen: boolean) => {\n if (nextOpen) {\n onOpenChange?.(true)\n return\n }\n void handleBack()\n }, [handleBack, onOpenChange])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') {\n event.preventDefault()\n void handleSubmit()\n return\n }\n\n if (event.key === 'Escape') {\n event.preventDefault()\n handleCancel()\n }\n }, [handleCancel, handleSubmit])\n\n const composerTitle = variant === 'reply'\n ? t('messages.reply', 'Reply')\n : variant === 'forward'\n ? t('messages.forward', 'Forward')\n : t('messages.compose', 'Compose message')\n\n const submitLabel = submitting\n ? submitMode === 'draft'\n ? t('messages.savingDraft', 'Saving draft...')\n : t('messages.sending', 'Sending...')\n : variant === 'reply'\n ? t('messages.reply', 'Reply')\n : variant === 'forward'\n ? t('messages.forward', 'Forward')\n : t('messages.send', 'Send')\n\n return {\n t,\n variant,\n messageId,\n open,\n inline,\n contextPreview,\n isOpen,\n messageTypes,\n createableMessageTypes,\n normalizedRequiredActionMode,\n contextActionOptions,\n shouldShowContextActions,\n isComposePublicVisibility,\n attachmentEntityId,\n attachmentRecordId,\n recipientIds,\n setRecipientIds,\n messageType,\n setMessageType,\n subject,\n setSubject,\n body,\n setBody,\n bodyFormat,\n setBodyFormat,\n priority,\n setPriority,\n visibility,\n setVisibility,\n externalEmail,\n setExternalEmail,\n sendViaEmail,\n setSendViaEmail,\n contextActionRequired,\n setContextActionRequired,\n contextActionType,\n setContextActionType,\n replyAll,\n setReplyAll,\n includeAttachments,\n setIncludeAttachments,\n submitting,\n submitMode,\n submitError,\n composerTitle,\n submitLabel,\n selectedRecipientOptions,\n resolveRecipientLabel,\n loadRecipientSuggestions,\n loadAttachmentIds,\n handleSaveDraft,\n handleBack,\n handleSubmit,\n handleDialogOpenChange,\n handleKeyDown,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["defaultType"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/ui",
|
|
3
|
-
"version": "0.6.6
|
|
3
|
+
"version": "0.6.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -155,13 +155,13 @@
|
|
|
155
155
|
"remark-gfm": "^4.0.1"
|
|
156
156
|
},
|
|
157
157
|
"peerDependencies": {
|
|
158
|
-
"@open-mercato/shared": "0.6.6
|
|
158
|
+
"@open-mercato/shared": "0.6.6",
|
|
159
159
|
"react": ">=18.0.0",
|
|
160
160
|
"react-dom": ">=18.0.0",
|
|
161
161
|
"react-is": ">=18.0.0"
|
|
162
162
|
},
|
|
163
163
|
"devDependencies": {
|
|
164
|
-
"@open-mercato/shared": "0.6.6
|
|
164
|
+
"@open-mercato/shared": "0.6.6",
|
|
165
165
|
"@testing-library/dom": "^10.4.1",
|
|
166
166
|
"@testing-library/jest-dom": "^6.9.1",
|
|
167
167
|
"@testing-library/react": "^16.3.1",
|
|
@@ -183,6 +183,5 @@
|
|
|
183
183
|
"type": "git",
|
|
184
184
|
"url": "https://github.com/open-mercato/open-mercato",
|
|
185
185
|
"directory": "packages/ui"
|
|
186
|
-
}
|
|
187
|
-
"stableVersion": "0.6.5"
|
|
186
|
+
}
|
|
188
187
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
SelectValue,
|
|
16
16
|
} from '../../primitives/select'
|
|
17
17
|
import { CUSTOM_FIELD_KINDS } from '@open-mercato/shared/modules/entities/kinds'
|
|
18
|
-
import { useOptionalT
|
|
18
|
+
import { useOptionalT } from '@open-mercato/shared/lib/i18n/context'
|
|
19
19
|
import { FieldRegistry } from '../fields/registry'
|
|
20
20
|
import { slugify } from '@open-mercato/shared/lib/slugify'
|
|
21
21
|
import { useConfirmDialog } from '../confirm-dialog'
|
|
@@ -35,16 +35,6 @@ import {
|
|
|
35
35
|
type FieldsetGroup = { code: string; title?: string; hint?: string }
|
|
36
36
|
type FieldsetConfig = { code: string; label: string; icon?: string; description?: string; groups?: FieldsetGroup[] }
|
|
37
37
|
|
|
38
|
-
function formatFallback(template: string, params?: Record<string, string | number>) {
|
|
39
|
-
if (!params) return template
|
|
40
|
-
return template.replace(/\{\{(\w+)\}\}|\{(\w+)\}/g, (match, doubleKey, singleKey) => {
|
|
41
|
-
const key = doubleKey ?? singleKey
|
|
42
|
-
if (!key) return match
|
|
43
|
-
const value = params[key]
|
|
44
|
-
return value === undefined ? match : String(value)
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
38
|
export type FieldDefinition = {
|
|
49
39
|
key: string
|
|
50
40
|
kind: string
|
|
@@ -78,7 +68,7 @@ export type FieldDefinitionsEditorProps = {
|
|
|
78
68
|
listProps?: React.HTMLAttributes<HTMLDivElement>
|
|
79
69
|
singleFieldsetPerRecord?: boolean
|
|
80
70
|
onSingleFieldsetPerRecordChange?: (value: boolean) => void
|
|
81
|
-
translate?:
|
|
71
|
+
translate?: (key: string, fallback: string) => string
|
|
82
72
|
}
|
|
83
73
|
|
|
84
74
|
const DEFAULT_VALUE_NONE = '__open_mercato_no_default__'
|
|
@@ -190,13 +180,11 @@ export function FieldDefinitionsEditor({
|
|
|
190
180
|
const dragIndex = React.useRef<number | null>(null)
|
|
191
181
|
const hasFieldsets = fieldsets.length > 0
|
|
192
182
|
const contextT = useOptionalT()
|
|
193
|
-
const t = React.useCallback
|
|
194
|
-
(key
|
|
195
|
-
if (translate) return translate(key,
|
|
196
|
-
if (contextT) return contextT(key,
|
|
197
|
-
return
|
|
198
|
-
? formatFallback(fallbackOrParams, params)
|
|
199
|
-
: key
|
|
183
|
+
const t = React.useCallback(
|
|
184
|
+
(key: string, fallback: string) => {
|
|
185
|
+
if (translate) return translate(key, fallback)
|
|
186
|
+
if (contextT) return contextT(key, fallback)
|
|
187
|
+
return fallback
|
|
200
188
|
},
|
|
201
189
|
[translate, contextT],
|
|
202
190
|
)
|
|
@@ -276,9 +264,7 @@ export function FieldDefinitionsEditor({
|
|
|
276
264
|
if (!onFieldsetsChange) return
|
|
277
265
|
if (!resolvedActiveFieldset) return
|
|
278
266
|
const confirmed = await confirm({
|
|
279
|
-
title: t('entities.customFields.editor.deleteFieldsetTitle', 'Delete fieldset "{code}"?',
|
|
280
|
-
code: resolvedActiveFieldset,
|
|
281
|
-
}),
|
|
267
|
+
title: t('entities.customFields.editor.deleteFieldsetTitle', 'Delete fieldset "{code}"?').replace('{code}', resolvedActiveFieldset),
|
|
282
268
|
text: t('entities.customFields.editor.deleteFieldsetText', 'This will move its fields to Unassigned.'),
|
|
283
269
|
variant: 'destructive',
|
|
284
270
|
})
|
|
@@ -555,7 +541,7 @@ type FieldDefinitionCardProps = {
|
|
|
555
541
|
onRegisterGroup?: (fieldsetCode: string, group: FieldsetGroup) => void
|
|
556
542
|
onRemoveGroup?: (fieldsetCode: string, groupCode: string) => void
|
|
557
543
|
onTranslate?: () => void
|
|
558
|
-
translate?:
|
|
544
|
+
translate?: (key: string, fallback: string) => string
|
|
559
545
|
}
|
|
560
546
|
|
|
561
547
|
const FieldDefinitionCard = React.memo(function FieldDefinitionCard({
|
|
@@ -587,15 +573,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard({
|
|
|
587
573
|
() => (typeof local.configJson?.fieldset === 'string' ? local.configJson.fieldset : ''),
|
|
588
574
|
[local.configJson?.fieldset],
|
|
589
575
|
)
|
|
590
|
-
const t = React.useCallback
|
|
591
|
-
(key, fallbackOrParams, params) => {
|
|
592
|
-
if (translate) return translate(key, fallbackOrParams, params)
|
|
593
|
-
return typeof fallbackOrParams === 'string'
|
|
594
|
-
? formatFallback(fallbackOrParams, params)
|
|
595
|
-
: key
|
|
596
|
-
},
|
|
597
|
-
[translate],
|
|
598
|
-
)
|
|
576
|
+
const t = React.useCallback((key: string, fallback: string) => (translate ? translate(key, fallback) : fallback), [translate])
|
|
599
577
|
React.useEffect(() => {
|
|
600
578
|
localRef.current = definition
|
|
601
579
|
setLocal(definition)
|
|
@@ -1115,29 +1093,23 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard({
|
|
|
1115
1093
|
<SelectValue />
|
|
1116
1094
|
</SelectTrigger>
|
|
1117
1095
|
<SelectContent>
|
|
1118
|
-
<SelectItem value="required">
|
|
1119
|
-
<SelectItem value="date">
|
|
1120
|
-
<SelectItem value="integer">
|
|
1121
|
-
<SelectItem value="float">
|
|
1122
|
-
<SelectItem value="lt">
|
|
1123
|
-
<SelectItem value="lte">
|
|
1124
|
-
<SelectItem value="gt">
|
|
1125
|
-
<SelectItem value="gte">
|
|
1126
|
-
<SelectItem value="eq">
|
|
1127
|
-
<SelectItem value="ne">
|
|
1128
|
-
<SelectItem value="regex">
|
|
1096
|
+
<SelectItem value="required">required</SelectItem>
|
|
1097
|
+
<SelectItem value="date">date</SelectItem>
|
|
1098
|
+
<SelectItem value="integer">integer</SelectItem>
|
|
1099
|
+
<SelectItem value="float">float</SelectItem>
|
|
1100
|
+
<SelectItem value="lt">lt</SelectItem>
|
|
1101
|
+
<SelectItem value="lte">lte</SelectItem>
|
|
1102
|
+
<SelectItem value="gt">gt</SelectItem>
|
|
1103
|
+
<SelectItem value="gte">gte</SelectItem>
|
|
1104
|
+
<SelectItem value="eq">eq</SelectItem>
|
|
1105
|
+
<SelectItem value="ne">ne</SelectItem>
|
|
1106
|
+
<SelectItem value="regex">regex</SelectItem>
|
|
1129
1107
|
</SelectContent>
|
|
1130
1108
|
</Select>
|
|
1131
1109
|
</div>
|
|
1132
1110
|
<div className="md:col-span-4">
|
|
1133
1111
|
<Input
|
|
1134
|
-
placeholder={
|
|
1135
|
-
rule?.rule === 'regex'
|
|
1136
|
-
? t('entities.customFields.editor.rulePatternPlaceholder', 'Pattern (e.g. ^[a-z]+$)')
|
|
1137
|
-
: (['lt','lte','gt','gte'].includes(rule?.rule)
|
|
1138
|
-
? t('entities.customFields.editor.ruleNumberPlaceholder', 'Number')
|
|
1139
|
-
: t('entities.customFields.editor.noParameterPlaceholder', '—'))
|
|
1140
|
-
}
|
|
1112
|
+
placeholder={rule?.rule === 'regex' ? t('entities.customFields.editor.rulePatternPlaceholder', 'Pattern (e.g. ^[a-z]+$)') : (['lt','lte','gt','gte'].includes(rule?.rule) ? t('entities.customFields.editor.ruleNumberPlaceholder', 'Number') : '—')}
|
|
1141
1113
|
value={rule?.param ?? ''}
|
|
1142
1114
|
onChange={(event) => {
|
|
1143
1115
|
const value = ['lt','lte','gt','gte'].includes(rule?.rule) ? Number(event.target.value) : event.target.value
|
|
@@ -1454,7 +1426,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard({
|
|
|
1454
1426
|
size="xs"
|
|
1455
1427
|
className="text-muted-foreground hover:text-foreground"
|
|
1456
1428
|
onClick={() => handleEditGroupEntry(group)}
|
|
1457
|
-
aria-label={t('entities.customFields.editor.editGroupAria', 'Edit {code}'
|
|
1429
|
+
aria-label={t('entities.customFields.editor.editGroupAria', 'Edit {code}').replace('{code}', group.code)}
|
|
1458
1430
|
>
|
|
1459
1431
|
<Pencil className="h-4 w-4" />
|
|
1460
1432
|
</IconButton>
|
|
@@ -1463,7 +1435,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard({
|
|
|
1463
1435
|
size="xs"
|
|
1464
1436
|
className="text-destructive hover:text-destructive/80"
|
|
1465
1437
|
onClick={() => handleRemoveGroupEntry(group.code)}
|
|
1466
|
-
aria-label={t('entities.customFields.editor.deleteGroupAria', 'Delete {code}'
|
|
1438
|
+
aria-label={t('entities.customFields.editor.deleteGroupAria', 'Delete {code}').replace('{code}', group.code)}
|
|
1467
1439
|
>
|
|
1468
1440
|
<Trash2 className="h-4 w-4" />
|
|
1469
1441
|
</IconButton>
|
|
@@ -413,10 +413,6 @@ export function useMessageCompose({
|
|
|
413
413
|
const params = new URLSearchParams()
|
|
414
414
|
params.set('page', '1')
|
|
415
415
|
params.set('pageSize', '100')
|
|
416
|
-
// Scope suggestions to the composer's active organization: a message is stamped with
|
|
417
|
-
// that org and its detail endpoint denies cross-org recipients, so a recipient from
|
|
418
|
-
// another org could never open what they were sent.
|
|
419
|
-
params.set('scopeToActiveOrganization', '1')
|
|
420
416
|
// Recipient lookup is filtered in TagsInput because incremental auth user search is unreliable.
|
|
421
417
|
|
|
422
418
|
const call = await apiCall<{ items?: UserListItem[] }>(
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jest-environment jsdom
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as React from 'react'
|
|
6
|
-
import { renderHook } from '@testing-library/react'
|
|
7
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
8
|
-
import { I18nProvider } from '@open-mercato/shared/lib/i18n/context'
|
|
9
|
-
import { useMessageCompose } from '../useMessageCompose'
|
|
10
|
-
import { apiCall } from '../../utils/apiCall'
|
|
11
|
-
|
|
12
|
-
jest.mock('../../utils/apiCall', () => ({
|
|
13
|
-
apiCall: jest.fn(),
|
|
14
|
-
}))
|
|
15
|
-
|
|
16
|
-
jest.mock('../../FlashMessages', () => ({
|
|
17
|
-
flash: jest.fn(),
|
|
18
|
-
}))
|
|
19
|
-
|
|
20
|
-
function createWrapper() {
|
|
21
|
-
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } })
|
|
22
|
-
return function Wrapper({ children }: { children: React.ReactNode }) {
|
|
23
|
-
return (
|
|
24
|
-
<QueryClientProvider client={queryClient}>
|
|
25
|
-
{/* @ts-expect-error shared provider accepts a loose dict shape */}
|
|
26
|
-
<I18nProvider locale="en" dict={{}}>
|
|
27
|
-
{children}
|
|
28
|
-
</I18nProvider>
|
|
29
|
-
</QueryClientProvider>
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
describe('useMessageCompose recipient suggestions', () => {
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
jest.resetAllMocks()
|
|
37
|
-
;(apiCall as jest.Mock).mockResolvedValue({
|
|
38
|
-
ok: true,
|
|
39
|
-
status: 200,
|
|
40
|
-
result: { items: [] },
|
|
41
|
-
response: { status: 200 },
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('scopes recipient suggestions to the composer active organization', async () => {
|
|
46
|
-
const { result } = renderHook(() => useMessageCompose({ variant: 'compose' }), {
|
|
47
|
-
wrapper: createWrapper(),
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
await result.current.loadRecipientSuggestions()
|
|
51
|
-
|
|
52
|
-
const authUsersCall = (apiCall as jest.Mock).mock.calls.find(
|
|
53
|
-
([url]) => typeof url === 'string' && url.startsWith('/api/auth/users'),
|
|
54
|
-
)
|
|
55
|
-
expect(authUsersCall).toBeDefined()
|
|
56
|
-
|
|
57
|
-
const requestedUrl = new URL(`http://localhost${authUsersCall[0]}`)
|
|
58
|
-
expect(requestedUrl.searchParams.get('scopeToActiveOrganization')).toBe('1')
|
|
59
|
-
})
|
|
60
|
-
})
|