@open-mercato/core 0.5.1-develop.2953.6647bb2c43 → 0.5.1-develop.2964.d5ac4a6ebb

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.
Files changed (226) hide show
  1. package/dist/helpers/integration/salesUi.js +25 -23
  2. package/dist/helpers/integration/salesUi.js.map +2 -2
  3. package/dist/modules/api_docs/frontend/docs/api/Explorer.js +24 -24
  4. package/dist/modules/api_docs/frontend/docs/api/Explorer.js.map +2 -2
  5. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +15 -7
  6. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  7. package/dist/modules/attachments/fields/attachment.js +4 -6
  8. package/dist/modules/attachments/fields/attachment.js.map +2 -2
  9. package/dist/modules/auth/backend/users/create/page.js +26 -26
  10. package/dist/modules/auth/backend/users/create/page.js.map +2 -2
  11. package/dist/modules/business_rules/components/ActionRow.js +36 -25
  12. package/dist/modules/business_rules/components/ActionRow.js.map +2 -2
  13. package/dist/modules/business_rules/components/ConditionGroup.js +14 -5
  14. package/dist/modules/business_rules/components/ConditionGroup.js.map +2 -2
  15. package/dist/modules/business_rules/components/ConditionRow.js +19 -10
  16. package/dist/modules/business_rules/components/ConditionRow.js.map +2 -2
  17. package/dist/modules/business_rules/components/RuleSetMembers.js +16 -10
  18. package/dist/modules/business_rules/components/RuleSetMembers.js.map +2 -2
  19. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +30 -34
  20. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  21. package/dist/modules/catalog/backend/catalog/products/create/page.js +220 -223
  22. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  23. package/dist/modules/catalog/components/PriceKindSettings.js +20 -19
  24. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  25. package/dist/modules/catalog/components/products/ProductUomSection.js +42 -37
  26. package/dist/modules/catalog/components/products/ProductUomSection.js.map +2 -2
  27. package/dist/modules/catalog/components/products/VariantBuilder.js +22 -18
  28. package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
  29. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +18 -26
  30. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  31. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +4 -6
  32. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  33. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +5 -4
  34. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
  35. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +19 -7
  36. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
  37. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +24 -21
  38. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  39. package/dist/modules/customers/components/AddressEditor.js +24 -7
  40. package/dist/modules/customers/components/AddressEditor.js.map +2 -2
  41. package/dist/modules/customers/components/AddressFormatSettings.js +35 -25
  42. package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
  43. package/dist/modules/customers/components/detail/ActivityForm.js +20 -12
  44. package/dist/modules/customers/components/detail/ActivityForm.js.map +2 -2
  45. package/dist/modules/customers/components/detail/AnnualRevenueField.js +2 -2
  46. package/dist/modules/customers/components/detail/AnnualRevenueField.js.map +2 -2
  47. package/dist/modules/customers/components/detail/DealForm.js +19 -14
  48. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  49. package/dist/modules/customers/components/formConfig.js +16 -12
  50. package/dist/modules/customers/components/formConfig.js.map +2 -2
  51. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +3 -2
  52. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
  53. package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js +18 -10
  54. package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js.map +2 -2
  55. package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js +3 -2
  56. package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js.map +2 -2
  57. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js +3 -2
  58. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js.map +2 -2
  59. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +27 -28
  60. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  61. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js +14 -6
  62. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js.map +2 -2
  63. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +14 -6
  64. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +2 -2
  65. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +3 -2
  66. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +2 -2
  67. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +3 -2
  68. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +2 -2
  69. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +17 -8
  70. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
  71. package/dist/modules/data_sync/backend/data-sync/page.js +40 -23
  72. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  73. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +15 -6
  74. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  75. package/dist/modules/dictionaries/components/AppearanceSelector.js +4 -4
  76. package/dist/modules/dictionaries/components/AppearanceSelector.js.map +2 -2
  77. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +4 -5
  78. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
  79. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +22 -14
  80. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
  81. package/dist/modules/dictionaries/fields/dictionary.js +18 -13
  82. package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
  83. package/dist/modules/entities/components/EncryptionManager.js +23 -19
  84. package/dist/modules/entities/components/EncryptionManager.js.map +2 -2
  85. package/dist/modules/feature_toggles/components/formConfig.js +17 -9
  86. package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
  87. package/dist/modules/feature_toggles/components/overrideFormConfig.js +17 -9
  88. package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
  89. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +15 -8
  90. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
  91. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +37 -22
  92. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
  93. package/dist/modules/integrations/backend/integrations/[id]/page.js +22 -17
  94. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  95. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +12 -6
  96. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  97. package/dist/modules/planner/components/AvailabilityRulesEditor.js +19 -12
  98. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  99. package/dist/modules/resources/components/ResourceCrudForm.js +15 -10
  100. package/dist/modules/resources/components/ResourceCrudForm.js.map +3 -3
  101. package/dist/modules/sales/backend/sales/documents/[id]/page.js +15 -18
  102. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  103. package/dist/modules/sales/components/ProviderFieldInput.js +23 -20
  104. package/dist/modules/sales/components/ProviderFieldInput.js.map +2 -2
  105. package/dist/modules/sales/components/ShippingMethodsSettings.js +25 -17
  106. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +3 -3
  107. package/dist/modules/sales/components/channels/ChannelOfferForm.js +35 -42
  108. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  109. package/dist/modules/sales/components/documents/AddressesSection.js +87 -90
  110. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  111. package/dist/modules/sales/components/documents/AdjustmentDialog.js +17 -6
  112. package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +3 -3
  113. package/dist/modules/sales/components/documents/LineItemDialog.js +42 -25
  114. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  115. package/dist/modules/sales/components/documents/SalesDocumentForm.js +96 -87
  116. package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
  117. package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js +20 -11
  118. package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js.map +2 -2
  119. package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js +20 -11
  120. package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js.map +2 -2
  121. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js +36 -22
  122. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js.map +2 -2
  123. package/dist/modules/staff/components/TeamMemberForm.js +14 -9
  124. package/dist/modules/staff/components/TeamMemberForm.js.map +3 -3
  125. package/dist/modules/workflows/backend/tasks/[id]/page.js +42 -21
  126. package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
  127. package/dist/modules/workflows/components/ActivitiesEditor.js +14 -6
  128. package/dist/modules/workflows/components/ActivitiesEditor.js.map +3 -3
  129. package/dist/modules/workflows/components/DefinitionTriggersEditor.js +25 -17
  130. package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +3 -3
  131. package/dist/modules/workflows/components/EdgeEditDialog.js +48 -45
  132. package/dist/modules/workflows/components/EdgeEditDialog.js.map +2 -2
  133. package/dist/modules/workflows/components/NodeEditDialog.js +90 -90
  134. package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
  135. package/dist/modules/workflows/components/StepsEditor.js +14 -6
  136. package/dist/modules/workflows/components/StepsEditor.js.map +3 -3
  137. package/dist/modules/workflows/components/TransitionsEditor.js +31 -26
  138. package/dist/modules/workflows/components/TransitionsEditor.js.map +3 -3
  139. package/dist/modules/workflows/components/fields/ActivityArrayEditor.js +19 -11
  140. package/dist/modules/workflows/components/fields/ActivityArrayEditor.js.map +3 -3
  141. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +12 -14
  142. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
  143. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +24 -16
  144. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +3 -3
  145. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +12 -13
  146. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
  147. package/dist/modules/workflows/components/mobile/MobileTaskForm.js +12 -8
  148. package/dist/modules/workflows/components/mobile/MobileTaskForm.js.map +2 -2
  149. package/dist/modules/workflows/frontend/checkout-demo/page.js +43 -46
  150. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  151. package/package.json +3 -3
  152. package/src/helpers/integration/salesUi.ts +40 -30
  153. package/src/modules/api_docs/frontend/docs/api/Explorer.tsx +25 -19
  154. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +21 -11
  155. package/src/modules/attachments/fields/attachment.tsx +4 -6
  156. package/src/modules/auth/backend/users/create/page.tsx +16 -20
  157. package/src/modules/business_rules/components/ActionRow.tsx +51 -32
  158. package/src/modules/business_rules/components/ConditionGroup.tsx +20 -9
  159. package/src/modules/business_rules/components/ConditionRow.tsx +24 -15
  160. package/src/modules/business_rules/components/RuleSetMembers.tsx +23 -13
  161. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +47 -53
  162. package/src/modules/catalog/backend/catalog/products/create/page.tsx +84 -87
  163. package/src/modules/catalog/components/PriceKindSettings.tsx +9 -9
  164. package/src/modules/catalog/components/products/ProductUomSection.tsx +85 -83
  165. package/src/modules/catalog/components/products/VariantBuilder.tsx +49 -33
  166. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +12 -27
  167. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +4 -6
  168. package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +5 -4
  169. package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +28 -15
  170. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +37 -26
  171. package/src/modules/customers/components/AddressEditor.tsx +30 -16
  172. package/src/modules/customers/components/AddressFormatSettings.tsx +25 -19
  173. package/src/modules/customers/components/detail/ActivityForm.tsx +35 -23
  174. package/src/modules/customers/components/detail/AnnualRevenueField.tsx +2 -2
  175. package/src/modules/customers/components/detail/DealForm.tsx +33 -20
  176. package/src/modules/customers/components/formConfig.tsx +25 -17
  177. package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +3 -2
  178. package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +21 -11
  179. package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +3 -2
  180. package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +3 -2
  181. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +17 -22
  182. package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +17 -7
  183. package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +20 -10
  184. package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +3 -2
  185. package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +3 -2
  186. package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +20 -9
  187. package/src/modules/data_sync/backend/data-sync/page.tsx +64 -38
  188. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +18 -7
  189. package/src/modules/dictionaries/components/AppearanceSelector.tsx +4 -4
  190. package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +3 -4
  191. package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +27 -21
  192. package/src/modules/dictionaries/fields/dictionary.tsx +36 -23
  193. package/src/modules/entities/components/EncryptionManager.tsx +49 -33
  194. package/src/modules/feature_toggles/components/formConfig.tsx +20 -10
  195. package/src/modules/feature_toggles/components/overrideFormConfig.tsx +20 -10
  196. package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +19 -10
  197. package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +49 -26
  198. package/src/modules/integrations/backend/integrations/[id]/page.tsx +20 -11
  199. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +19 -9
  200. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +34 -21
  201. package/src/modules/resources/components/ResourceCrudForm.tsx +24 -15
  202. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +12 -15
  203. package/src/modules/sales/components/ProviderFieldInput.tsx +26 -17
  204. package/src/modules/sales/components/ShippingMethodsSettings.tsx +28 -20
  205. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +51 -46
  206. package/src/modules/sales/components/documents/AddressesSection.tsx +78 -76
  207. package/src/modules/sales/components/documents/AdjustmentDialog.tsx +27 -15
  208. package/src/modules/sales/components/documents/LineItemDialog.tsx +69 -51
  209. package/src/modules/sales/components/documents/SalesDocumentForm.tsx +98 -87
  210. package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +23 -12
  211. package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +23 -12
  212. package/src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx +35 -19
  213. package/src/modules/staff/components/TeamMemberForm.tsx +23 -14
  214. package/src/modules/workflows/backend/tasks/[id]/page.tsx +51 -23
  215. package/src/modules/workflows/components/ActivitiesEditor.tsx +20 -10
  216. package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +28 -18
  217. package/src/modules/workflows/components/EdgeEditDialog.tsx +51 -40
  218. package/src/modules/workflows/components/NodeEditDialog.tsx +81 -77
  219. package/src/modules/workflows/components/StepsEditor.tsx +20 -10
  220. package/src/modules/workflows/components/TransitionsEditor.tsx +61 -44
  221. package/src/modules/workflows/components/fields/ActivityArrayEditor.tsx +22 -12
  222. package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +9 -13
  223. package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +27 -17
  224. package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +9 -12
  225. package/src/modules/workflows/components/mobile/MobileTaskForm.tsx +19 -11
  226. package/src/modules/workflows/frontend/checkout-demo/page.tsx +71 -60
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/dictionaries/fields/dictionary.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\nimport { FieldRegistry } from '@open-mercato/ui/backend/fields/registry'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { DictionarySelectControl } from '../components/DictionarySelectControl'\nimport { useDictionaryEntries } from '../components/hooks/useDictionaryEntries'\n\ntype DictionaryFieldDefinition = {\n dictionaryId?: string\n dictionaryInlineCreate?: boolean\n defaultValue?: string\n}\n\ntype Props = CrudCustomFieldRenderProps & { def?: DictionaryFieldDefinition }\n\ntype DictionarySummary = {\n id: string\n name: string\n key: string\n isActive: boolean\n}\n\nfunction DictionaryDefaultSelector({\n dictionaryId,\n defaultValue,\n onChange,\n}: {\n dictionaryId: string\n defaultValue: string\n onChange: (value: string) => void\n}) {\n const t = useT()\n const { data, isLoading } = useDictionaryEntries(dictionaryId)\n const entries = data?.entries ?? []\n const isStale = defaultValue && entries.length > 0 && !entries.some((e) => e.value === defaultValue)\n\n return (\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.defaultValue', 'Default value')}\n </label>\n <select\n className=\"w-full rounded border px-2 py-1 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n value={defaultValue}\n onChange={(event) => onChange(event.target.value)}\n >\n <option value=\"\">{t('dictionaries.customFields.defaultValueNone', 'No default')}</option>\n {entries.map((entry) => (\n <option key={entry.value} value={entry.value}>\n {entry.label}\n </option>\n ))}\n </select>\n {isLoading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {isStale ? (\n <p className=\"text-xs text-amber-600\">\n {t('dictionaries.customFields.defaultValueStale', 'Default entry not found \u2014 it may have been deleted or renamed.')}\n </p>\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldDefEditor({ def, onChange }: { def: { configJson?: DictionaryFieldDefinition } | undefined; onChange: (patch: Partial<DictionaryFieldDefinition>) => void }) {\n const t = useT()\n const [items, setItems] = React.useState<DictionarySummary[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const selectedId = typeof def?.configJson?.dictionaryId === 'string' ? def?.configJson?.dictionaryId : ''\n const inlineCreate = def?.configJson?.dictionaryInlineCreate !== false\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setLoading(true)\n setError(null)\n try {\n const call = await apiCall<{ items?: unknown[]; error?: string }>(\n '/api/dictionaries?includeInactive=true',\n )\n if (!call.ok) {\n const message =\n typeof call.result?.error === 'string' ? call.result.error : 'Failed to load dictionaries'\n throw new Error(message)\n }\n const entries = Array.isArray(call.result?.items) ? call.result!.items : []\n if (!cancelled) {\n setItems(\n entries.map((entry: any) => ({\n id: String(entry.id),\n name: typeof entry.name === 'string' && entry.name.trim().length ? entry.name : String(entry.key ?? entry.id),\n key: typeof entry.key === 'string' ? entry.key : '',\n isActive: entry.isActive !== false,\n })),\n )\n }\n } catch (err) {\n if (!cancelled) {\n console.error('Failed to load dictionaries list', err)\n setError(t('dictionaries.customFields.errorLoad', 'Failed to load dictionaries.'))\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n load().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [t])\n\n const manageHref = '/backend/config/dictionaries'\n\n return (\n <div className=\"mt-3 space-y-3 rounded border border-dashed border-muted-foreground/40 bg-muted/30 p-3\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.dictionaryLabel', 'Dictionary source')}\n </label>\n <select\n className=\"w-full rounded border px-2 py-1 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n value={selectedId}\n onChange={(event) => onChange({ dictionaryId: event.target.value || undefined })}\n >\n <option value=\"\">{t('dictionaries.customFields.dictionaryPlaceholder', 'Select a dictionary')}</option>\n {items.map((item) => (\n <option key={item.id} value={item.id}>\n {item.name}\n {item.isActive ? '' : ` (${t('dictionaries.customFields.inactive', 'inactive')})`}\n </option>\n ))}\n </select>\n {loading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {error ? <p className=\"text-xs text-red-600\">{error}</p> : null}\n {!loading && !error && items.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.empty', 'No dictionaries available yet. Create one first.')}\n </p>\n ) : null}\n </div>\n {selectedId ? (\n <div className=\"flex flex-wrap items-center justify-between gap-2 rounded bg-background/80 px-2 py-1 text-xs text-muted-foreground\">\n <span>{t('dictionaries.customFields.selectedHint', 'Entries from this dictionary populate the field.')}</span>\n <a href={manageHref} className=\"font-medium text-primary hover:underline\" target=\"_blank\" rel=\"noreferrer\">\n {t('dictionaries.customFields.manageLink', 'Manage dictionaries')}\n </a>\n </div>\n ) : null}\n <label className=\"inline-flex items-center gap-2 text-xs\">\n <input\n type=\"checkbox\"\n checked={inlineCreate}\n onChange={(event) => onChange({ dictionaryInlineCreate: event.target.checked })}\n disabled={!selectedId}\n />\n {t('dictionaries.customFields.allowInlineCreate', 'Allow inline creation inside forms')}\n </label>\n {selectedId ? (\n <DictionaryDefaultSelector\n dictionaryId={selectedId}\n defaultValue={typeof def?.configJson?.defaultValue === 'string' ? def.configJson.defaultValue : ''}\n onChange={(value) => onChange({ defaultValue: value || undefined })}\n />\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldInput({ value, setValue, disabled, def }: Props) {\n const t = useT()\n const dictionaryId = def?.dictionaryId\n if (!dictionaryId) {\n return (\n <div className=\"rounded border border-dashed p-3 text-sm text-muted-foreground\">\n {t('dictionaries.config.entries.error.load', 'Failed to load dictionary entries.')}\n </div>\n )\n }\n const normalizedValue = typeof value === 'string' ? value : Array.isArray(value) ? String(value[0] ?? '') : undefined\n return (\n <DictionarySelectControl\n dictionaryId={dictionaryId}\n value={normalizedValue ?? ''}\n onChange={(next) => setValue(next ?? undefined)}\n allowInlineCreate={def?.dictionaryInlineCreate !== false}\n disabled={disabled}\n />\n )\n}\n\nFieldRegistry.register('dictionary', {\n input: DictionaryFieldInput,\n defEditor: (props) => <DictionaryFieldDefEditor {...props} />,\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport type { CrudCustomFieldRenderProps } from '@open-mercato/ui/backend/CrudForm'\nimport { FieldRegistry } from '@open-mercato/ui/backend/fields/registry'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { DictionarySelectControl } from '../components/DictionarySelectControl'\nimport { useDictionaryEntries } from '../components/hooks/useDictionaryEntries'\n\ntype DictionaryFieldDefinition = {\n dictionaryId?: string\n dictionaryInlineCreate?: boolean\n defaultValue?: string\n}\n\ntype Props = CrudCustomFieldRenderProps & { def?: DictionaryFieldDefinition }\n\ntype DictionarySummary = {\n id: string\n name: string\n key: string\n isActive: boolean\n}\n\nfunction DictionaryDefaultSelector({\n dictionaryId,\n defaultValue,\n onChange,\n}: {\n dictionaryId: string\n defaultValue: string\n onChange: (value: string) => void\n}) {\n const t = useT()\n const { data, isLoading } = useDictionaryEntries(dictionaryId)\n const entries = data?.entries ?? []\n const isStale = defaultValue && entries.length > 0 && !entries.some((e) => e.value === defaultValue)\n\n return (\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.defaultValue', 'Default value')}\n </label>\n <Select\n value={defaultValue || undefined}\n onValueChange={(next) => onChange(next ?? '')}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('dictionaries.customFields.defaultValueNone', 'No default')} />\n </SelectTrigger>\n <SelectContent>\n {entries.map((entry) => (\n <SelectItem key={entry.value} value={entry.value}>\n {entry.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {isLoading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {isStale ? (\n <p className=\"text-xs text-amber-600\">\n {t('dictionaries.customFields.defaultValueStale', 'Default entry not found \u2014 it may have been deleted or renamed.')}\n </p>\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldDefEditor({ def, onChange }: { def: { configJson?: DictionaryFieldDefinition } | undefined; onChange: (patch: Partial<DictionaryFieldDefinition>) => void }) {\n const t = useT()\n const [items, setItems] = React.useState<DictionarySummary[]>([])\n const [loading, setLoading] = React.useState(false)\n const [error, setError] = React.useState<string | null>(null)\n const selectedId = typeof def?.configJson?.dictionaryId === 'string' ? def?.configJson?.dictionaryId : ''\n const inlineCreate = def?.configJson?.dictionaryInlineCreate !== false\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setLoading(true)\n setError(null)\n try {\n const call = await apiCall<{ items?: unknown[]; error?: string }>(\n '/api/dictionaries?includeInactive=true',\n )\n if (!call.ok) {\n const message =\n typeof call.result?.error === 'string' ? call.result.error : 'Failed to load dictionaries'\n throw new Error(message)\n }\n const entries = Array.isArray(call.result?.items) ? call.result!.items : []\n if (!cancelled) {\n setItems(\n entries.map((entry: any) => ({\n id: String(entry.id),\n name: typeof entry.name === 'string' && entry.name.trim().length ? entry.name : String(entry.key ?? entry.id),\n key: typeof entry.key === 'string' ? entry.key : '',\n isActive: entry.isActive !== false,\n })),\n )\n }\n } catch (err) {\n if (!cancelled) {\n console.error('Failed to load dictionaries list', err)\n setError(t('dictionaries.customFields.errorLoad', 'Failed to load dictionaries.'))\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n load().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [t])\n\n const manageHref = '/backend/config/dictionaries'\n\n return (\n <div className=\"mt-3 space-y-3 rounded border border-dashed border-muted-foreground/40 bg-muted/30 p-3\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('dictionaries.customFields.dictionaryLabel', 'Dictionary source')}\n </label>\n <Select\n value={selectedId || undefined}\n onValueChange={(next) => onChange({ dictionaryId: next || undefined })}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('dictionaries.customFields.dictionaryPlaceholder', 'Select a dictionary')} />\n </SelectTrigger>\n <SelectContent>\n {items.map((item) => (\n <SelectItem key={item.id} value={item.id}>\n {item.name}\n {item.isActive ? '' : ` (${t('dictionaries.customFields.inactive', 'inactive')})`}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {loading ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.loading', 'Loading dictionaries\u2026')}\n </p>\n ) : null}\n {error ? <p className=\"text-xs text-red-600\">{error}</p> : null}\n {!loading && !error && items.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('dictionaries.customFields.empty', 'No dictionaries available yet. Create one first.')}\n </p>\n ) : null}\n </div>\n {selectedId ? (\n <div className=\"flex flex-wrap items-center justify-between gap-2 rounded bg-background/80 px-2 py-1 text-xs text-muted-foreground\">\n <span>{t('dictionaries.customFields.selectedHint', 'Entries from this dictionary populate the field.')}</span>\n <a href={manageHref} className=\"font-medium text-primary hover:underline\" target=\"_blank\" rel=\"noreferrer\">\n {t('dictionaries.customFields.manageLink', 'Manage dictionaries')}\n </a>\n </div>\n ) : null}\n <label className=\"inline-flex items-center gap-2 text-xs\">\n <input\n type=\"checkbox\"\n checked={inlineCreate}\n onChange={(event) => onChange({ dictionaryInlineCreate: event.target.checked })}\n disabled={!selectedId}\n />\n {t('dictionaries.customFields.allowInlineCreate', 'Allow inline creation inside forms')}\n </label>\n {selectedId ? (\n <DictionaryDefaultSelector\n dictionaryId={selectedId}\n defaultValue={typeof def?.configJson?.defaultValue === 'string' ? def.configJson.defaultValue : ''}\n onChange={(value) => onChange({ defaultValue: value || undefined })}\n />\n ) : null}\n </div>\n )\n}\n\nfunction DictionaryFieldInput({ value, setValue, disabled, def }: Props) {\n const t = useT()\n const dictionaryId = def?.dictionaryId\n if (!dictionaryId) {\n return (\n <div className=\"rounded border border-dashed p-3 text-sm text-muted-foreground\">\n {t('dictionaries.config.entries.error.load', 'Failed to load dictionary entries.')}\n </div>\n )\n }\n const normalizedValue = typeof value === 'string' ? value : Array.isArray(value) ? String(value[0] ?? '') : undefined\n return (\n <DictionarySelectControl\n dictionaryId={dictionaryId}\n value={normalizedValue ?? ''}\n onChange={(next) => setValue(next ?? undefined)}\n allowInlineCreate={def?.dictionaryInlineCreate !== false}\n disabled={disabled}\n />\n )\n}\n\nFieldRegistry.register('dictionary', {\n input: DictionaryFieldInput,\n defEditor: (props) => <DictionaryFieldDefEditor {...props} />,\n})\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,6 +3,13 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { useQuery, useMutation } from "@tanstack/react-query";
5
5
  import { Button } from "@open-mercato/ui/primitives/button";
