@open-mercato/ui 0.6.7-develop.6605.1.761dd4c810 → 0.6.7-develop.6621.1.cdbe9dee3d

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.
@@ -818,7 +818,8 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard2({
818
818
  /* @__PURE__ */ jsxs(SelectContent, { children: [
819
819
  /* @__PURE__ */ jsx(SelectItem, { value: "markdown", children: t("entities.customFields.editor.editorMarkdown", "Markdown (UIW)") }),
820
820
  /* @__PURE__ */ jsx(SelectItem, { value: "simpleMarkdown", children: t("entities.customFields.editor.editorSimpleMarkdown", "Simple Markdown") }),
821
- /* @__PURE__ */ jsx(SelectItem, { value: "htmlRichText", children: t("entities.customFields.editor.editorHtmlRichText", "HTML Rich Text") })
821
+ /* @__PURE__ */ jsx(SelectItem, { value: "htmlRichText", children: t("entities.customFields.editor.editorHtmlRichText", "HTML Rich Text") }),
822
+ /* @__PURE__ */ jsx(SelectItem, { value: "plain", children: t("entities.customFields.editor.editorPlain", "Plain textarea") })
822
823
  ] })
823
824
  ]
824
825
  }
@@ -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, 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 <SelectItem value=\"plain\">{t('entities.customFields.editor.editorPlain', 'Plain textarea')}</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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",
6
6
  "names": ["code", "FieldDefinitionCard", "nextConfig"]
7
7
  }