6
+ import {
7
+ Select,
8
+ SelectContent,
9
+ SelectItem,
10
+ SelectTrigger,
11
+ SelectValue
12
+ } from "@open-mercato/ui/primitives/select";
6
13
  import { LoadingMessage, ErrorMessage } from "@open-mercato/ui/backend/detail";
7
14
  import { flash } from "@open-mercato/ui/backend/FlashMessages";
8
15
  import { apiCall, readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
@@ -238,27 +245,25 @@ function EncryptionManager() {
238
245
  const hashOpts = withFallbackOption(row.hashField);
239
246
  return /* @__PURE__ */ jsxs("tr", { className: "border-t", children: [
240
247
  /* @__PURE__ */ jsx("td", { className: "px-3 py-2 align-top", children: /* @__PURE__ */ jsxs(
241
- "select",
248
+ Select,
242
249
  {
243
- className: "w-full rounded border bg-background px-3 py-2 text-sm",
244
- value: row.field,
245
- onChange: (event) => updateField(row.id, { field: event.target.value }),
250
+ value: row.field || void 0,
251
+ onValueChange: (value) => updateField(row.id, { field: value ?? "" }),
246
252
  children: [
247
- /* @__PURE__ */ jsx("option", { value: "", children: t("entities.encryption.fields.selectField", "Select field") }),
248
- fieldOpts.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
253
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("entities.encryption.fields.selectField", "Select field") }) }),
254
+ /* @__PURE__ */ jsx(SelectContent, { children: fieldOpts.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
249
255
  ]
250
256
  }
251
257
  ) }),
252
258
  /* @__PURE__ */ jsxs("td", { className: "px-3 py-2 align-top", children: [
253
259
  /* @__PURE__ */ jsxs(
254
- "select",
260
+ Select,
255
261
  {
256
- className: "w-full rounded border bg-background px-3 py-2 text-sm",
257
- value: row.hashField || "",
258
- onChange: (event) => updateField(row.id, { hashField: event.target.value ? event.target.value : null }),
262
+ value: row.hashField || void 0,
263
+ onValueChange: (value) => updateField(row.id, { hashField: value || null }),
259
264
  children: [
260
- /* @__PURE__ */ jsx("option", { value: "", children: t("entities.encryption.fields.selectHash", "Select hash field (optional)") }),
261
- hashOpts.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
265
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("entities.encryption.fields.selectHash", "Select hash field (optional)") }) }),
266
+ /* @__PURE__ */ jsx(SelectContent, { children: hashOpts.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
262
267
  ]
263
268
  }
264
269
  ),
@@ -288,19 +293,18 @@ function EncryptionManager() {
288
293
  /* @__PURE__ */ jsxs("div", { children: [
289
294
  /* @__PURE__ */ jsx("label", { className: "text-xs text-muted-foreground", children: t("entities.encryption.selectEntity", "Choose entity") }),
290
295
  /* @__PURE__ */ jsxs(
291
- "select",
296
+ Select,
292
297
  {
293
- className: "mt-1 w-full rounded border px-3 py-2 text-sm",
294
- value: selectedEntityId,
295
- onChange: (event) => setSelectedEntityId(event.target.value),
298
+ value: selectedEntityId || void 0,
299
+ onValueChange: (value) => setSelectedEntityId(value ?? ""),
296
300
  disabled: loadingEntities || !!entitiesError,
297
301
  children: [
298
- !selectedEntityId ? /* @__PURE__ */ jsx("option", { value: "", children: t("entities.encryption.placeholder", "Select an entity") }) : null,
299
- (entities?.items || []).map((item) => /* @__PURE__ */ jsxs("option", { value: item.entityId, children: [
302
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "mt-1", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("entities.encryption.placeholder", "Select an entity") }) }),
303
+ /* @__PURE__ */ jsx(SelectContent, { children: (entities?.items || []).map((item) => /* @__PURE__ */ jsxs(SelectItem, { value: item.entityId, children: [
300
304
  item.label || item.entityId,
301
305
  " ",
302
306
  item.source === "custom" ? `(${t("entities.encryption.source.custom", "custom")})` : ""
303
- ] }, item.entityId))
307
+ ] }, item.entityId)) })
304
308
  ]
305
309
  }
306
310
  ),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/entities/components/EncryptionManager.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useQuery, useMutation } from '@tanstack/react-query'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { Plus, Save, Trash2 } from 'lucide-react'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { getEntityFields } from '#generated/entity-fields-registry'\n\ntype EntityOption = { entityId: string; label?: string; source?: string }\n\ntype EncryptionFieldRow = {\n id: string\n field: string\n hashField?: string | null\n}\n\ntype EncryptionMapResponse = {\n entityId: string\n fields?: Array<{ field: string; hashField?: string | null }>\n isActive?: boolean\n}\n\ntype CanonicalOption = { value: string; label?: string }\n\nfunction normalizeToken(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[^a-z0-9]/gi, '')\n .toLowerCase()\n}\n\nfunction canonicalizeFieldName(raw: string, options: CanonicalOption[]): string {\n const trimmed = typeof raw === 'string' ? raw.trim() : ''\n if (!trimmed) return ''\n const normalized = normalizeToken(trimmed)\n for (const option of options) {\n const optionValue = typeof option.value === 'string' ? option.value.trim() : ''\n if (optionValue && normalizeToken(optionValue) === normalized) return optionValue\n if (option.label && normalizeToken(option.label) === normalized) return optionValue\n }\n return trimmed\n}\n\nfunction normalizeFieldRows(raw: EncryptionMapResponse | undefined, options: CanonicalOption[]): EncryptionFieldRow[] {\n const rows = Array.isArray(raw?.fields) ? raw!.fields : []\n return rows.map((entry, idx) => ({\n id: `${entry.field}-${idx}`,\n field: canonicalizeFieldName(entry.field, options),\n hashField: entry.hashField ? canonicalizeFieldName(entry.hashField, options) : null,\n }))\n}\n\nfunction buildRowId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID()\n return `row-${Math.random().toString(36).slice(2)}`\n}\n\nexport function EncryptionManager() {\n const t = useT()\n const scopeVersion = useOrganizationScopeVersion()\n const [selectedEntityId, setSelectedEntityId] = React.useState('')\n const [fields, setFields] = React.useState<EncryptionFieldRow[]>([])\n const [isActive, setIsActive] = React.useState(true)\n const [baseFieldOptions, setBaseFieldOptions] = React.useState<Array<{ value: string; label: string }>>([])\n const [hasUserEdited, setHasUserEdited] = React.useState(false)\n const { data: fieldDefs = [], isLoading: loadingFieldDefs } = useCustomFieldDefs(selectedEntityId ? [selectedEntityId] : [], {\n enabled: !!selectedEntityId,\n })\n const canonicalOptions = React.useMemo<CanonicalOption[]>(() => {\n const options: CanonicalOption[] = []\n for (const option of baseFieldOptions) {\n if (!option.value) continue\n if (options.some((opt) => opt.value === option.value)) continue\n options.push(option)\n }\n for (const def of fieldDefs) {\n const key = typeof def.key === 'string' ? def.key.trim() : ''\n if (!key || options.some((opt) => opt.value === key)) continue\n const label = typeof def.label === 'string' ? def.label : undefined\n options.push({ value: key, label })\n }\n return options\n }, [baseFieldOptions, fieldDefs])\n const fieldOptions = React.useMemo(() => {\n const entries = new Map<string, string>()\n for (const option of baseFieldOptions) {\n if (!option.value || entries.has(option.value)) continue\n entries.set(option.value, option.label || option.value)\n }\n for (const def of fieldDefs) {\n const key = typeof def.key === 'string' ? def.key.trim() : ''\n if (!key || entries.has(key)) continue\n const label = typeof def.label === 'string' && def.label.trim().length ? def.label : key\n entries.set(key, label)\n }\n for (const row of fields) {\n const main = row.field?.trim()\n if (main && !entries.has(main)) entries.set(main, main)\n const hash = row.hashField?.trim()\n if (hash && !entries.has(hash)) entries.set(hash, hash)\n }\n return Array.from(entries.entries()).map(([value, label]) => ({ value, label }))\n }, [baseFieldOptions, fieldDefs, fields])\n\n const { data: entities, isLoading: loadingEntities, error: entitiesError } = useQuery<{ items: EntityOption[] }>({\n queryKey: ['entities-list', scopeVersion],\n queryFn: async () =>\n readApiResultOrThrow('/api/entities/entities', undefined, {\n errorMessage: t('entities.encryption.errors.loadEntities', 'Failed to load entities'),\n }),\n })\n\n React.useEffect(() => {\n if (!selectedEntityId && entities?.items?.length) {\n const first = entities.items[0]\n setSelectedEntityId(first.entityId)\n }\n }, [entities, selectedEntityId])\n\n React.useEffect(() => {\n if (!selectedEntityId) {\n setBaseFieldOptions([])\n return\n }\n const parts = selectedEntityId.split(':')\n const entitySlug = parts[1]\n if (!entitySlug) {\n setBaseFieldOptions([])\n return\n }\n\n // Use static registry instead of dynamic import for Turbopack compatibility\n const mod = getEntityFields(entitySlug)\n if (!mod) {\n console.warn('[encryption] No fields found for entity', entitySlug)\n setBaseFieldOptions([])\n return\n }\n\n const options: Array<{ value: string; label: string }> = []\n for (const raw of Object.values(mod)) {\n if (typeof raw !== 'string' || !raw.trim()) continue\n const value = raw.trim()\n if (options.some((opt) => opt.value === value)) continue\n const label = value\n .split('_')\n .map((segment) => (segment ? `${segment[0].toUpperCase()}${segment.slice(1)}` : ''))\n .join(' ')\n .trim() || value\n options.push({ value, label })\n }\n setBaseFieldOptions(options)\n }, [selectedEntityId])\n\n const {\n data: map,\n isLoading: loadingMap,\n isError: mapError,\n refetch: refetchMap,\n } = useQuery<EncryptionMapResponse>({\n queryKey: ['encryption-map', selectedEntityId, scopeVersion],\n enabled: !!selectedEntityId,\n queryFn: async () =>\n readApiResultOrThrow(`/api/entities/encryption?entityId=${encodeURIComponent(selectedEntityId)}`, undefined, {\n errorMessage: t('entities.encryption.errors.loadMap', 'Failed to load encryption map'),\n }),\n })\n\n const mapSignature = React.useMemo(() => JSON.stringify(map ?? null), [map])\n const lastMapSignatureRef = React.useRef<string | null>(null)\n\n React.useEffect(() => {\n const signature = mapSignature\n const isSameMap = signature === lastMapSignatureRef.current\n if (isSameMap && hasUserEdited) return\n if (!map) {\n setFields([])\n setIsActive(true)\n setHasUserEdited(false)\n lastMapSignatureRef.current = signature\n return\n }\n setFields(normalizeFieldRows(map, canonicalOptions))\n setIsActive(map?.isActive !== false)\n setHasUserEdited(false)\n lastMapSignatureRef.current = signature\n }, [mapSignature, map, canonicalOptions, hasUserEdited])\n\n const mutation = useMutation({\n mutationFn: async () => {\n const trimmed = fields\n .map((row) => ({\n field: canonicalizeFieldName(row.field, canonicalOptions).trim(),\n hashField: row.hashField ? canonicalizeFieldName(row.hashField, canonicalOptions).trim() : '',\n }))\n .filter((row) => row.field.length > 0)\n .map((row) => ({\n field: row.field,\n hashField: row.hashField ? row.hashField : null,\n }))\n if (!selectedEntityId) {\n throw new Error(t('entities.encryption.errors.selectEntity', 'Select an entity before saving'))\n }\n if (!trimmed.length) {\n throw new Error(t('entities.encryption.errors.noFields', 'Add at least one field to encrypt'))\n }\n const res = await apiCall('/api/entities/encryption', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ entityId: selectedEntityId, fields: trimmed, isActive }),\n })\n if (!res.ok) {\n await raiseCrudError(res.response, t('entities.encryption.errors.save', 'Failed to save encryption map'))\n }\n return true\n },\n onSuccess: () => {\n flash(t('entities.encryption.flash.saved', 'Encryption map saved'), 'success')\n void refetchMap()\n },\n onError: (err: any) => {\n const message = err?.message || t('entities.encryption.errors.save', 'Failed to save encryption map')\n flash(message, 'error')\n },\n })\n\n const addField = () => {\n setHasUserEdited(true)\n setFields((prev) => [...prev, { id: buildRowId(), field: '', hashField: null }])\n }\n\n const updateField = (id: string, patch: Partial<EncryptionFieldRow>) => {\n setHasUserEdited(true)\n setFields((prev) => prev.map((row) => (row.id === id ? { ...row, ...patch } : row)))\n }\n\n const removeField = (id: string) => {\n setHasUserEdited(true)\n setFields((prev) => prev.filter((row) => row.id !== id))\n }\n\n const renderFields = () => {\n if (loadingMap || loadingFieldDefs) {\n return (\n <LoadingMessage\n label={t('entities.encryption.loading', 'Loading encryption map\u2026')}\n className=\"border-0 bg-transparent p-4\"\n />\n )\n }\n if (mapError) {\n return (\n <ErrorMessage\n label={t('entities.encryption.errors.loadMap', 'Failed to load encryption map')}\n action={(\n <Button variant=\"outline\" size=\"sm\" onClick={() => void refetchMap()}>\n {t('entities.encryption.actions.retry', 'Retry')}\n </Button>\n )}\n />\n )\n }\n if (!fields.length) {\n return (\n <div className=\"rounded border bg-background/80 p-4 text-sm text-muted-foreground\">\n {t('entities.encryption.empty', 'No fields are encrypted yet. Add the first one below.')}\n </div>\n )\n }\n const withFallbackOption = (value?: string | null) => {\n if (value && !fieldOptions.some((opt) => opt.value === value)) {\n return [...fieldOptions, { value, label: value }]\n }\n return fieldOptions\n }\n return (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[720px] text-sm\">\n <thead>\n <tr className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n <th className=\"px-3 py-2 text-left\">\n {t('entities.encryption.fields.field', 'Field name')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('entities.encryption.fields.hash', 'Hash field (optional)')}\n </th>\n <th className=\"px-3 py-2 text-right\">\n {t('entities.encryption.fields.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody>\n {fields.map((row) => {\n const fieldOpts = withFallbackOption(row.field)\n const hashOpts = withFallbackOption(row.hashField)\n return (\n <tr key={row.id} className=\"border-t\">\n <td className=\"px-3 py-2 align-top\">\n <select\n className=\"w-full rounded border bg-background px-3 py-2 text-sm\"\n value={row.field}\n onChange={(event) => updateField(row.id, { field: event.target.value })}\n >\n <option value=\"\">{t('entities.encryption.fields.selectField', 'Select field')}</option>\n {fieldOpts.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </td>\n <td className=\"px-3 py-2 align-top\">\n <select\n className=\"w-full rounded border bg-background px-3 py-2 text-sm\"\n value={row.hashField || ''}\n onChange={(event) => updateField(row.id, { hashField: event.target.value ? event.target.value : null })}\n >\n <option value=\"\">{t('entities.encryption.fields.selectHash', 'Select hash field (optional)')}</option>\n {hashOpts.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <p className=\"mt-1 text-overline text-muted-foreground\">\n {t('entities.encryption.fields.hashHint', 'Use when lookups must stay deterministic (e.g., login by email).')}\n </p>\n </td>\n <td className=\"px-3 py-2 align-top text-right\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-9 px-0\"\n aria-label={t('entities.encryption.actions.remove', 'Remove')}\n onClick={() => removeField(row.id)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </td>\n </tr>\n )\n })}\n </tbody>\n </table>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-6\">\n <div className=\"flex flex-col gap-3 rounded-lg border bg-card p-4 shadow-sm\">\n <div className=\"space-y-2\">\n <h2 className=\"text-xl font-semibold\">{t('entities.encryption.title', 'Encryption')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('entities.encryption.description', 'Manage which entity fields are encrypted with tenant keys and optional hash columns.')}\n </p>\n </div>\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-end\">\n <div className=\"flex-1 space-y-3\">\n <div>\n <label className=\"text-xs text-muted-foreground\">\n {t('entities.encryption.selectEntity', 'Choose entity')}\n </label>\n <select\n className=\"mt-1 w-full rounded border px-3 py-2 text-sm\"\n value={selectedEntityId}\n onChange={(event) => setSelectedEntityId(event.target.value)}\n disabled={loadingEntities || !!entitiesError}\n >\n {!selectedEntityId ? <option value=\"\">{t('entities.encryption.placeholder', 'Select an entity')}</option> : null}\n {(entities?.items || []).map((item) => (\n <option key={item.entityId} value={item.entityId}>\n {item.label || item.entityId} {item.source === 'custom' ? `(${t('entities.encryption.source.custom', 'custom')})` : ''}\n </option>\n ))}\n </select>\n {entitiesError ? (\n <p className=\"mt-1 text-xs text-red-600\">\n {t('entities.encryption.errors.loadEntities', 'Failed to load entities')}\n </p>\n ) : (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {t('entities.encryption.entityHint', 'Maps apply per tenant/organization. Use field names from your entities.')}\n </p>\n )}\n </div>\n <label className=\"inline-flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={isActive}\n onChange={(event) => setIsActive(event.target.checked)}\n />\n {t('entities.encryption.active', 'Encryption enabled for this entity')}\n </label>\n </div>\n </div>\n <div className=\"rounded-lg border bg-background/80 p-4\">\n <div className=\"mb-3 flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-medium\">{t('entities.encryption.fields.title', 'Encrypted fields')}</h3>\n <p className=\"text-xs text-muted-foreground\">\n {t('entities.encryption.fields.subtitle', 'List the attributes that should be encrypted with the tenant key.')}\n </p>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={addField}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {t('entities.encryption.actions.add', 'Add field')}\n </Button>\n </div>\n {renderFields()}\n </div>\n <div className=\"flex justify-end\">\n <Button\n onClick={() => mutation.mutate()}\n disabled={mutation.isPending || loadingEntities || !!entitiesError || !selectedEntityId}\n >\n <Save className=\"mr-2 h-4 w-4\" />\n {mutation.isPending\n ? t('entities.encryption.actions.saving', 'Saving\u2026')\n : t('entities.encryption.actions.save', 'Save encryption map')}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n"],
5
- "mappings": ";AA2PQ,cAmCI,YAnCJ;AAzPR,YAAY,WAAW;AACvB,SAAS,UAAU,mBAAmB;AACtC,SAAS,cAAc;AACvB,SAAS,gBAAgB,oBAAoB;AAC7C,SAAS,aAAa;AACtB,SAAS,SAAS,4BAA4B;AAC9C,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,MAAM,MAAM,cAAc;AACnC,SAAS,mCAAmC;AAC5C,SAAS,YAAY;AACrB,SAAS,uBAAuB;AAkBhC,SAAS,eAAe,OAAuB;AAC7C,SAAO,MACJ,QAAQ,sBAAsB,OAAO,EACrC,QAAQ,eAAe,EAAE,EACzB,YAAY;AACjB;AAEA,SAAS,sBAAsB,KAAa,SAAoC;AAC9E,QAAM,UAAU,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI;AACvD,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,aAAa,eAAe,OAAO;AACzC,aAAW,UAAU,SAAS;AAC5B,UAAM,cAAc,OAAO,OAAO,UAAU,WAAW,OAAO,MAAM,KAAK,IAAI;AAC7E,QAAI,eAAe,eAAe,WAAW,MAAM,WAAY,QAAO;AACtE,QAAI,OAAO,SAAS,eAAe,OAAO,KAAK,MAAM,WAAY,QAAO;AAAA,EAC1E;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,KAAwC,SAAkD;AACpH,QAAM,OAAO,MAAM,QAAQ,KAAK,MAAM,IAAI,IAAK,SAAS,CAAC;AACzD,SAAO,KAAK,IAAI,CAAC,OAAO,SAAS;AAAA,IAC/B,IAAI,GAAG,MAAM,KAAK,IAAI,GAAG;AAAA,IACzB,OAAO,sBAAsB,MAAM,OAAO,OAAO;AAAA,IACjD,WAAW,MAAM,YAAY,sBAAsB,MAAM,WAAW,OAAO,IAAI;AAAA,EACjF,EAAE;AACJ;AAEA,SAAS,aAAqB;AAC5B,MAAI,OAAO,WAAW,eAAe,OAAO,WAAY,QAAO,OAAO,WAAW;AACjF,SAAO,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AACnD;AAEO,SAAS,oBAAoB;AAClC,QAAM,IAAI,KAAK;AACf,QAAM,eAAe,4BAA4B;AACjD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAS,EAAE;AACjE,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAA+B,CAAC,CAAC;AACnE,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAS,IAAI;AACnD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAkD,CAAC,CAAC;AAC1G,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,EAAE,MAAM,YAAY,CAAC,GAAG,WAAW,iBAAiB,IAAI,mBAAmB,mBAAmB,CAAC,gBAAgB,IAAI,CAAC,GAAG;AAAA,IAC3H,SAAS,CAAC,CAAC;AAAA,EACb,CAAC;AACD,QAAM,mBAAmB,MAAM,QAA2B,MAAM;AAC9D,UAAM,UAA6B,CAAC;AACpC,eAAW,UAAU,kBAAkB;AACrC,UAAI,CAAC,OAAO,MAAO;AACnB,UAAI,QAAQ,KAAK,CAAC,QAAQ,IAAI,UAAU,OAAO,KAAK,EAAG;AACvD,cAAQ,KAAK,MAAM;AAAA,IACrB;AACA,eAAW,OAAO,WAAW;AAC3B,YAAM,MAAM,OAAO,IAAI,QAAQ,WAAW,IAAI,IAAI,KAAK,IAAI;AAC3D,UAAI,CAAC,OAAO,QAAQ,KAAK,CAAC,QAAQ,IAAI,UAAU,GAAG,EAAG;AACtD,YAAM,QAAQ,OAAO,IAAI,UAAU,WAAW,IAAI,QAAQ;AAC1D,cAAQ,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;AAAA,IACpC;AACA,WAAO;AAAA,EACT,GAAG,CAAC,kBAAkB,SAAS,CAAC;AAChC,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,UAAM,UAAU,oBAAI,IAAoB;AACxC,eAAW,UAAU,kBAAkB;AACrC,UAAI,CAAC,OAAO,SAAS,QAAQ,IAAI,OAAO,KAAK,EAAG;AAChD,cAAQ,IAAI,OAAO,OAAO,OAAO,SAAS,OAAO,KAAK;AAAA,IACxD;AACA,eAAW,OAAO,WAAW;AAC3B,YAAM,MAAM,OAAO,IAAI,QAAQ,WAAW,IAAI,IAAI,KAAK,IAAI;AAC3D,UAAI,CAAC,OAAO,QAAQ,IAAI,GAAG,EAAG;AAC9B,YAAM,QAAQ,OAAO,IAAI,UAAU,YAAY,IAAI,MAAM,KAAK,EAAE,SAAS,IAAI,QAAQ;AACrF,cAAQ,IAAI,KAAK,KAAK;AAAA,IACxB;AACA,eAAW,OAAO,QAAQ;AACxB,YAAM,OAAO,IAAI,OAAO,KAAK;AAC7B,UAAI,QAAQ,CAAC,QAAQ,IAAI,IAAI,EAAG,SAAQ,IAAI,MAAM,IAAI;AACtD,YAAM,OAAO,IAAI,WAAW,KAAK;AACjC,UAAI,QAAQ,CAAC,QAAQ,IAAI,IAAI,EAAG,SAAQ,IAAI,MAAM,IAAI;AAAA,IACxD;AACA,WAAO,MAAM,KAAK,QAAQ,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE;AAAA,EACjF,GAAG,CAAC,kBAAkB,WAAW,MAAM,CAAC;AAExC,QAAM,EAAE,MAAM,UAAU,WAAW,iBAAiB,OAAO,cAAc,IAAI,SAAoC;AAAA,IAC/G,UAAU,CAAC,iBAAiB,YAAY;AAAA,IACxC,SAAS,YACP,qBAAqB,0BAA0B,QAAW;AAAA,MACxD,cAAc,EAAE,2CAA2C,yBAAyB;AAAA,IACtF,CAAC;AAAA,EACL,CAAC;AAED,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,oBAAoB,UAAU,OAAO,QAAQ;AAChD,YAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,0BAAoB,MAAM,QAAQ;AAAA,IACpC;AAAA,EACF,GAAG,CAAC,UAAU,gBAAgB,CAAC;AAE/B,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,kBAAkB;AACrB,0BAAoB,CAAC,CAAC;AACtB;AAAA,IACF;AACA,UAAM,QAAQ,iBAAiB,MAAM,GAAG;AACxC,UAAM,aAAa,MAAM,CAAC;AAC1B,QAAI,CAAC,YAAY;AACf,0BAAoB,CAAC,CAAC;AACtB;AAAA,IACF;AAGA,UAAM,MAAM,gBAAgB,UAAU;AACtC,QAAI,CAAC,KAAK;AACR,cAAQ,KAAK,2CAA2C,UAAU;AAClE,0BAAoB,CAAC,CAAC;AACtB;AAAA,IACF;AAEA,UAAM,UAAmD,CAAC;AAC1D,eAAW,OAAO,OAAO,OAAO,GAAG,GAAG;AACpC,UAAI,OAAO,QAAQ,YAAY,CAAC,IAAI,KAAK,EAAG;AAC5C,YAAM,QAAQ,IAAI,KAAK;AACvB,UAAI,QAAQ,KAAK,CAAC,QAAQ,IAAI,UAAU,KAAK,EAAG;AAChD,YAAM,QAAQ,MACX,MAAM,GAAG,EACT,IAAI,CAAC,YAAa,UAAU,GAAG,QAAQ,CAAC,EAAE,YAAY,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC,KAAK,EAAG,EAClF,KAAK,GAAG,EACR,KAAK,KAAK;AACb,cAAQ,KAAK,EAAE,OAAO,MAAM,CAAC;AAAA,IAC/B;AACA,wBAAoB,OAAO;AAAA,EAC7B,GAAG,CAAC,gBAAgB,CAAC;AAErB,QAAM;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,SAAS;AAAA,EACX,IAAI,SAAgC;AAAA,IAClC,UAAU,CAAC,kBAAkB,kBAAkB,YAAY;AAAA,IAC3D,SAAS,CAAC,CAAC;AAAA,IACX,SAAS,YACP,qBAAqB,qCAAqC,mBAAmB,gBAAgB,CAAC,IAAI,QAAW;AAAA,MAC3G,cAAc,EAAE,sCAAsC,+BAA+B;AAAA,IACvF,CAAC;AAAA,EACL,CAAC;AAED,QAAM,eAAe,MAAM,QAAQ,MAAM,KAAK,UAAU,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC;AAC3E,QAAM,sBAAsB,MAAM,OAAsB,IAAI;AAE5D,QAAM,UAAU,MAAM;AACpB,UAAM,YAAY;AAClB,UAAM,YAAY,cAAc,oBAAoB;AACpD,QAAI,aAAa,cAAe;AAChC,QAAI,CAAC,KAAK;AACR,gBAAU,CAAC,CAAC;AACZ,kBAAY,IAAI;AAChB,uBAAiB,KAAK;AACtB,0BAAoB,UAAU;AAC9B;AAAA,IACF;AACA,cAAU,mBAAmB,KAAK,gBAAgB,CAAC;AACnD,gBAAY,KAAK,aAAa,KAAK;AACnC,qBAAiB,KAAK;AACtB,wBAAoB,UAAU;AAAA,EAChC,GAAG,CAAC,cAAc,KAAK,kBAAkB,aAAa,CAAC;AAEvD,QAAM,WAAW,YAAY;AAAA,IAC3B,YAAY,YAAY;AACtB,YAAM,UAAU,OACb,IAAI,CAAC,SAAS;AAAA,QACb,OAAO,sBAAsB,IAAI,OAAO,gBAAgB,EAAE,KAAK;AAAA,QAC/D,WAAW,IAAI,YAAY,sBAAsB,IAAI,WAAW,gBAAgB,EAAE,KAAK,IAAI;AAAA,MAC7F,EAAE,EACD,OAAO,CAAC,QAAQ,IAAI,MAAM,SAAS,CAAC,EACpC,IAAI,CAAC,SAAS;AAAA,QACb,OAAO,IAAI;AAAA,QACX,WAAW,IAAI,YAAY,IAAI,YAAY;AAAA,MAC7C,EAAE;AACJ,UAAI,CAAC,kBAAkB;AACrB,cAAM,IAAI,MAAM,EAAE,2CAA2C,gCAAgC,CAAC;AAAA,MAChG;AACA,UAAI,CAAC,QAAQ,QAAQ;AACnB,cAAM,IAAI,MAAM,EAAE,uCAAuC,mCAAmC,CAAC;AAAA,MAC/F;AACA,YAAM,MAAM,MAAM,QAAQ,4BAA4B;AAAA,QACpD,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,UAAU,kBAAkB,QAAQ,SAAS,SAAS,CAAC;AAAA,MAChF,CAAC;AACD,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,eAAe,IAAI,UAAU,EAAE,mCAAmC,+BAA+B,CAAC;AAAA,MAC1G;AACA,aAAO;AAAA,IACT;AAAA,IACA,WAAW,MAAM;AACf,YAAM,EAAE,mCAAmC,sBAAsB,GAAG,SAAS;AAC7E,WAAK,WAAW;AAAA,IAClB;AAAA,IACA,SAAS,CAAC,QAAa;AACrB,YAAM,UAAU,KAAK,WAAW,EAAE,mCAAmC,+BAA+B;AACpG,YAAM,SAAS,OAAO;AAAA,IACxB;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM;AACrB,qBAAiB,IAAI;AACrB,cAAU,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,IAAI,WAAW,GAAG,OAAO,IAAI,WAAW,KAAK,CAAC,CAAC;AAAA,EACjF;AAEA,QAAM,cAAc,CAAC,IAAY,UAAuC;AACtE,qBAAiB,IAAI;AACrB,cAAU,CAAC,SAAS,KAAK,IAAI,CAAC,QAAS,IAAI,OAAO,KAAK,EAAE,GAAG,KAAK,GAAG,MAAM,IAAI,GAAI,CAAC;AAAA,EACrF;AAEA,QAAM,cAAc,CAAC,OAAe;AAClC,qBAAiB,IAAI;AACrB,cAAU,CAAC,SAAS,KAAK,OAAO,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC;AAAA,EACzD;AAEA,QAAM,eAAe,MAAM;AACzB,QAAI,cAAc,kBAAkB;AAClC,aACE;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,+BAA+B,8BAAyB;AAAA,UACjE,WAAU;AAAA;AAAA,MACZ;AAAA,IAEJ;AACA,QAAI,UAAU;AACZ,aACE;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,sCAAsC,+BAA+B;AAAA,UAC9E,QACE,oBAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,MAAM,KAAK,WAAW,GAChE,YAAE,qCAAqC,OAAO,GACjD;AAAA;AAAA,MAEJ;AAAA,IAEJ;AACA,QAAI,CAAC,OAAO,QAAQ;AAClB,aACE,oBAAC,SAAI,WAAU,qEACZ,YAAE,6BAA6B,uDAAuD,GACzF;AAAA,IAEJ;AACA,UAAM,qBAAqB,CAAC,UAA0B;AACpD,UAAI,SAAS,CAAC,aAAa,KAAK,CAAC,QAAQ,IAAI,UAAU,KAAK,GAAG;AAC7D,eAAO,CAAC,GAAG,cAAc,EAAE,OAAO,OAAO,MAAM,CAAC;AAAA,MAClD;AACA,aAAO;AAAA,IACT;AACA,WACE,oBAAC,SAAI,WAAU,mBACb,+BAAC,WAAM,WAAU,gCACf;AAAA,0BAAC,WACC,+BAAC,QAAG,WAAU,yDACZ;AAAA,4BAAC,QAAG,WAAU,uBACX,YAAE,oCAAoC,YAAY,GACrD;AAAA,QACA,oBAAC,QAAG,WAAU,uBACX,YAAE,mCAAmC,uBAAuB,GAC/D;AAAA,QACA,oBAAC,QAAG,WAAU,wBACX,YAAE,sCAAsC,SAAS,GACpD;AAAA,SACF,GACF;AAAA,MACA,oBAAC,WACE,iBAAO,IAAI,CAAC,QAAQ;AACnB,cAAM,YAAY,mBAAmB,IAAI,KAAK;AAC9C,cAAM,WAAW,mBAAmB,IAAI,SAAS;AACjD,eACE,qBAAC,QAAgB,WAAU,YACzB;AAAA,8BAAC,QAAG,WAAU,uBACZ;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,IAAI;AAAA,cACX,UAAU,CAAC,UAAU,YAAY,IAAI,IAAI,EAAE,OAAO,MAAM,OAAO,MAAM,CAAC;AAAA,cAEtE;AAAA,oCAAC,YAAO,OAAM,IAAI,YAAE,0CAA0C,cAAc,GAAE;AAAA,gBAC7E,UAAU,IAAI,CAAC,WACd,oBAAC,YAA0B,OAAO,OAAO,OACtC,iBAAO,SADG,OAAO,KAEpB,CACD;AAAA;AAAA;AAAA,UACH,GACF;AAAA,UACA,qBAAC,QAAG,WAAU,uBACZ;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO,IAAI,aAAa;AAAA,gBACxB,UAAU,CAAC,UAAU,YAAY,IAAI,IAAI,EAAE,WAAW,MAAM,OAAO,QAAQ,MAAM,OAAO,QAAQ,KAAK,CAAC;AAAA,gBAEtG;AAAA,sCAAC,YAAO,OAAM,IAAI,YAAE,yCAAyC,8BAA8B,GAAE;AAAA,kBAC5F,SAAS,IAAI,CAAC,WACb,oBAAC,YAA0B,OAAO,OAAO,OACtC,iBAAO,SADG,OAAO,KAEpB,CACD;AAAA;AAAA;AAAA,YACH;AAAA,YACA,oBAAC,OAAE,WAAU,4CACV,YAAE,uCAAuC,kEAAkE,GAC9G;AAAA,aACF;AAAA,UACA,oBAAC,QAAG,WAAU,kCACZ;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,cAAY,EAAE,sCAAsC,QAAQ;AAAA,cAC5D,SAAS,MAAM,YAAY,IAAI,EAAE;AAAA,cAEjC,8BAAC,UAAO,WAAU,WAAU;AAAA;AAAA,UAC9B,GACF;AAAA,aA1CO,IAAI,EA2Cb;AAAA,MAEJ,CAAC,GACH;AAAA,OACF,GACF;AAAA,EAEJ;AAEA,SACE,oBAAC,SAAI,WAAU,aACb,+BAAC,SAAI,WAAU,+DACb;AAAA,yBAAC,SAAI,WAAU,aACb;AAAA,0BAAC,QAAG,WAAU,yBAAyB,YAAE,6BAA6B,YAAY,GAAE;AAAA,MACpF,oBAAC,OAAE,WAAU,iCACV,YAAE,mCAAmC,sFAAsF,GAC9H;AAAA,OACF;AAAA,IACA,oBAAC,SAAI,WAAU,gDACb,+BAAC,SAAI,WAAU,oBACb;AAAA,2BAAC,SACC;AAAA,4BAAC,WAAM,WAAU,iCACd,YAAE,oCAAoC,eAAe,GACxD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,oBAAoB,MAAM,OAAO,KAAK;AAAA,YAC3D,UAAU,mBAAmB,CAAC,CAAC;AAAA,YAE9B;AAAA,eAAC,mBAAmB,oBAAC,YAAO,OAAM,IAAI,YAAE,mCAAmC,kBAAkB,GAAE,IAAY;AAAA,eAC1G,UAAU,SAAS,CAAC,GAAG,IAAI,CAAC,SAC5B,qBAAC,YAA2B,OAAO,KAAK,UACrC;AAAA,qBAAK,SAAS,KAAK;AAAA,gBAAS;AAAA,gBAAE,KAAK,WAAW,WAAW,IAAI,EAAE,qCAAqC,QAAQ,CAAC,MAAM;AAAA,mBADzG,KAAK,QAElB,CACD;AAAA;AAAA;AAAA,QACH;AAAA,QACC,gBACC,oBAAC,OAAE,WAAU,6BACV,YAAE,2CAA2C,yBAAyB,GACzE,IAEA,oBAAC,OAAE,WAAU,sCACV,YAAE,kCAAkC,yEAAyE,GAChH;AAAA,SAEJ;AAAA,MACA,qBAAC,WAAM,WAAU,0CACf;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT,UAAU,CAAC,UAAU,YAAY,MAAM,OAAO,OAAO;AAAA;AAAA,QACvD;AAAA,QACC,EAAE,8BAA8B,oCAAoC;AAAA,SACvE;AAAA,OACF,GACF;AAAA,IACA,qBAAC,SAAI,WAAU,0CACb;AAAA,2BAAC,SAAI,WAAU,0CACb;AAAA,6BAAC,SACC;AAAA,8BAAC,QAAG,WAAU,uBAAuB,YAAE,oCAAoC,kBAAkB,GAAE;AAAA,UAC/F,oBAAC,OAAE,WAAU,iCACV,YAAE,uCAAuC,mEAAmE,GAC/G;AAAA,WACF;AAAA,QACA,qBAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,UAC3C;AAAA,8BAAC,QAAK,WAAU,gBAAe;AAAA,UAC9B,EAAE,mCAAmC,WAAW;AAAA,WACnD;AAAA,SACF;AAAA,MACC,aAAa;AAAA,OAChB;AAAA,IACA,oBAAC,SAAI,WAAU,oBACb;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM,SAAS,OAAO;AAAA,QAC/B,UAAU,SAAS,aAAa,mBAAmB,CAAC,CAAC,iBAAiB,CAAC;AAAA,QAEvE;AAAA,8BAAC,QAAK,WAAU,gBAAe;AAAA,UAC9B,SAAS,YACN,EAAE,sCAAsC,cAAS,IACjD,EAAE,oCAAoC,qBAAqB;AAAA;AAAA;AAAA,IACjE,GACF;AAAA,KACF,GACF;AAEJ;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useQuery, useMutation } from '@tanstack/react-query'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { LoadingMessage, ErrorMessage } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { useCustomFieldDefs } from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport { Plus, Save, Trash2 } from 'lucide-react'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { getEntityFields } from '#generated/entity-fields-registry'\n\ntype EntityOption = { entityId: string; label?: string; source?: string }\n\ntype EncryptionFieldRow = {\n id: string\n field: string\n hashField?: string | null\n}\n\ntype EncryptionMapResponse = {\n entityId: string\n fields?: Array<{ field: string; hashField?: string | null }>\n isActive?: boolean\n}\n\ntype CanonicalOption = { value: string; label?: string }\n\nfunction normalizeToken(value: string): string {\n return value\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[^a-z0-9]/gi, '')\n .toLowerCase()\n}\n\nfunction canonicalizeFieldName(raw: string, options: CanonicalOption[]): string {\n const trimmed = typeof raw === 'string' ? raw.trim() : ''\n if (!trimmed) return ''\n const normalized = normalizeToken(trimmed)\n for (const option of options) {\n const optionValue = typeof option.value === 'string' ? option.value.trim() : ''\n if (optionValue && normalizeToken(optionValue) === normalized) return optionValue\n if (option.label && normalizeToken(option.label) === normalized) return optionValue\n }\n return trimmed\n}\n\nfunction normalizeFieldRows(raw: EncryptionMapResponse | undefined, options: CanonicalOption[]): EncryptionFieldRow[] {\n const rows = Array.isArray(raw?.fields) ? raw!.fields : []\n return rows.map((entry, idx) => ({\n id: `${entry.field}-${idx}`,\n field: canonicalizeFieldName(entry.field, options),\n hashField: entry.hashField ? canonicalizeFieldName(entry.hashField, options) : null,\n }))\n}\n\nfunction buildRowId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID()\n return `row-${Math.random().toString(36).slice(2)}`\n}\n\nexport function EncryptionManager() {\n const t = useT()\n const scopeVersion = useOrganizationScopeVersion()\n const [selectedEntityId, setSelectedEntityId] = React.useState('')\n const [fields, setFields] = React.useState<EncryptionFieldRow[]>([])\n const [isActive, setIsActive] = React.useState(true)\n const [baseFieldOptions, setBaseFieldOptions] = React.useState<Array<{ value: string; label: string }>>([])\n const [hasUserEdited, setHasUserEdited] = React.useState(false)\n const { data: fieldDefs = [], isLoading: loadingFieldDefs } = useCustomFieldDefs(selectedEntityId ? [selectedEntityId] : [], {\n enabled: !!selectedEntityId,\n })\n const canonicalOptions = React.useMemo<CanonicalOption[]>(() => {\n const options: CanonicalOption[] = []\n for (const option of baseFieldOptions) {\n if (!option.value) continue\n if (options.some((opt) => opt.value === option.value)) continue\n options.push(option)\n }\n for (const def of fieldDefs) {\n const key = typeof def.key === 'string' ? def.key.trim() : ''\n if (!key || options.some((opt) => opt.value === key)) continue\n const label = typeof def.label === 'string' ? def.label : undefined\n options.push({ value: key, label })\n }\n return options\n }, [baseFieldOptions, fieldDefs])\n const fieldOptions = React.useMemo(() => {\n const entries = new Map<string, string>()\n for (const option of baseFieldOptions) {\n if (!option.value || entries.has(option.value)) continue\n entries.set(option.value, option.label || option.value)\n }\n for (const def of fieldDefs) {\n const key = typeof def.key === 'string' ? def.key.trim() : ''\n if (!key || entries.has(key)) continue\n const label = typeof def.label === 'string' && def.label.trim().length ? def.label : key\n entries.set(key, label)\n }\n for (const row of fields) {\n const main = row.field?.trim()\n if (main && !entries.has(main)) entries.set(main, main)\n const hash = row.hashField?.trim()\n if (hash && !entries.has(hash)) entries.set(hash, hash)\n }\n return Array.from(entries.entries()).map(([value, label]) => ({ value, label }))\n }, [baseFieldOptions, fieldDefs, fields])\n\n const { data: entities, isLoading: loadingEntities, error: entitiesError } = useQuery<{ items: EntityOption[] }>({\n queryKey: ['entities-list', scopeVersion],\n queryFn: async () =>\n readApiResultOrThrow('/api/entities/entities', undefined, {\n errorMessage: t('entities.encryption.errors.loadEntities', 'Failed to load entities'),\n }),\n })\n\n React.useEffect(() => {\n if (!selectedEntityId && entities?.items?.length) {\n const first = entities.items[0]\n setSelectedEntityId(first.entityId)\n }\n }, [entities, selectedEntityId])\n\n React.useEffect(() => {\n if (!selectedEntityId) {\n setBaseFieldOptions([])\n return\n }\n const parts = selectedEntityId.split(':')\n const entitySlug = parts[1]\n if (!entitySlug) {\n setBaseFieldOptions([])\n return\n }\n\n // Use static registry instead of dynamic import for Turbopack compatibility\n const mod = getEntityFields(entitySlug)\n if (!mod) {\n console.warn('[encryption] No fields found for entity', entitySlug)\n setBaseFieldOptions([])\n return\n }\n\n const options: Array<{ value: string; label: string }> = []\n for (const raw of Object.values(mod)) {\n if (typeof raw !== 'string' || !raw.trim()) continue\n const value = raw.trim()\n if (options.some((opt) => opt.value === value)) continue\n const label = value\n .split('_')\n .map((segment) => (segment ? `${segment[0].toUpperCase()}${segment.slice(1)}` : ''))\n .join(' ')\n .trim() || value\n options.push({ value, label })\n }\n setBaseFieldOptions(options)\n }, [selectedEntityId])\n\n const {\n data: map,\n isLoading: loadingMap,\n isError: mapError,\n refetch: refetchMap,\n } = useQuery<EncryptionMapResponse>({\n queryKey: ['encryption-map', selectedEntityId, scopeVersion],\n enabled: !!selectedEntityId,\n queryFn: async () =>\n readApiResultOrThrow(`/api/entities/encryption?entityId=${encodeURIComponent(selectedEntityId)}`, undefined, {\n errorMessage: t('entities.encryption.errors.loadMap', 'Failed to load encryption map'),\n }),\n })\n\n const mapSignature = React.useMemo(() => JSON.stringify(map ?? null), [map])\n const lastMapSignatureRef = React.useRef<string | null>(null)\n\n React.useEffect(() => {\n const signature = mapSignature\n const isSameMap = signature === lastMapSignatureRef.current\n if (isSameMap && hasUserEdited) return\n if (!map) {\n setFields([])\n setIsActive(true)\n setHasUserEdited(false)\n lastMapSignatureRef.current = signature\n return\n }\n setFields(normalizeFieldRows(map, canonicalOptions))\n setIsActive(map?.isActive !== false)\n setHasUserEdited(false)\n lastMapSignatureRef.current = signature\n }, [mapSignature, map, canonicalOptions, hasUserEdited])\n\n const mutation = useMutation({\n mutationFn: async () => {\n const trimmed = fields\n .map((row) => ({\n field: canonicalizeFieldName(row.field, canonicalOptions).trim(),\n hashField: row.hashField ? canonicalizeFieldName(row.hashField, canonicalOptions).trim() : '',\n }))\n .filter((row) => row.field.length > 0)\n .map((row) => ({\n field: row.field,\n hashField: row.hashField ? row.hashField : null,\n }))\n if (!selectedEntityId) {\n throw new Error(t('entities.encryption.errors.selectEntity', 'Select an entity before saving'))\n }\n if (!trimmed.length) {\n throw new Error(t('entities.encryption.errors.noFields', 'Add at least one field to encrypt'))\n }\n const res = await apiCall('/api/entities/encryption', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ entityId: selectedEntityId, fields: trimmed, isActive }),\n })\n if (!res.ok) {\n await raiseCrudError(res.response, t('entities.encryption.errors.save', 'Failed to save encryption map'))\n }\n return true\n },\n onSuccess: () => {\n flash(t('entities.encryption.flash.saved', 'Encryption map saved'), 'success')\n void refetchMap()\n },\n onError: (err: any) => {\n const message = err?.message || t('entities.encryption.errors.save', 'Failed to save encryption map')\n flash(message, 'error')\n },\n })\n\n const addField = () => {\n setHasUserEdited(true)\n setFields((prev) => [...prev, { id: buildRowId(), field: '', hashField: null }])\n }\n\n const updateField = (id: string, patch: Partial<EncryptionFieldRow>) => {\n setHasUserEdited(true)\n setFields((prev) => prev.map((row) => (row.id === id ? { ...row, ...patch } : row)))\n }\n\n const removeField = (id: string) => {\n setHasUserEdited(true)\n setFields((prev) => prev.filter((row) => row.id !== id))\n }\n\n const renderFields = () => {\n if (loadingMap || loadingFieldDefs) {\n return (\n <LoadingMessage\n label={t('entities.encryption.loading', 'Loading encryption map\u2026')}\n className=\"border-0 bg-transparent p-4\"\n />\n )\n }\n if (mapError) {\n return (\n <ErrorMessage\n label={t('entities.encryption.errors.loadMap', 'Failed to load encryption map')}\n action={(\n <Button variant=\"outline\" size=\"sm\" onClick={() => void refetchMap()}>\n {t('entities.encryption.actions.retry', 'Retry')}\n </Button>\n )}\n />\n )\n }\n if (!fields.length) {\n return (\n <div className=\"rounded border bg-background/80 p-4 text-sm text-muted-foreground\">\n {t('entities.encryption.empty', 'No fields are encrypted yet. Add the first one below.')}\n </div>\n )\n }\n const withFallbackOption = (value?: string | null) => {\n if (value && !fieldOptions.some((opt) => opt.value === value)) {\n return [...fieldOptions, { value, label: value }]\n }\n return fieldOptions\n }\n return (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[720px] text-sm\">\n <thead>\n <tr className=\"text-xs uppercase tracking-wide text-muted-foreground\">\n <th className=\"px-3 py-2 text-left\">\n {t('entities.encryption.fields.field', 'Field name')}\n </th>\n <th className=\"px-3 py-2 text-left\">\n {t('entities.encryption.fields.hash', 'Hash field (optional)')}\n </th>\n <th className=\"px-3 py-2 text-right\">\n {t('entities.encryption.fields.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody>\n {fields.map((row) => {\n const fieldOpts = withFallbackOption(row.field)\n const hashOpts = withFallbackOption(row.hashField)\n return (\n <tr key={row.id} className=\"border-t\">\n <td className=\"px-3 py-2 align-top\">\n <Select\n value={row.field || undefined}\n onValueChange={(value) => updateField(row.id, { field: value ?? '' })}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.encryption.fields.selectField', 'Select field')} />\n </SelectTrigger>\n <SelectContent>\n {fieldOpts.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </td>\n <td className=\"px-3 py-2 align-top\">\n <Select\n value={row.hashField || undefined}\n onValueChange={(value) => updateField(row.id, { hashField: value || null })}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('entities.encryption.fields.selectHash', 'Select hash field (optional)')} />\n </SelectTrigger>\n <SelectContent>\n {hashOpts.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"mt-1 text-overline text-muted-foreground\">\n {t('entities.encryption.fields.hashHint', 'Use when lookups must stay deterministic (e.g., login by email).')}\n </p>\n </td>\n <td className=\"px-3 py-2 align-top text-right\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-9 px-0\"\n aria-label={t('entities.encryption.actions.remove', 'Remove')}\n onClick={() => removeField(row.id)}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </td>\n </tr>\n )\n })}\n </tbody>\n </table>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-6\">\n <div className=\"flex flex-col gap-3 rounded-lg border bg-card p-4 shadow-sm\">\n <div className=\"space-y-2\">\n <h2 className=\"text-xl font-semibold\">{t('entities.encryption.title', 'Encryption')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('entities.encryption.description', 'Manage which entity fields are encrypted with tenant keys and optional hash columns.')}\n </p>\n </div>\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-end\">\n <div className=\"flex-1 space-y-3\">\n <div>\n <label className=\"text-xs text-muted-foreground\">\n {t('entities.encryption.selectEntity', 'Choose entity')}\n </label>\n <Select\n value={selectedEntityId || undefined}\n onValueChange={(value) => setSelectedEntityId(value ?? '')}\n disabled={loadingEntities || !!entitiesError}\n >\n <SelectTrigger className=\"mt-1\">\n <SelectValue placeholder={t('entities.encryption.placeholder', 'Select an entity')} />\n </SelectTrigger>\n <SelectContent>\n {(entities?.items || []).map((item) => (\n <SelectItem key={item.entityId} value={item.entityId}>\n {item.label || item.entityId} {item.source === 'custom' ? `(${t('entities.encryption.source.custom', 'custom')})` : ''}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {entitiesError ? (\n <p className=\"mt-1 text-xs text-red-600\">\n {t('entities.encryption.errors.loadEntities', 'Failed to load entities')}\n </p>\n ) : (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {t('entities.encryption.entityHint', 'Maps apply per tenant/organization. Use field names from your entities.')}\n </p>\n )}\n </div>\n <label className=\"inline-flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={isActive}\n onChange={(event) => setIsActive(event.target.checked)}\n />\n {t('entities.encryption.active', 'Encryption enabled for this entity')}\n </label>\n </div>\n </div>\n <div className=\"rounded-lg border bg-background/80 p-4\">\n <div className=\"mb-3 flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-medium\">{t('entities.encryption.fields.title', 'Encrypted fields')}</h3>\n <p className=\"text-xs text-muted-foreground\">\n {t('entities.encryption.fields.subtitle', 'List the attributes that should be encrypted with the tenant key.')}\n </p>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={addField}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {t('entities.encryption.actions.add', 'Add field')}\n </Button>\n </div>\n {renderFields()}\n </div>\n <div className=\"flex justify-end\">\n <Button\n onClick={() => mutation.mutate()}\n disabled={mutation.isPending || loadingEntities || !!entitiesError || !selectedEntityId}\n >\n <Save className=\"mr-2 h-4 w-4\" />\n {mutation.isPending\n ? t('entities.encryption.actions.saving', 'Saving\u2026')\n : t('entities.encryption.actions.save', 'Save encryption map')}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,14 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { JsonBuilder } from "@open-mercato/ui/backend/JsonBuilder";
4
+ import { Input } from "@open-mercato/ui/primitives/input";
5
+ import {
6
+ Select,
7
+ SelectContent,
8
+ SelectItem,
9
+ SelectTrigger,
10
+ SelectValue
11
+ } from "@open-mercato/ui/primitives/select";
4
12
  import { useT } from "@open-mercato/shared/lib/i18n/context";
5
13
  function renderDefaultValueCreateComponent(props) {
6
14
  const t = useT();
@@ -10,15 +18,17 @@ function renderDefaultValueCreateComponent(props) {
10
18
  return /* @__PURE__ */ jsxs("div", { children: [
11
19
  /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: t("feature_toggles.form.fields.defaultValue.boolean.label", "Default Value (Boolean)") }),
12
20
  /* @__PURE__ */ jsxs(
13
- "select",
21
+ Select,
14
22
  {
15
23
  value: props.value || "false",
16
- onChange: (e) => props.setValue(e.target.value === "true"),
17
- className: "w-full h-9 rounded border px-2 text-sm",
24
+ onValueChange: (value) => props.setValue(value === "true"),
18
25
  disabled: props.disabled,
19
26
  children: [
20
- /* @__PURE__ */ jsx("option", { value: "true", children: t("feature_toggles.values.true", "True") }),
21
- /* @__PURE__ */ jsx("option", { value: "false", children: t("feature_toggles.values.false", "False") })
27
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
28
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
29
+ /* @__PURE__ */ jsx(SelectItem, { value: "true", children: t("feature_toggles.values.true", "True") }),
30
+ /* @__PURE__ */ jsx(SelectItem, { value: "false", children: t("feature_toggles.values.false", "False") })
31
+ ] })
22
32
  ]
23
33
  }
24
34
  )
@@ -27,13 +37,12 @@ function renderDefaultValueCreateComponent(props) {
27
37
  return /* @__PURE__ */ jsxs("div", { children: [
28
38
  /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: t("feature_toggles.form.fields.defaultValue.string.label", "Default Value (String)") }),
29
39
  /* @__PURE__ */ jsx(
30
- "input",
40
+ Input,
31
41
  {
32
42
  type: "text",
33
43
  value: props.value || "",
34
44
  onChange: (e) => props.setValue(e.target.value),
35
45
  placeholder: t("feature_toggles.form.fields.defaultValue.string.placeholder", "Enter default string value"),
36
- className: "w-full h-9 rounded border px-2 text-sm",
37
46
  disabled: props.disabled,
38
47
  autoFocus: props.autoFocus
39
48
  }
@@ -43,12 +52,11 @@ function renderDefaultValueCreateComponent(props) {
43
52
  return /* @__PURE__ */ jsxs("div", { children: [
44
53
  /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: t("feature_toggles.form.fields.defaultValue.number.label", "Default Value (Number)") }),
45
54
  /* @__PURE__ */ jsx(
46
- "input",
55
+ Input,
47
56
  {
48
57
  type: "number",
49
58
  value: props.value || 0,
50
59
  onChange: (e) => props.setValue(Number(e.target.value) || 0),
51
- className: "w-full h-9 rounded border px-2 text-sm",
52
60
  disabled: props.disabled,
53
61
  autoFocus: props.autoFocus
54
62
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/feature_toggles/components/formConfig.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport { CrudFormGroup, CrudCustomFieldRenderProps, CrudField } from \"@open-mercato/ui/backend/CrudForm\";\nimport { JsonBuilder } from \"@open-mercato/ui/backend/JsonBuilder\";\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\n\nexport function renderDefaultValueCreateComponent(props: CrudCustomFieldRenderProps) {\n const t = useT()\n const selectedType = props.values?.type as string;\n\n switch (selectedType) {\n case 'boolean':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.boolean.label', 'Default Value (Boolean)')}</label>\n <select\n value={props.value as string || 'false'}\n onChange={(e) => props.setValue(e.target.value === 'true')}\n className=\"w-full h-9 rounded border px-2 text-sm\"\n disabled={props.disabled}\n >\n <option value=\"true\">{t('feature_toggles.values.true', 'True')}</option>\n <option value=\"false\">{t('feature_toggles.values.false', 'False')}</option>\n </select>\n </div>\n );\n\n case 'string':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.string.label', 'Default Value (String)')}</label>\n <input\n type=\"text\"\n value={props.value as string || ''}\n onChange={(e) => props.setValue(e.target.value)}\n placeholder={t('feature_toggles.form.fields.defaultValue.string.placeholder', 'Enter default string value')}\n className=\"w-full h-9 rounded border px-2 text-sm\"\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'number':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.number.label', 'Default Value (Number)')}</label>\n <input\n type=\"number\"\n value={props.value as number || 0}\n onChange={(e) => props.setValue(Number(e.target.value) || 0)}\n className=\"w-full h-9 rounded border px-2 text-sm\"\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'json':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.json.label', 'Default Value (JSON)')}</label>\n <JsonBuilder\n value={props.value}\n onChange={props.setValue}\n disabled={props.disabled}\n />\n </div>\n );\n\n default:\n return (\n <div className=\"text-sm text-muted-foreground p-4 text-center bg-muted/30 rounded border border-dashed\">\n {t('feature_toggles.form.fields.defaultValue.selectType', 'Please select a type above to configure the default value')}\n </div>\n );\n }\n}\n\nexport function createFieldDefinitions(\n t: (key: string) => string,\n): CrudField[] {\n return [\n {\n id: 'identifier',\n label: t('feature_toggles.form.fields.identifier.label'),\n type: 'text',\n required: true,\n },\n {\n id: 'name',\n label: t('feature_toggles.form.fields.name.label'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('feature_toggles.form.fields.description.label'),\n type: 'textarea',\n required: false,\n },\n {\n id: 'category',\n label: t('feature_toggles.form.fields.category.label'),\n type: 'text',\n required: false,\n },\n {\n id: 'type',\n label: t('feature_toggles.form.fields.type.label'),\n type: 'select',\n required: true,\n options: [\n { label: t('feature_toggles.types.boolean'), value: 'boolean' },\n { label: t('feature_toggles.types.string'), value: 'string' },\n { label: t('feature_toggles.types.number'), value: 'number' },\n { label: t('feature_toggles.types.json'), value: 'json' },\n ],\n },\n {\n id: 'defaultValue',\n label: '',\n type: 'custom',\n component: renderDefaultValueCreateComponent,\n description: t('feature_toggles.form.fields.defaultValue.description'),\n },\n ]\n}\n\nexport function createFormGroups(\n t: (key: string) => string,\n): CrudFormGroup[] {\n return [\n {\n id: 'basic',\n title: t('feature_toggles.form.groups.basic'),\n column: 1,\n fields: [\n 'identifier',\n 'name',\n 'description',\n 'category',\n ],\n },\n {\n id: 'type',\n title: t('feature_toggles.form.groups.type'),\n column: 1,\n fields: ['type'],\n },\n {\n id: 'defaultValue',\n title: t('feature_toggles.form.groups.defaultValue'),\n column: 1,\n fields: ['defaultValue'],\n },\n ]\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport { CrudFormGroup, CrudCustomFieldRenderProps, CrudField } from \"@open-mercato/ui/backend/CrudForm\";\nimport { JsonBuilder } from \"@open-mercato/ui/backend/JsonBuilder\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@open-mercato/ui/primitives/select\";\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\n\nexport function renderDefaultValueCreateComponent(props: CrudCustomFieldRenderProps) {\n const t = useT()\n const selectedType = props.values?.type as string;\n\n switch (selectedType) {\n case 'boolean':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.boolean.label', 'Default Value (Boolean)')}</label>\n <Select\n value={props.value as string || 'false'}\n onValueChange={(value) => props.setValue(value === 'true')}\n disabled={props.disabled}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">{t('feature_toggles.values.true', 'True')}</SelectItem>\n <SelectItem value=\"false\">{t('feature_toggles.values.false', 'False')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n );\n\n case 'string':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.string.label', 'Default Value (String)')}</label>\n <Input\n type=\"text\"\n value={props.value as string || ''}\n onChange={(e) => props.setValue(e.target.value)}\n placeholder={t('feature_toggles.form.fields.defaultValue.string.placeholder', 'Enter default string value')}\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'number':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.number.label', 'Default Value (Number)')}</label>\n <Input\n type=\"number\"\n value={props.value as number || 0}\n onChange={(e) => props.setValue(Number(e.target.value) || 0)}\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'json':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.form.fields.defaultValue.json.label', 'Default Value (JSON)')}</label>\n <JsonBuilder\n value={props.value}\n onChange={props.setValue}\n disabled={props.disabled}\n />\n </div>\n );\n\n default:\n return (\n <div className=\"text-sm text-muted-foreground p-4 text-center bg-muted/30 rounded border border-dashed\">\n {t('feature_toggles.form.fields.defaultValue.selectType', 'Please select a type above to configure the default value')}\n </div>\n );\n }\n}\n\nexport function createFieldDefinitions(\n t: (key: string) => string,\n): CrudField[] {\n return [\n {\n id: 'identifier',\n label: t('feature_toggles.form.fields.identifier.label'),\n type: 'text',\n required: true,\n },\n {\n id: 'name',\n label: t('feature_toggles.form.fields.name.label'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('feature_toggles.form.fields.description.label'),\n type: 'textarea',\n required: false,\n },\n {\n id: 'category',\n label: t('feature_toggles.form.fields.category.label'),\n type: 'text',\n required: false,\n },\n {\n id: 'type',\n label: t('feature_toggles.form.fields.type.label'),\n type: 'select',\n required: true,\n options: [\n { label: t('feature_toggles.types.boolean'), value: 'boolean' },\n { label: t('feature_toggles.types.string'), value: 'string' },\n { label: t('feature_toggles.types.number'), value: 'number' },\n { label: t('feature_toggles.types.json'), value: 'json' },\n ],\n },\n {\n id: 'defaultValue',\n label: '',\n type: 'custom',\n component: renderDefaultValueCreateComponent,\n description: t('feature_toggles.form.fields.defaultValue.description'),\n },\n ]\n}\n\nexport function createFormGroups(\n t: (key: string) => string,\n): CrudFormGroup[] {\n return [\n {\n id: 'basic',\n title: t('feature_toggles.form.groups.basic'),\n column: 1,\n fields: [\n 'identifier',\n 'name',\n 'description',\n 'category',\n ],\n },\n {\n id: 'type',\n title: t('feature_toggles.form.groups.type'),\n column: 1,\n fields: ['type'],\n },\n {\n id: 'defaultValue',\n title: t('feature_toggles.form.groups.defaultValue'),\n column: 1,\n fields: ['defaultValue'],\n },\n ]\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,14 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { JsonBuilder } from "@open-mercato/ui/backend/JsonBuilder";
4
+ import { Input } from "@open-mercato/ui/primitives/input";
5
+ import {
6
+ Select,
7
+ SelectContent,
8
+ SelectItem,
9
+ SelectTrigger,
10
+ SelectValue
11
+ } from "@open-mercato/ui/primitives/select";
4
12
  import { useT } from "@open-mercato/shared/lib/i18n/context";
5
13
  function renderOverrideValueComponent(props) {
6
14
  const t = useT();
@@ -14,15 +22,17 @@ function renderOverrideValueComponent(props) {
14
22
  return /* @__PURE__ */ jsxs("div", { children: [
15
23
  /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: t("feature_toggles.override.fields.value.boolean.label", "Override Value (Boolean)") }),
16
24
  /* @__PURE__ */ jsxs(
17
- "select",
25
+ Select,
18
26
  {
19
27
  value: props.value || "false",
20
- onChange: (e) => props.setValue(e.target.value === "true"),
21
- className: "w-full h-9 rounded border px-2 text-sm",
28
+ onValueChange: (value) => props.setValue(value === "true"),
22
29
  disabled: props.disabled,
23
30
  children: [
24
- /* @__PURE__ */ jsx("option", { value: "true", children: t("feature_toggles.values.true", "True") }),
25
- /* @__PURE__ */ jsx("option", { value: "false", children: t("feature_toggles.values.false", "False") })
31
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
32
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
33
+ /* @__PURE__ */ jsx(SelectItem, { value: "true", children: t("feature_toggles.values.true", "True") }),
34
+ /* @__PURE__ */ jsx(SelectItem, { value: "false", children: t("feature_toggles.values.false", "False") })
35
+ ] })
26
36
  ]
27
37
  }
28
38
  )
@@ -31,13 +41,12 @@ function renderOverrideValueComponent(props) {
31
41
  return /* @__PURE__ */ jsxs("div", { children: [
32
42
  /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: t("feature_toggles.override.fields.value.string.label", "Override Value (String)") }),
33
43
  /* @__PURE__ */ jsx(
34
- "input",
44
+ Input,
35
45
  {
36
46
  type: "text",
37
47
  value: props.value || "",
38
48
  onChange: (e) => props.setValue(e.target.value),
39
49
  placeholder: t("feature_toggles.override.fields.value.string.placeholder", "Enter override string value"),
40
- className: "w-full h-9 rounded border px-2 text-sm",
41
50
  disabled: props.disabled,
42
51
  autoFocus: props.autoFocus
43
52
  }
@@ -47,12 +56,11 @@ function renderOverrideValueComponent(props) {
47
56
  return /* @__PURE__ */ jsxs("div", { children: [
48
57
  /* @__PURE__ */ jsx("label", { className: "block text-sm font-medium mb-2", children: t("feature_toggles.override.fields.value.number.label", "Override Value (Number)") }),
49
58
  /* @__PURE__ */ jsx(
50
- "input",
59
+ Input,
51
60
  {
52
61
  type: "number",
53
62
  value: props.value || 0,
54
63
  onChange: (e) => props.setValue(Number(e.target.value) || 0),
55
- className: "w-full h-9 rounded border px-2 text-sm",
56
64
  disabled: props.disabled,
57
65
  autoFocus: props.autoFocus
58
66
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/feature_toggles/components/overrideFormConfig.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport { CrudFormGroup, CrudCustomFieldRenderProps, CrudField } from \"@open-mercato/ui/backend/CrudForm\";\nimport { JsonBuilder } from \"@open-mercato/ui/backend/JsonBuilder\";\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport function renderOverrideValueComponent(props: CrudCustomFieldRenderProps) {\n const t = useT()\n const toggleType = props.values?.toggleType as string;\n const isOverride = props.values?.isOverride as boolean;\n\n if (!isOverride) {\n return (\n <div className=\"text-sm text-muted-foreground p-4 text-center bg-muted/30 rounded border border-dashed\">\n {t('feature_toggles.override.disabled', 'Override is disabled. Values will be inherited from the default configuration.')}\n </div>\n );\n }\n\n switch (toggleType) {\n case 'boolean':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.boolean.label', 'Override Value (Boolean)')}</label>\n <select\n value={props.value as string || 'false'}\n onChange={(e) => props.setValue(e.target.value === 'true')}\n className=\"w-full h-9 rounded border px-2 text-sm\"\n disabled={props.disabled}\n >\n <option value=\"true\">{t('feature_toggles.values.true', 'True')}</option>\n <option value=\"false\">{t('feature_toggles.values.false', 'False')}</option>\n </select>\n </div>\n );\n\n case 'string':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.string.label', 'Override Value (String)')}</label>\n <input\n type=\"text\"\n value={props.value as string || ''}\n onChange={(e) => props.setValue(e.target.value)}\n placeholder={t('feature_toggles.override.fields.value.string.placeholder', 'Enter override string value')}\n className=\"w-full h-9 rounded border px-2 text-sm\"\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'number':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.number.label', 'Override Value (Number)')}</label>\n <input\n type=\"number\"\n value={props.value as number || 0}\n onChange={(e) => props.setValue(Number(e.target.value) || 0)}\n className=\"w-full h-9 rounded border px-2 text-sm\"\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'json':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.json.label', 'Override Value (JSON)')}</label>\n <JsonBuilder\n value={props.value}\n onChange={props.setValue}\n disabled={props.disabled}\n />\n </div>\n );\n\n default:\n return (\n <div className=\"text-sm text-muted-foreground p-4 text-center bg-muted/30 rounded border border-dashed\">\n {t('feature_toggles.override.unknownType', 'Unknown toggle type. Cannot configure override value.')}\n </div>\n );\n }\n}\n\nexport function createOverrideFieldDefinitions(\n t: (key: string) => string,\n): CrudField[] {\n return [\n {\n id: 'isOverride',\n label: t('feature_toggles.override.fields.isOverride.label'),\n type: 'checkbox',\n required: false,\n description: t('feature_toggles.override.fields.isOverride.description'),\n },\n {\n id: 'overrideValue',\n label: '',\n type: 'custom',\n component: renderOverrideValueComponent,\n description: t('feature_toggles.override.fields.overrideValue.description'),\n },\n ]\n}\n\nexport function createOverrideFormGroups(\n t: (key: string) => string,\n): CrudFormGroup[] {\n return [\n {\n id: 'overrideMode',\n title: t('feature_toggles.override.groups.mode'),\n column: 1,\n fields: ['isOverride'],\n },\n {\n id: 'overrideValue',\n title: t('feature_toggles.override.groups.value'),\n column: 1,\n fields: ['overrideValue'],\n },\n ]\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport { CrudFormGroup, CrudCustomFieldRenderProps, CrudField } from \"@open-mercato/ui/backend/CrudForm\";\nimport { JsonBuilder } from \"@open-mercato/ui/backend/JsonBuilder\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@open-mercato/ui/primitives/select\";\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport function renderOverrideValueComponent(props: CrudCustomFieldRenderProps) {\n const t = useT()\n const toggleType = props.values?.toggleType as string;\n const isOverride = props.values?.isOverride as boolean;\n\n if (!isOverride) {\n return (\n <div className=\"text-sm text-muted-foreground p-4 text-center bg-muted/30 rounded border border-dashed\">\n {t('feature_toggles.override.disabled', 'Override is disabled. Values will be inherited from the default configuration.')}\n </div>\n );\n }\n\n switch (toggleType) {\n case 'boolean':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.boolean.label', 'Override Value (Boolean)')}</label>\n <Select\n value={props.value as string || 'false'}\n onValueChange={(value) => props.setValue(value === 'true')}\n disabled={props.disabled}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">{t('feature_toggles.values.true', 'True')}</SelectItem>\n <SelectItem value=\"false\">{t('feature_toggles.values.false', 'False')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n );\n\n case 'string':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.string.label', 'Override Value (String)')}</label>\n <Input\n type=\"text\"\n value={props.value as string || ''}\n onChange={(e) => props.setValue(e.target.value)}\n placeholder={t('feature_toggles.override.fields.value.string.placeholder', 'Enter override string value')}\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'number':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.number.label', 'Override Value (Number)')}</label>\n <Input\n type=\"number\"\n value={props.value as number || 0}\n onChange={(e) => props.setValue(Number(e.target.value) || 0)}\n disabled={props.disabled}\n autoFocus={props.autoFocus}\n />\n </div>\n );\n\n case 'json':\n return (\n <div>\n <label className=\"block text-sm font-medium mb-2\">{t('feature_toggles.override.fields.value.json.label', 'Override Value (JSON)')}</label>\n <JsonBuilder\n value={props.value}\n onChange={props.setValue}\n disabled={props.disabled}\n />\n </div>\n );\n\n default:\n return (\n <div className=\"text-sm text-muted-foreground p-4 text-center bg-muted/30 rounded border border-dashed\">\n {t('feature_toggles.override.unknownType', 'Unknown toggle type. Cannot configure override value.')}\n </div>\n );\n }\n}\n\nexport function createOverrideFieldDefinitions(\n t: (key: string) => string,\n): CrudField[] {\n return [\n {\n id: 'isOverride',\n label: t('feature_toggles.override.fields.isOverride.label'),\n type: 'checkbox',\n required: false,\n description: t('feature_toggles.override.fields.isOverride.description'),\n },\n {\n id: 'overrideValue',\n label: '',\n type: 'custom',\n component: renderOverrideValueComponent,\n description: t('feature_toggles.override.fields.overrideValue.description'),\n },\n ]\n}\n\nexport function createOverrideFormGroups(\n t: (key: string) => string,\n): CrudFormGroup[] {\n return [\n {\n id: 'overrideMode',\n title: t('feature_toggles.override.groups.mode'),\n column: 1,\n fields: ['isOverride'],\n },\n {\n id: 'overrideValue',\n title: t('feature_toggles.override.groups.value'),\n column: 1,\n fields: ['overrideValue'],\n },\n ]\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -4,6 +4,13 @@ import * as React from "react";
4
4
  import Link from "next/link";
5
5
  import { Page, PageBody } from "@open-mercato/ui/backend/Page";
6
6
  import { Button } from "@open-mercato/ui/primitives/button";
7
+ import {
8
+ Select,
9
+ SelectContent,
10
+ SelectItem,
11
+ SelectTrigger,
12
+ SelectValue
13
+ } from "@open-mercato/ui/primitives/select";
7
14
  import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
8
15
  import { flash } from "@open-mercato/ui/backend/FlashMessages";
9
16
  import { LoadingMessage, ErrorMessage } from "@open-mercato/ui/backend/detail";
@@ -57,8 +64,7 @@ function InboxSettingsPage() {
57
64
  setTimeout(() => setCopied(false), 2e3);
58
65
  }
59
66
  }, [settings]);
60
- const handleLanguageChange = React.useCallback(async (event) => {
61
- const workingLanguage = event.target.value;
67
+ const handleLanguageChange = React.useCallback(async (workingLanguage) => {
62
68
  setIsSavingLanguage(true);
63
69
  const result = await runMutation({
64
70
  operation: () => apiCall("/api/inbox_ops/settings", {
@@ -99,15 +105,16 @@ function InboxSettingsPage() {
99
105
  /* @__PURE__ */ jsxs("div", { children: [
100
106
  /* @__PURE__ */ jsx("label", { htmlFor: "working-language", className: "text-sm font-medium text-foreground", children: t("inbox_ops.settings.working_language", "Working Language") }),
101
107
  /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: t("inbox_ops.settings.working_language_hint", "AI summaries and action descriptions will be generated in this language") }),
102
- /* @__PURE__ */ jsx(
103
- "select",
108
+ /* @__PURE__ */ jsxs(
109
+ Select,
104
110
  {
105
- id: "working-language",
106
- className: "mt-2 block w-full sm:w-[200px] h-11 md:h-9 rounded-md border border-input bg-background px-3 text-sm",
107
111
  value: settings.workingLanguage || "en",
108
- onChange: handleLanguageChange,
112
+ onValueChange: (value) => handleLanguageChange(value),
109
113
  disabled: isSavingLanguage,
110
- children: languageOptions.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
114
+ children: [
115
+ /* @__PURE__ */ jsx(SelectTrigger, { id: "working-language", className: "mt-2 sm:w-[200px]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
116
+ /* @__PURE__ */ jsx(SelectContent, { children: languageOptions.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
117
+ ]
111
118
  }
112
119
  )
113
120
  ] })