@@ -66,6 +66,9 @@ function buildFormFieldFromCustomFieldDef(def, opts) {
66
66
  case "datetime":
67
67
  return { id, label, type: "datetime", ...baseProps };
68
68
  case "multiline": {
69
+ if (def.editor === "plain") {
70
+ return { id, label, type: "textarea", ...baseProps };
71
+ }
69
72
  let editor = "html";
70
73
  if (def.editor === "simpleMarkdown") editor = "simple";
71
74
  else if (def.editor === "htmlRichText") editor = "html";
@@ -145,6 +148,9 @@ function buildFormFieldFromCustomFieldDef(def, opts) {
145
148
  return base;
146
149
  }
147
150
  if (def.kind === "text" && typeof def.editor === "string" && def.editor) {
151
+ if (def.editor === "plain") {
152
+ return { id, label, type: "textarea", ...baseProps };
153
+ }
148
154
  let editor = "html";
149
155
  if (def.editor === "simpleMarkdown") editor = "simple";
150
156
  else if (def.editor === "htmlRichText") editor = "html";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/backend/utils/customFieldForms.ts"],
4
- "sourcesContent": ["import type { CrudField } from '../CrudForm'\nimport type {\n CustomFieldDefDto,\n CustomFieldDefinitionsPayload,\n} from './customFieldDefs'\nimport {\n filterCustomFieldDefs,\n fetchCustomFieldDefs,\n fetchCustomFieldDefinitionsPayload,\n} from './customFieldDefs'\nimport { FieldRegistry, loadGeneratedFieldRegistrations } from '../fields/registry'\nimport { apiCall } from './apiCall'\nimport { normalizeCustomFieldOptions } from '@open-mercato/shared/modules/entities/options'\nimport { CURRENCY_OPTIONS_URL } from '@open-mercato/shared/modules/entities/kinds'\n\nlet registryReady: Promise<void> | null = null\n\nasync function ensureFieldRegistryReady() {\n if (!registryReady) {\n registryReady = loadGeneratedFieldRegistrations().catch((err) => {\n registryReady = null\n throw err\n })\n }\n await registryReady\n}\n\nfunction buildOptionsUrl(base: string, query?: string): string {\n if (!query) return base\n try {\n const isAbsolute = /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(base)\n const origin = typeof window !== 'undefined' ? window.location.origin : 'http://localhost'\n const url = isAbsolute ? new URL(base) : new URL(base, origin)\n if (!url.searchParams.has('query')) url.searchParams.append('query', query)\n if (!url.searchParams.has('q')) url.searchParams.append('q', query)\n if (isAbsolute) return url.toString()\n return `${url.pathname}${url.search}`\n } catch {\n const sep = base.includes('?') ? '&' : '?'\n if (base.includes('query=')) return `${base}${sep}q=${encodeURIComponent(query)}`\n return `${base}${sep}query=${encodeURIComponent(query)}`\n }\n}\n\ntype OptionsResponse = { items?: unknown[] }\n\nasync function loadRemoteOptions(url: string): Promise<Array<{ value: string; label: string }>> {\n try {\n const call = await apiCall<OptionsResponse>(url, undefined, { fallback: { items: [] } })\n if (!call.ok) return []\n const payload = call.result ?? { items: [] }\n const items = Array.isArray(payload?.items) ? payload.items : []\n return items.map((it: any) => ({\n value: String(it?.value ?? it),\n label: String(it?.label ?? it?.value ?? it),\n }))\n } catch {\n return []\n }\n}\n\nexport function buildFormFieldFromCustomFieldDef(\n def: CustomFieldDefDto,\n opts?: { bareIds?: boolean }\n): CrudField | null {\n const id = opts?.bareIds ? def.key : `cf_${def.key}`\n const label = def.label || def.key\n const required = Array.isArray((def as any).validation)\n ? ((def as any).validation as any[]).some((rule) => rule && rule.rule === 'required')\n : false\n const baseProps = {\n description: def.description,\n required,\n ...(def.defaultValue !== undefined && def.defaultValue !== null ? { defaultValue: def.defaultValue } : {}),\n }\n\n switch (def.kind) {\n case 'boolean':\n return { id, label, type: 'checkbox', ...baseProps }\n case 'integer':\n case 'float':\n return { id, label, type: 'number', ...baseProps }\n case 'date':\n return { id, label, type: 'datepicker', ...baseProps }\n case 'datetime':\n return { id, label, type: 'datetime', ...baseProps }\n case 'multiline': {\n let editor: 'simple' | 'uiw' | 'html' = 'html'\n if (def.editor === 'simpleMarkdown') editor = 'simple'\n else if (def.editor === 'htmlRichText') editor = 'html'\n return { id, label, type: 'richtext', ...baseProps, editor }\n }\n case 'select':\n case 'currency':\n case 'relation':\n return {\n id,\n label,\n type: 'select',\n ...baseProps,\n options: normalizeCustomFieldOptions(def.options || []).map((option) => ({\n value: option.value,\n label: option.label,\n })),\n multiple: !!def.multi,\n ...(def.kind === 'currency'\n ? {\n loadOptions: async (query?: string) => {\n const url = buildOptionsUrl(CURRENCY_OPTIONS_URL, query)\n return loadRemoteOptions(url)\n },\n }\n : def.optionsUrl\n ? {\n loadOptions: async (query?: string) => {\n const url = buildOptionsUrl(def.optionsUrl!, query)\n return loadRemoteOptions(url)\n },\n }\n : {}),\n ...(def.multi && def.input === 'listbox' ? ({ listbox: true } as any) : {}),\n }\n case 'dictionary': {\n if (!def.multi) {\n const input = FieldRegistry.getInput(def.kind)\n if (input) {\n return {\n id,\n label,\n type: 'custom',\n ...baseProps,\n component: (props) => input({ ...props, def }),\n }\n }\n return { id, label, type: 'text', ...baseProps }\n }\n const optionsUrl = def.optionsUrl || (def.dictionaryId ? `/api/dictionaries/${def.dictionaryId}/entries` : undefined)\n return {\n id,\n label,\n type: 'select',\n description: def.description,\n required,\n options: [],\n multiple: true,\n listbox: true,\n ...(optionsUrl\n ? {\n loadOptions: async (query?: string) => {\n const url = buildOptionsUrl(optionsUrl, query)\n return loadRemoteOptions(url)\n },\n }\n : {}),\n }\n }\n default: {\n if (def.kind === 'text' && def.multi) {\n const base: any = { id, label, type: 'tags', ...baseProps }\n const resolvedOptions = normalizeCustomFieldOptions(def.options || [])\n if (resolvedOptions.length > 0) {\n base.options = resolvedOptions.map((option) => ({ value: option.value, label: option.label }))\n }\n if (def.optionsUrl) {\n base.loadOptions = async (query?: string) => {\n const url = buildOptionsUrl(def.optionsUrl!, query)\n return loadRemoteOptions(url)\n }\n }\n return base\n }\n if (def.kind === 'text' && typeof def.editor === 'string' && def.editor) {\n let editor: 'simple' | 'uiw' | 'html' = 'html'\n if (def.editor === 'simpleMarkdown') editor = 'simple'\n else if (def.editor === 'htmlRichText') editor = 'html'\n return { id, label, type: 'richtext', ...baseProps, editor }\n }\n const input = FieldRegistry.getInput(def.kind)\n if (input) {\n return {\n id,\n label,\n type: 'custom',\n ...baseProps,\n component: (props) => input({ ...props, def }),\n }\n }\n return { id, label, type: 'text', ...baseProps }\n }\n }\n}\n\nexport function buildFormFieldsFromCustomFields(\n defs: CustomFieldDefDto[],\n opts?: { bareIds?: boolean }\n): CrudField[] {\n const fields: CrudField[] = []\n const visible = filterCustomFieldDefs(defs, 'form')\n const seenKeys = new Set<string>()\n for (const def of visible) {\n const keyLower = String(def.key).toLowerCase()\n if (seenKeys.has(keyLower)) continue\n seenKeys.add(keyLower)\n const field = buildFormFieldFromCustomFieldDef(def, opts)\n if (field) fields.push(field)\n }\n return fields\n}\n\nexport async function fetchCustomFieldFormStructure(\n entityIds: string | string[],\n fetchImpl?: typeof fetch,\n options?: { bareIds?: boolean },\n): Promise<{ fields: CrudField[]; definitions: CustomFieldDefDto[]; metadata: CustomFieldDefinitionsPayload }> {\n await ensureFieldRegistryReady()\n const metadata = await fetchCustomFieldDefinitionsPayload(entityIds, fetchImpl)\n const definitions = Array.isArray(metadata.items) ? metadata.items : []\n const fields = buildFormFieldsFromCustomFields(definitions, options)\n return { fields, definitions, metadata }\n}\n\nexport async function fetchCustomFieldFormFields(\n entityIds: string | string[],\n fetchImpl?: typeof fetch,\n options?: { bareIds?: boolean },\n): Promise<CrudField[]> {\n const { fields } = await fetchCustomFieldFormStructure(entityIds, fetchImpl, options)\n return fields\n}\n\nexport async function fetchCustomFieldFormFieldsWithDefinitions(\n entityIds: string | string[],\n fetchImpl?: typeof fetch,\n options?: { bareIds?: boolean },\n): Promise<{ fields: CrudField[]; definitions: CustomFieldDefDto[]; metadata: CustomFieldDefinitionsPayload }> {\n return fetchCustomFieldFormStructure(entityIds, fetchImpl, options)\n}\n"],
5
- "mappings": "AAKA;AAAA,EACE;AAAA,EAEA;AAAA,OACK;AACP,SAAS,eAAe,uCAAuC;AAC/D,SAAS,eAAe;AACxB,SAAS,mCAAmC;AAC5C,SAAS,4BAA4B;AAErC,IAAI,gBAAsC;AAE1C,eAAe,2BAA2B;AACxC,MAAI,CAAC,eAAe;AAClB,oBAAgB,gCAAgC,EAAE,MAAM,CAAC,QAAQ;AAC/D,sBAAgB;AAChB,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,QAAM;AACR;AAEA,SAAS,gBAAgB,MAAc,OAAwB;AAC7D,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACF,UAAM,aAAa,8BAA8B,KAAK,IAAI;AAC1D,UAAM,SAAS,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AACxE,UAAM,MAAM,aAAa,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM,MAAM;AAC7D,QAAI,CAAC,IAAI,aAAa,IAAI,OAAO,EAAG,KAAI,aAAa,OAAO,SAAS,KAAK;AAC1E,QAAI,CAAC,IAAI,aAAa,IAAI,GAAG,EAAG,KAAI,aAAa,OAAO,KAAK,KAAK;AAClE,QAAI,WAAY,QAAO,IAAI,SAAS;AACpC,WAAO,GAAG,IAAI,QAAQ,GAAG,IAAI,MAAM;AAAA,EACrC,QAAQ;AACN,UAAM,MAAM,KAAK,SAAS,GAAG,IAAI,MAAM;AACvC,QAAI,KAAK,SAAS,QAAQ,EAAG,QAAO,GAAG,IAAI,GAAG,GAAG,KAAK,mBAAmB,KAAK,CAAC;AAC/E,WAAO,GAAG,IAAI,GAAG,GAAG,SAAS,mBAAmB,KAAK,CAAC;AAAA,EACxD;AACF;AAIA,eAAe,kBAAkB,KAA+D;AAC9F,MAAI;AACF,UAAM,OAAO,MAAM,QAAyB,KAAK,QAAW,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;AACvF,QAAI,CAAC,KAAK,GAAI,QAAO,CAAC;AACtB,UAAM,UAAU,KAAK,UAAU,EAAE,OAAO,CAAC,EAAE;AAC3C,UAAM,QAAQ,MAAM,QAAQ,SAAS,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC/D,WAAO,MAAM,IAAI,CAAC,QAAa;AAAA,MAC7B,OAAO,OAAO,IAAI,SAAS,EAAE;AAAA,MAC7B,OAAO,OAAO,IAAI,SAAS,IAAI,SAAS,EAAE;AAAA,IAC5C,EAAE;AAAA,EACJ,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,iCACd,KACA,MACkB;AAClB,QAAM,KAAK,MAAM,UAAU,IAAI,MAAM,MAAM,IAAI,GAAG;AAClD,QAAM,QAAQ,IAAI,SAAS,IAAI;AAC/B,QAAM,WAAW,MAAM,QAAS,IAAY,UAAU,IAChD,IAAY,WAAqB,KAAK,CAAC,SAAS,QAAQ,KAAK,SAAS,UAAU,IAClF;AACJ,QAAM,YAAY;AAAA,IAChB,aAAa,IAAI;AAAA,IACjB;AAAA,IACA,GAAI,IAAI,iBAAiB,UAAa,IAAI,iBAAiB,OAAO,EAAE,cAAc,IAAI,aAAa,IAAI,CAAC;AAAA,EAC1G;AAEA,UAAQ,IAAI,MAAM;AAAA,IAChB,KAAK;AACH,aAAO,EAAE,IAAI,OAAO,MAAM,YAAY,GAAG,UAAU;AAAA,IACrD,KAAK;AAAA,IACL,KAAK;AACH,aAAO,EAAE,IAAI,OAAO,MAAM,UAAU,GAAG,UAAU;AAAA,IACnD,KAAK;AACH,aAAO,EAAE,IAAI,OAAO,MAAM,cAAc,GAAG,UAAU;AAAA,IACvD,KAAK;AACH,aAAO,EAAE,IAAI,OAAO,MAAM,YAAY,GAAG,UAAU;AAAA,IACrD,KAAK,aAAa;AAChB,UAAI,SAAoC;AACxC,UAAI,IAAI,WAAW,iBAAkB,UAAS;AAAA,eACrC,IAAI,WAAW,eAAgB,UAAS;AACjD,aAAO,EAAE,IAAI,OAAO,MAAM,YAAY,GAAG,WAAW,OAAO;AAAA,IAC7D;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,GAAG;AAAA,QACH,SAAS,4BAA4B,IAAI,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY;AAAA,UACvE,OAAO,OAAO;AAAA,UACd,OAAO,OAAO;AAAA,QAChB,EAAE;AAAA,QACF,UAAU,CAAC,CAAC,IAAI;AAAA,QAChB,GAAI,IAAI,SAAS,aACb;AAAA,UACE,aAAa,OAAO,UAAmB;AACrC,kBAAM,MAAM,gBAAgB,sBAAsB,KAAK;AACvD,mBAAO,kBAAkB,GAAG;AAAA,UAC9B;AAAA,QACF,IACA,IAAI,aACJ;AAAA,UACE,aAAa,OAAO,UAAmB;AACrC,kBAAM,MAAM,gBAAgB,IAAI,YAAa,KAAK;AAClD,mBAAO,kBAAkB,GAAG;AAAA,UAC9B;AAAA,QACF,IACA,CAAC;AAAA,QACL,GAAI,IAAI,SAAS,IAAI,UAAU,YAAa,EAAE,SAAS,KAAK,IAAY,CAAC;AAAA,MAC3E;AAAA,IACF,KAAK,cAAc;AACjB,UAAI,CAAC,IAAI,OAAO;AACd,cAAM,QAAQ,cAAc,SAAS,IAAI,IAAI;AAC7C,YAAI,OAAO;AACT,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,GAAG;AAAA,YACH,WAAW,CAAC,UAAU,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC;AAAA,UAC/C;AAAA,QACF;AACA,eAAO,EAAE,IAAI,OAAO,MAAM,QAAQ,GAAG,UAAU;AAAA,MACjD;AACA,YAAM,aAAa,IAAI,eAAe,IAAI,eAAe,qBAAqB,IAAI,YAAY,aAAa;AAC3G,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,aAAa,IAAI;AAAA,QACjB;AAAA,QACA,SAAS,CAAC;AAAA,QACV,UAAU;AAAA,QACV,SAAS;AAAA,QACT,GAAI,aACA;AAAA,UACE,aAAa,OAAO,UAAmB;AACrC,kBAAM,MAAM,gBAAgB,YAAY,KAAK;AAC7C,mBAAO,kBAAkB,GAAG;AAAA,UAC9B;AAAA,QACF,IACA,CAAC;AAAA,MACP;AAAA,IACF;AAAA,IACA,SAAS;AACP,UAAI,IAAI,SAAS,UAAU,IAAI,OAAO;AACpC,cAAM,OAAY,EAAE,IAAI,OAAO,MAAM,QAAQ,GAAG,UAAU;AAC1D,cAAM,kBAAkB,4BAA4B,IAAI,WAAW,CAAC,CAAC;AACrE,YAAI,gBAAgB,SAAS,GAAG;AAC9B,eAAK,UAAU,gBAAgB,IAAI,CAAC,YAAY,EAAE,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,EAAE;AAAA,QAC/F;AACA,YAAI,IAAI,YAAY;AAClB,eAAK,cAAc,OAAO,UAAmB;AAC3C,kBAAM,MAAM,gBAAgB,IAAI,YAAa,KAAK;AAClD,mBAAO,kBAAkB,GAAG;AAAA,UAC9B;AAAA,QACF;AACA,eAAO;AAAA,MACT;AACA,UAAI,IAAI,SAAS,UAAU,OAAO,IAAI,WAAW,YAAY,IAAI,QAAQ;AACvE,YAAI,SAAoC;AACxC,YAAI,IAAI,WAAW,iBAAkB,UAAS;AAAA,iBACrC,IAAI,WAAW,eAAgB,UAAS;AACjD,eAAO,EAAE,IAAI,OAAO,MAAM,YAAY,GAAG,WAAW,OAAO;AAAA,MAC7D;AACA,YAAM,QAAQ,cAAc,SAAS,IAAI,IAAI;AAC7C,UAAI,OAAO;AACT,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,GAAG;AAAA,UACH,WAAW,CAAC,UAAU,MAAM,EAAE,GAAG,OAAO,IAAI,CAAC;AAAA,QAC/C;AAAA,MACF;AACA,aAAO,EAAE,IAAI,OAAO,MAAM,QAAQ,GAAG,UAAU;AAAA,IACjD;AAAA,EACF;AACF;AAEO,SAAS,gCACd,MACA,MACa;AACb,QAAM,SAAsB,CAAC;AAC7B,QAAM,UAAU,sBAAsB,MAAM,MAAM;AAClD,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,OAAO,SAAS;AACzB,UAAM,WAAW,OAAO,IAAI,GAAG,EAAE,YAAY;AAC7C,QAAI,SAAS,IAAI,QAAQ,EAAG;AAC5B,aAAS,IAAI,QAAQ;AACrB,UAAM,QAAQ,iCAAiC,KAAK,IAAI;AACxD,QAAI,MAAO,QAAO,KAAK,KAAK;AAAA,EAC9B;AACA,SAAO;AACT;AAEA,eAAsB,8BACpB,WACA,WACA,SAC6G;AAC7G,QAAM,yBAAyB;AAC/B,QAAM,WAAW,MAAM,mCAAmC,WAAW,SAAS;AAC9E,QAAM,cAAc,MAAM,QAAQ,SAAS,KAAK,IAAI,SAAS,QAAQ,CAAC;AACtE,QAAM,SAAS,gCAAgC,aAAa,OAAO;AACnE,SAAO,EAAE,QAAQ,aAAa,SAAS;AACzC;AAEA,eAAsB,2BACpB,WACA,WACA,SACsB;AACtB,QAAM,EAAE,OAAO,IAAI,MAAM,8BAA8B,WAAW,WAAW,OAAO;AACpF,SAAO;AACT;AAEA,eAAsB,0CACpB,WACA,WACA,SAC6G;AAC7G,SAAO,8BAA8B,WAAW,WAAW,OAAO;AACpE;",
4
+ "sourcesContent": ["import type { CrudField } from '../CrudForm'\nimport type {\n CustomFieldDefDto,\n CustomFieldDefinitionsPayload,\n} from './customFieldDefs'\nimport {\n filterCustomFieldDefs,\n fetchCustomFieldDefs,\n fetchCustomFieldDefinitionsPayload,\n} from './customFieldDefs'\nimport { FieldRegistry, loadGeneratedFieldRegistrations } from '../fields/registry'\nimport { apiCall } from './apiCall'\nimport { normalizeCustomFieldOptions } from '@open-mercato/shared/modules/entities/options'\nimport { CURRENCY_OPTIONS_URL } from '@open-mercato/shared/modules/entities/kinds'\n\nlet registryReady: Promise<void> | null = null\n\nasync function ensureFieldRegistryReady() {\n if (!registryReady) {\n registryReady = loadGeneratedFieldRegistrations().catch((err) => {\n registryReady = null\n throw err\n })\n }\n await registryReady\n}\n\nfunction buildOptionsUrl(base: string, query?: string): string {\n if (!query) return base\n try {\n const isAbsolute = /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(base)\n const origin = typeof window !== 'undefined' ? window.location.origin : 'http://localhost'\n const url = isAbsolute ? new URL(base) : new URL(base, origin)\n if (!url.searchParams.has('query')) url.searchParams.append('query', query)\n if (!url.searchParams.has('q')) url.searchParams.append('q', query)\n if (isAbsolute) return url.toString()\n return `${url.pathname}${url.search}`\n } catch {\n const sep = base.includes('?') ? '&' : '?'\n if (base.includes('query=')) return `${base}${sep}q=${encodeURIComponent(query)}`\n return `${base}${sep}query=${encodeURIComponent(query)}`\n }\n}\n\ntype OptionsResponse = { items?: unknown[] }\n\nasync function loadRemoteOptions(url: string): Promise<Array<{ value: string; label: string }>> {\n try {\n const call = await apiCall<OptionsResponse>(url, undefined, { fallback: { items: [] } })\n if (!call.ok) return []\n const payload = call.result ?? { items: [] }\n const items = Array.isArray(payload?.items) ? payload.items : []\n return items.map((it: any) => ({\n value: String(it?.value ?? it),\n label: String(it?.label ?? it?.value ?? it),\n }))\n } catch {\n return []\n }\n}\n\nexport function buildFormFieldFromCustomFieldDef(\n def: CustomFieldDefDto,\n opts?: { bareIds?: boolean }\n): CrudField | null {\n const id = opts?.bareIds ? def.key : `cf_${def.key}`\n const label = def.label || def.key\n const required = Array.isArray((def as any).validation)\n ? ((def as any).validation as any[]).some((rule) => rule && rule.rule === 'required')\n : false\n const baseProps = {\n description: def.description,\n required,\n ...(def.defaultValue !== undefined && def.defaultValue !== null ? { defaultValue: def.defaultValue } : {}),\n }\n\n switch (def.kind) {\n case 'boolean':\n return { id, label, type: 'checkbox', ...baseProps }\n case 'integer':\n case 'float':\n return { id, label, type: 'number', ...baseProps }\n case 'date':\n return { id, label, type: 'datepicker', ...baseProps }\n case 'datetime':\n return { id, label, type: 'datetime', ...baseProps }\n case 'multiline': {\n if (def.editor === 'plain') {\n return { id, label, type: 'textarea', ...baseProps }\n }\n let editor: 'simple' | 'uiw' | 'html' = 'html'\n if (def.editor === 'simpleMarkdown') editor = 'simple'\n else if (def.editor === 'htmlRichText') editor = 'html'\n return { id, label, type: 'richtext', ...baseProps, editor }\n }\n case 'select':\n case 'currency':\n case 'relation':\n return {\n id,\n label,\n type: 'select',\n ...baseProps,\n options: normalizeCustomFieldOptions(def.options || []).map((option) => ({\n value: option.value,\n label: option.label,\n })),\n multiple: !!def.multi,\n ...(def.kind === 'currency'\n ? {\n loadOptions: async (query?: string) => {\n const url = buildOptionsUrl(CURRENCY_OPTIONS_URL, query)\n return loadRemoteOptions(url)\n },\n }\n : def.optionsUrl\n ? {\n loadOptions: async (query?: string) => {\n const url = buildOptionsUrl(def.optionsUrl!, query)\n return loadRemoteOptions(url)\n },\n }\n : {}),\n ...(def.multi && def.input === 'listbox' ? ({ listbox: true } as any) : {}),\n }\n case 'dictionary': {\n if (!def.multi) {\n const input = FieldRegistry.getInput(def.kind)\n if (input) {\n return {\n id,\n label,\n type: 'custom',\n ...baseProps,\n component: (props) => input({ ...props, def }),\n }\n }\n return { id, label, type: 'text', ...baseProps }\n }\n const optionsUrl = def.optionsUrl || (def.dictionaryId ? `/api/dictionaries/${def.dictionaryId}/entries` : undefined)\n return {\n id,\n label,\n type: 'select',\n description: def.description,\n required,\n options: [],\n multiple: true,\n listbox: true,\n ...(optionsUrl\n ? {\n loadOptions: async (query?: string) => {\n const url = buildOptionsUrl(optionsUrl, query)\n return loadRemoteOptions(url)\n },\n }\n : {}),\n }\n }\n default: {\n if (def.kind === 'text' && def.multi) {\n const base: any = { id, label, type: 'tags', ...baseProps }\n const resolvedOptions = normalizeCustomFieldOptions(def.options || [])\n if (resolvedOptions.length > 0) {\n base.options = resolvedOptions.map((option) => ({ value: option.value, label: option.label }))\n }\n if (def.optionsUrl) {\n base.loadOptions = async (query?: string) => {\n const url = buildOptionsUrl(def.optionsUrl!, query)\n return loadRemoteOptions(url)\n }\n }\n return base\n }\n if (def.kind === 'text' && typeof def.editor === 'string' && def.editor) {\n if (def.editor === 'plain') {\n return { id, label, type: 'textarea', ...baseProps }\n }\n let editor: 'simple' | 'uiw' | 'html' = 'html'\n if (def.editor === 'simpleMarkdown') editor = 'simple'\n else if (def.editor === 'htmlRichText') editor = 'html'\n return { id, label, type: 'richtext', ...baseProps, editor }\n }\n const input = FieldRegistry.getInput(def.kind)\n if (input) {\n return {\n id,\n label,\n type: 'custom',\n ...baseProps,\n component: (props) => input({ ...props, def }),\n }\n }\n return { id, label, type: 'text', ...baseProps }\n }\n }\n}\n\nexport function buildFormFieldsFromCustomFields(\n defs: CustomFieldDefDto[],\n opts?: { bareIds?: boolean }\n): CrudField[] {\n const fields: CrudField[] = []\n const visible = filterCustomFieldDefs(defs, 'form')\n const seenKeys = new Set<string>()\n for (const def of visible) {\n const keyLower = String(def.key).toLowerCase()\n if (seenKeys.has(keyLower)) continue\n seenKeys.add(keyLower)\n const field = buildFormFieldFromCustomFieldDef(def, opts)\n if (field) fields.push(field)\n }\n return fields\n}\n\nexport async function fetchCustomFieldFormStructure(\n entityIds: string | string[],\n fetchImpl?: typeof fetch,\n options?: { bareIds?: boolean },\n): Promise<{ fields: CrudField[]; definitions: CustomFieldDefDto[]; metadata: CustomFieldDefinitionsPayload }> {\n await ensureFieldRegistryReady()\n const metadata = await fetchCustomFieldDefinitionsPayload(entityIds, fetchImpl)\n const definitions = Array.isArray(metadata.items) ? metadata.items : []\n const fields = buildFormFieldsFromCustomFields(definitions, options)\n return { fields, definitions, metadata }\n}\n\nexport async function fetchCustomFieldFormFields(\n entityIds: string | string[],\n fetchImpl?: typeof fetch,\n options?: { bareIds?: boolean },\n): Promise<CrudField[]> {\n const { fields } = await fetchCustomFieldFormStructure(entityIds, fetchImpl, options)\n return fields\n}\n\nexport async function fetchCustomFieldFormFieldsWithDefinitions(\n entityIds: string | string[],\n fetchImpl?: typeof fetch,\n options?: { bareIds?: boolean },\n): Promise<{ fields: CrudField[]; definitions: CustomFieldDefDto[]; metadata: CustomFieldDefinitionsPayload }> {\n return fetchCustomFieldFormStructure(entityIds, fetchImpl, options)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/ui",
3
- "version": "0.6.7-develop.6605.1.761dd4c810",
3
+ "version": "0.6.7-develop.6621.1.cdbe9dee3d",
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.7-develop.6605.1.761dd4c810",
158
+ "@open-mercato/shared": "0.6.7-develop.6621.1.cdbe9dee3d",
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.7-develop.6605.1.761dd4c810",
164
+ "@open-mercato/shared": "0.6.7-develop.6621.1.cdbe9dee3d",
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",
@@ -936,6 +936,7 @@ const FieldDefinitionCard = React.memo(function FieldDefinitionCard({
936
936
  <SelectItem value="markdown">{t('entities.customFields.editor.editorMarkdown', 'Markdown (UIW)')}</SelectItem>
937
937
  <SelectItem value="simpleMarkdown">{t('entities.customFields.editor.editorSimpleMarkdown', 'Simple Markdown')}</SelectItem>
938
938
  <SelectItem value="htmlRichText">{t('entities.customFields.editor.editorHtmlRichText', 'HTML Rich Text')}</SelectItem>
939
+ <SelectItem value="plain">{t('entities.customFields.editor.editorPlain', 'Plain textarea')}</SelectItem>
939
940
  </SelectContent>
940
941
  </Select>
941
942
  </div>
@@ -0,0 +1,29 @@
1
+ import { buildFormFieldFromCustomFieldDef } from '../customFieldForms'
2
+
3
+ /**
4
+ * Guards issue #4371: `kind: 'multiline'` definitions must be able to render
5
+ * a plain <textarea> via `editor: 'plain'` instead of always mapping to the
6
+ * rich-text editor.
7
+ */
8
+ describe('buildFormFieldFromCustomFieldDef multiline mapping', () => {
9
+ it('maps multiline without an editor hint to the html rich-text editor', () => {
10
+ const field = buildFormFieldFromCustomFieldDef({ key: 'notes', kind: 'multiline' })
11
+ expect(field).toMatchObject({ type: 'richtext', editor: 'html' })
12
+ })
13
+
14
+ it('maps editor simpleMarkdown to the simple rich-text editor', () => {
15
+ const field = buildFormFieldFromCustomFieldDef({ key: 'notes', kind: 'multiline', editor: 'simpleMarkdown' })
16
+ expect(field).toMatchObject({ type: 'richtext', editor: 'simple' })
17
+ })
18
+
19
+ it('maps editor plain to a plain textarea', () => {
20
+ const field = buildFormFieldFromCustomFieldDef({ key: 'notes', kind: 'multiline', editor: 'plain' })
21
+ expect(field).toMatchObject({ id: 'cf_notes', type: 'textarea' })
22
+ expect(field).not.toHaveProperty('editor')
23
+ })
24
+
25
+ it('maps text kind with editor plain to a plain textarea as well', () => {
26
+ const field = buildFormFieldFromCustomFieldDef({ key: 'summary', kind: 'text', editor: 'plain' })
27
+ expect(field).toMatchObject({ id: 'cf_summary', type: 'textarea' })
28
+ })
29
+ })
@@ -85,6 +85,9 @@ export function buildFormFieldFromCustomFieldDef(
85
85
  case 'datetime':
86
86
  return { id, label, type: 'datetime', ...baseProps }
87
87
  case 'multiline': {
88
+ if (def.editor === 'plain') {
89
+ return { id, label, type: 'textarea', ...baseProps }
90
+ }
88
91
  let editor: 'simple' | 'uiw' | 'html' = 'html'
89
92
  if (def.editor === 'simpleMarkdown') editor = 'simple'
90
93
  else if (def.editor === 'htmlRichText') editor = 'html'
@@ -170,6 +173,9 @@ export function buildFormFieldFromCustomFieldDef(
170
173
  return base
171
174
  }
172
175
  if (def.kind === 'text' && typeof def.editor === 'string' && def.editor) {
176
+ if (def.editor === 'plain') {
177
+ return { id, label, type: 'textarea', ...baseProps }
178
+ }
173
179
  let editor: 'simple' | 'uiw' | 'html' = 'html'
174
180
  if (def.editor === 'simpleMarkdown') editor = 'simple'
175
181
  else if (def.editor === 'htmlRichText') editor = 'html'