@rebasepro/admin 0.4.0 → 0.6.0

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 (353) hide show
  1. package/README.md +135 -0
  2. package/dist/CollectionEditorDialog-jA-PLh6N.js +3549 -0
  3. package/dist/CollectionEditorDialog-jA-PLh6N.js.map +1 -0
  4. package/dist/CollectionsStudioView-UKouBPOm.js +170 -0
  5. package/dist/CollectionsStudioView-UKouBPOm.js.map +1 -0
  6. package/dist/PropertyEditView-DEUddmg_.js +3660 -0
  7. package/dist/PropertyEditView-DEUddmg_.js.map +1 -0
  8. package/dist/collection_editor/ConfigControllerProvider.d.ts +2 -2
  9. package/dist/collection_editor/ui/AddKanbanColumnAction.d.ts +2 -1
  10. package/dist/collection_editor/ui/CollectionViewHeaderAction.d.ts +2 -1
  11. package/dist/collection_editor/ui/EditorCollectionAction.d.ts +1 -1
  12. package/dist/collection_editor/ui/EditorCollectionActionStart.d.ts +1 -1
  13. package/dist/collection_editor/ui/EditorEntityAction.d.ts +1 -1
  14. package/dist/collection_editor/ui/HomePageEditorCollectionAction.d.ts +1 -1
  15. package/dist/collection_editor/ui/KanbanSetupAction.d.ts +2 -1
  16. package/dist/collection_editor/ui/MissingReferenceWidget.d.ts +1 -1
  17. package/dist/collection_editor/ui/NewCollectionButton.d.ts +1 -1
  18. package/dist/collection_editor/ui/NewCollectionCard.d.ts +1 -1
  19. package/dist/collection_editor/ui/PropertyAddColumnComponent.d.ts +1 -1
  20. package/dist/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.d.ts +1 -1
  21. package/dist/collection_editor/ui/collection_editor/AIModifiedPathsContext.d.ts +1 -1
  22. package/dist/collection_editor/ui/collection_editor/CollectionDetailsForm.d.ts +2 -1
  23. package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +2 -2
  24. package/dist/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.d.ts +2 -2
  25. package/dist/collection_editor/ui/collection_editor/CollectionJsonImportDialog.d.ts +2 -1
  26. package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -1
  27. package/dist/collection_editor/ui/collection_editor/CollectionRLSTab.d.ts +2 -1
  28. package/dist/collection_editor/ui/collection_editor/CollectionRelationsTab.d.ts +2 -1
  29. package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +2 -1
  30. package/dist/collection_editor/ui/collection_editor/CollectionYupValidation.d.ts +1 -9
  31. package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +2 -1
  32. package/dist/collection_editor/ui/collection_editor/DisplaySettingsForm.d.ts +2 -1
  33. package/dist/collection_editor/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
  34. package/dist/collection_editor/ui/collection_editor/EntityActionsSelectDialog.d.ts +2 -1
  35. package/dist/collection_editor/ui/collection_editor/EntityCustomViewsSelectDialog.d.ts +2 -1
  36. package/dist/collection_editor/ui/collection_editor/EnumForm.d.ts +2 -1
  37. package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +2 -1
  38. package/dist/collection_editor/ui/collection_editor/GetCodeDialog.d.ts +2 -1
  39. package/dist/collection_editor/ui/collection_editor/KanbanConfigSection.d.ts +2 -1
  40. package/dist/collection_editor/ui/collection_editor/LayoutModeSwitch.d.ts +1 -1
  41. package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +4 -3
  42. package/dist/collection_editor/ui/collection_editor/PropertyFieldPreview.d.ts +2 -2
  43. package/dist/collection_editor/ui/collection_editor/PropertyTree.d.ts +2 -2
  44. package/dist/collection_editor/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
  45. package/dist/collection_editor/ui/collection_editor/SwitchControl.d.ts +2 -1
  46. package/dist/collection_editor/ui/collection_editor/ViewModeSwitch.d.ts +1 -1
  47. package/dist/collection_editor/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +1 -1
  48. package/dist/collection_editor/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +3 -2
  49. package/dist/collection_editor/ui/collection_editor/properties/BlockPropertyField.d.ts +2 -1
  50. package/dist/collection_editor/ui/collection_editor/properties/BooleanPropertyField.d.ts +2 -1
  51. package/dist/collection_editor/ui/collection_editor/properties/DateTimePropertyField.d.ts +2 -1
  52. package/dist/collection_editor/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
  53. package/dist/collection_editor/ui/collection_editor/properties/KeyValuePropertyField.d.ts +2 -1
  54. package/dist/collection_editor/ui/collection_editor/properties/MapPropertyField.d.ts +2 -1
  55. package/dist/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.d.ts +2 -1
  56. package/dist/collection_editor/ui/collection_editor/properties/NumberPropertyField.d.ts +2 -1
  57. package/dist/collection_editor/ui/collection_editor/properties/ReferencePropertyField.d.ts +3 -2
  58. package/dist/collection_editor/ui/collection_editor/properties/RelationPropertyField.d.ts +2 -1
  59. package/dist/collection_editor/ui/collection_editor/properties/RepeatPropertyField.d.ts +2 -1
  60. package/dist/collection_editor/ui/collection_editor/properties/StoragePropertyField.d.ts +2 -1
  61. package/dist/collection_editor/ui/collection_editor/properties/StringPropertyField.d.ts +2 -1
  62. package/dist/collection_editor/ui/collection_editor/properties/UrlPropertyField.d.ts +2 -1
  63. package/dist/collection_editor/ui/collection_editor/properties/VectorPropertyField.d.ts +2 -1
  64. package/dist/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.d.ts +2 -1
  65. package/dist/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +2 -1
  66. package/dist/collection_editor/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +1 -1
  67. package/dist/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +2 -1
  68. package/dist/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.d.ts +2 -1
  69. package/dist/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.d.ts +2 -1
  70. package/dist/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.d.ts +2 -1
  71. package/dist/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.d.ts +2 -1
  72. package/dist/collection_editor/ui/collection_editor/properties/validation/ValidationPanel.d.ts +1 -1
  73. package/dist/collection_editor/ui/collection_editor/templates/blog_template.d.ts +1 -1
  74. package/dist/collection_editor/ui/collection_editor/templates/pages_template.d.ts +1 -1
  75. package/dist/collection_editor/ui/collection_editor/templates/products_template.d.ts +1 -1
  76. package/dist/collection_editor/ui/collection_editor/templates/users_template.d.ts +1 -1
  77. package/dist/collection_editor_ui.js +4 -11
  78. package/dist/components/ArrayContainer.d.ts +3 -3
  79. package/dist/components/ClearFilterSortButton.d.ts +1 -1
  80. package/dist/components/CollectionEditorDialogs.d.ts +2 -1
  81. package/dist/components/CollectionPanel.d.ts +2 -27
  82. package/dist/components/DefaultAppBar.d.ts +1 -1
  83. package/dist/components/DefaultDrawer.d.ts +4 -4
  84. package/dist/components/DeleteEntityDialog.d.ts +2 -1
  85. package/dist/components/DrawerNavigationGroup.d.ts +1 -1
  86. package/dist/components/DrawerNavigationItem.d.ts +1 -1
  87. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +1 -1
  88. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -1
  89. package/dist/components/EntityCollectionTable/fields/TableMultipleRelationField.d.ts +3 -3
  90. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +3 -3
  91. package/dist/components/EntityCollectionTable/fields/TableRelationField.d.ts +3 -3
  92. package/dist/components/EntityCollectionTable/fields/TableRelationSelectorField.d.ts +2 -1
  93. package/dist/components/EntityCollectionTable/fields/TableStorageUpload.d.ts +2 -2
  94. package/dist/components/EntityCollectionTable/fields/VirtualTableDateField.d.ts +1 -1
  95. package/dist/components/EntityCollectionTable/fields/VirtualTableInput.d.ts +2 -1
  96. package/dist/components/EntityCollectionTable/fields/VirtualTableNumberInput.d.ts +2 -1
  97. package/dist/components/EntityCollectionTable/fields/VirtualTableSelect.d.ts +1 -1
  98. package/dist/components/EntityCollectionTable/fields/VirtualTableSwitch.d.ts +2 -1
  99. package/dist/components/EntityCollectionTable/fields/VirtualTableUserSelect.d.ts +1 -1
  100. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -1
  101. package/dist/components/EntityCollectionTable/internal/EntityTableCellActions.d.ts +1 -1
  102. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +4 -3
  103. package/dist/components/EntityCollectionView/Board.d.ts +2 -1
  104. package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +1 -1
  105. package/dist/components/EntityCollectionView/BoardSortableList.d.ts +1 -1
  106. package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +1 -1
  107. package/dist/components/EntityCollectionView/EntityCard.d.ts +2 -1
  108. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +1 -1
  109. package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +1 -1
  110. package/dist/components/EntityCollectionView/EntityCollectionListView.d.ts +1 -1
  111. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +0 -24
  112. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +1 -1
  113. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +2 -1
  114. package/dist/components/EntityCollectionView/FilterPresetsButton.d.ts +2 -1
  115. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -1
  116. package/dist/components/EntityCollectionView/SplitListView.d.ts +1 -1
  117. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +2 -1
  118. package/dist/components/EntityDetailView.d.ts +1 -1
  119. package/dist/components/EntityEditView.d.ts +2 -2
  120. package/dist/components/EntityEditViewFormActions.d.ts +2 -1
  121. package/dist/components/EntityJsonPreview.d.ts +2 -1
  122. package/dist/components/EntityPreview.d.ts +3 -3
  123. package/dist/components/EntitySidePanel.d.ts +2 -1
  124. package/dist/components/EntityView.d.ts +2 -1
  125. package/dist/components/FieldCaption.d.ts +1 -1
  126. package/dist/components/HomePage/ContentHomePage.d.ts +1 -1
  127. package/dist/components/HomePage/FavouritesView.d.ts +1 -1
  128. package/dist/components/HomePage/HomePageDnD.d.ts +4 -4
  129. package/dist/components/HomePage/NavigationCard.d.ts +1 -1
  130. package/dist/components/HomePage/NavigationCardBinding.d.ts +2 -1
  131. package/dist/components/HomePage/NavigationGroup.d.ts +2 -2
  132. package/dist/components/HomePage/RenameGroupDialog.d.ts +2 -1
  133. package/dist/components/HomePage/SmallNavigationCard.d.ts +1 -1
  134. package/dist/components/PropertyCollectionView.d.ts +2 -1
  135. package/dist/components/PropertyIdCopyTooltip.d.ts +2 -2
  136. package/dist/components/RebaseAuthGate.d.ts +1 -1
  137. package/dist/components/RebaseLayout.d.ts +1 -1
  138. package/dist/components/RebaseNavigation.d.ts +1 -1
  139. package/dist/components/RebaseRouteDefs.d.ts +1 -1
  140. package/dist/components/RebaseShell.d.ts +1 -1
  141. package/dist/components/ReferenceTable/EntitySelectionTable.d.ts +1 -1
  142. package/dist/components/ReferenceWidget.d.ts +2 -1
  143. package/dist/components/SearchIconsView.d.ts +2 -1
  144. package/dist/components/SelectableTable/SelectableTable.d.ts +2 -2
  145. package/dist/components/SelectableTable/filters/BooleanFilterField.d.ts +2 -1
  146. package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
  147. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  148. package/dist/components/SelectableTable/filters/RelationFilterField.d.ts +2 -1
  149. package/dist/components/SelectableTable/filters/StringNumberFilterField.d.ts +2 -1
  150. package/dist/components/SideDialogs.d.ts +1 -1
  151. package/dist/components/SideEntityProvider.d.ts +1 -1
  152. package/dist/components/admin/CreationResultDialog.d.ts +2 -1
  153. package/dist/components/app/AppBar.d.ts +1 -1
  154. package/dist/components/app/Drawer.d.ts +1 -1
  155. package/dist/components/common/default_entity_actions.d.ts +2 -1
  156. package/dist/components/history/EntityHistoryEntry.d.ts +1 -1
  157. package/dist/components/history/EntityHistoryView.d.ts +1 -1
  158. package/dist/components/history/LastEditedByFormAction.d.ts +2 -1
  159. package/dist/components/history/LastEditedByIndicator.d.ts +2 -1
  160. package/dist/components/history/UserChip.d.ts +1 -1
  161. package/dist/data_export/export/BasicExportAction.d.ts +2 -1
  162. package/dist/data_export/export/ExportCollectionAction.d.ts +1 -1
  163. package/dist/data_import/components/DataNewPropertiesMapping.d.ts +1 -1
  164. package/dist/data_import/components/ImportFileUpload.d.ts +1 -1
  165. package/dist/data_import/components/ImportNewPropertyFieldPreview.d.ts +2 -1
  166. package/dist/data_import/components/ImportSaveInProgress.d.ts +1 -1
  167. package/dist/data_import/import/ImportCollectionAction.d.ts +4 -3
  168. package/dist/editor/components/SlashCommandMenu.d.ts +2 -1
  169. package/dist/editor/editor.d.ts +1 -1
  170. package/dist/editor/selectors/color-selector.d.ts +1 -1
  171. package/dist/editor/selectors/link-selector.d.ts +1 -1
  172. package/dist/editor/selectors/node-selector.d.ts +1 -1
  173. package/dist/editor/selectors/text-buttons.d.ts +1 -1
  174. package/dist/editor.js +2621 -3574
  175. package/dist/editor.js.map +1 -1
  176. package/dist/form/EntityForm.d.ts +2 -1
  177. package/dist/form/EntityFormActions.d.ts +2 -1
  178. package/dist/form/components/FieldHelperText.d.ts +1 -1
  179. package/dist/form/components/FormEntry.d.ts +1 -1
  180. package/dist/form/components/FormLayout.d.ts +1 -1
  181. package/dist/form/components/LabelWithIconAndTooltip.d.ts +1 -1
  182. package/dist/form/components/LocalChangesMenu.d.ts +2 -1
  183. package/dist/form/components/StorageItemPreview.d.ts +2 -1
  184. package/dist/form/components/StorageUploadProgress.d.ts +2 -1
  185. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +2 -1
  186. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +2 -1
  187. package/dist/form/field_bindings/BlockFieldBinding.d.ts +2 -1
  188. package/dist/form/field_bindings/DateTimeFieldBinding.d.ts +2 -1
  189. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +2 -1
  190. package/dist/form/field_bindings/MapFieldBinding.d.ts +2 -1
  191. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +2 -1
  192. package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +2 -1
  193. package/dist/form/field_bindings/MultipleRelationFieldBinding.d.ts +2 -1
  194. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +2 -1
  195. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +2 -1
  196. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -1
  197. package/dist/form/field_bindings/RelationFieldBinding.d.ts +2 -1
  198. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +2 -1
  199. package/dist/form/field_bindings/SelectFieldBinding.d.ts +2 -1
  200. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -2
  201. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +2 -1
  202. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -1
  203. package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +2 -1
  204. package/dist/form/field_bindings/VectorFieldBinding.d.ts +2 -1
  205. package/dist/history-BL49TIDb.js +311 -0
  206. package/dist/history-BL49TIDb.js.map +1 -0
  207. package/dist/hooks/navigation/useBuildNavigationStateController.d.ts +0 -2
  208. package/dist/hooks/navigation/useNavigationResolution.d.ts +5 -6
  209. package/dist/hooks/navigation/useResolvedCollections.d.ts +0 -2
  210. package/dist/hooks/useBreadcrumbsController.d.ts +2 -32
  211. package/dist/index.js +2 -3393
  212. package/dist/markdown-CklalUUk.js +526 -0
  213. package/dist/markdown-CklalUUk.js.map +1 -0
  214. package/dist/preview/components/ArrayEnumPreview.d.ts +2 -1
  215. package/dist/preview/components/EmptyValue.d.ts +2 -1
  216. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  217. package/dist/preview/components/ImagePreview.d.ts +2 -1
  218. package/dist/preview/components/ReferencePreview.d.ts +2 -1
  219. package/dist/preview/components/RelationPreview.d.ts +2 -1
  220. package/dist/preview/components/StorageThumbnail.d.ts +1 -1
  221. package/dist/preview/components/UserPreview.d.ts +6 -3
  222. package/dist/preview/property_previews/ArrayOfMapsPreview.d.ts +2 -1
  223. package/dist/preview/property_previews/ArrayOfReferencesPreview.d.ts +1 -1
  224. package/dist/preview/property_previews/ArrayOfRelationsPreview.d.ts +1 -1
  225. package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +2 -1
  226. package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +2 -1
  227. package/dist/preview/property_previews/ArrayOneOfPreview.d.ts +2 -1
  228. package/dist/preview/property_previews/ArrayPropertyEnumPreview.d.ts +1 -1
  229. package/dist/preview/property_previews/ArrayPropertyPreview.d.ts +2 -1
  230. package/dist/preview/property_previews/MapPropertyPreview.d.ts +3 -2
  231. package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +5 -4
  232. package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
  233. package/dist/routes/RebaseRoute.d.ts +1 -1
  234. package/dist/src-BJ8fkM8y.js +24010 -0
  235. package/dist/src-BJ8fkM8y.js.map +1 -0
  236. package/dist/types/components/PropertyPreviewProps.d.ts +4 -0
  237. package/dist/types/components/formex.d.ts +1 -40
  238. package/dist/types/fields.d.ts +9 -1
  239. package/dist/util/navigation_utils.d.ts +2 -1
  240. package/dist/util/previews.d.ts +5 -0
  241. package/dist/util/property_utils.d.ts +1 -1
  242. package/package.json +29 -27
  243. package/src/collection_editor/ConfigControllerProvider.tsx +10 -7
  244. package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +2 -1
  245. package/src/collection_editor/ui/EditorCollectionAction.tsx +2 -1
  246. package/src/collection_editor/ui/EditorCollectionActionStart.tsx +2 -1
  247. package/src/collection_editor/ui/EditorEntityAction.tsx +2 -1
  248. package/src/collection_editor/ui/KanbanSetupAction.tsx +2 -1
  249. package/src/collection_editor/ui/MissingReferenceWidget.tsx +2 -1
  250. package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +2 -1
  251. package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +2 -3
  252. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +0 -1
  253. package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +8 -4
  254. package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +2 -2
  255. package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +2 -1
  256. package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +2 -1
  257. package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +2 -2
  258. package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +5 -2
  259. package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +2 -1
  260. package/src/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +1 -1
  261. package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +1 -1
  262. package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +1 -1
  263. package/src/collection_editor/ui/collection_editor/templates/products_template.ts +1 -1
  264. package/src/collection_editor/ui/collection_editor/templates/users_template.ts +1 -1
  265. package/src/collection_editor/useLocalCollectionsConfigController.tsx +7 -2
  266. package/src/collection_editor/validateCollectionJson.ts +2 -2
  267. package/src/components/CollectionPanel.tsx +51 -25
  268. package/src/components/DefaultAppBar.tsx +1 -2
  269. package/src/components/DefaultDrawer.tsx +3 -2
  270. package/src/components/DrawerNavigationGroup.tsx +3 -2
  271. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +30 -9
  272. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +1 -1
  273. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -0
  274. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +5 -2
  275. package/src/components/EntityCollectionView/Board.tsx +10 -8
  276. package/src/components/EntityCollectionView/BoardSortableList.tsx +2 -2
  277. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +4 -2
  278. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +14 -4
  279. package/src/components/EntityCollectionView/EntityCollectionListView.tsx +48 -26
  280. package/src/components/EntityCollectionView/EntityCollectionView.tsx +146 -73
  281. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +2 -1
  282. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +3 -2
  283. package/src/components/EntityCollectionView/FilterPresetsButton.tsx +4 -2
  284. package/src/components/EntityCollectionView/ViewModeToggle.tsx +0 -1
  285. package/src/components/EntityCollectionView/useBoardDataController.tsx +17 -15
  286. package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +32 -23
  287. package/src/components/EntityDetailView.tsx +72 -39
  288. package/src/components/EntityEditView.tsx +79 -47
  289. package/src/components/EntitySidePanel.tsx +9 -3
  290. package/src/components/HomePage/ContentHomePage.tsx +3 -3
  291. package/src/components/HomePage/NavigationCard.tsx +5 -5
  292. package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
  293. package/src/components/RebaseLayout.tsx +5 -2
  294. package/src/components/RebaseNavigation.tsx +1 -4
  295. package/src/components/RebaseRouteDefs.tsx +5 -3
  296. package/src/components/SearchIconsView.tsx +1 -1
  297. package/src/components/SelectableTable/SelectableTable.tsx +2 -3
  298. package/src/components/SelectableTable/SelectionStore.ts +9 -3
  299. package/src/components/UserSelector.tsx +92 -2
  300. package/src/components/common/default_entity_actions.tsx +23 -6
  301. package/src/components/field_configs.tsx +6 -3
  302. package/src/editor/editor.tsx +1 -1
  303. package/src/editor/extensions/Image/index.ts +2 -2
  304. package/src/editor/extensions/Image.ts +2 -2
  305. package/src/editor/extensions/clipboard.ts +2 -2
  306. package/src/editor/markdown-it-plugins.d.ts +24 -0
  307. package/src/editor/markdown.ts +2 -3
  308. package/src/form/EntityForm.tsx +21 -15
  309. package/src/form/PropertyFieldBinding.tsx +1 -1
  310. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  311. package/src/form/field_bindings/MapFieldBinding.tsx +5 -47
  312. package/src/form/field_bindings/VectorFieldBinding.tsx +3 -3
  313. package/src/form/validation.ts +17 -15
  314. package/src/hooks/navigation/useBuildNavigationStateController.tsx +3 -6
  315. package/src/hooks/navigation/useNavigationResolution.ts +143 -19
  316. package/src/hooks/navigation/useResolvedCollections.ts +4 -6
  317. package/src/hooks/useBreadcrumbsController.tsx +2 -34
  318. package/src/hooks/useBuildSideEntityController.tsx +25 -3
  319. package/src/preview/PropertyPreview.tsx +6 -2
  320. package/src/preview/components/ReferencePreview.tsx +64 -13
  321. package/src/preview/components/RelationPreview.tsx +101 -13
  322. package/src/preview/components/UserPreview.tsx +5 -14
  323. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  324. package/src/routes/RebaseRoute.tsx +5 -4
  325. package/src/types/components/PropertyPreviewProps.tsx +5 -0
  326. package/src/types/components/formex.tsx +1 -45
  327. package/src/types/fields.tsx +10 -1
  328. package/src/util/navigation_utils.ts +14 -4
  329. package/src/util/previews.ts +101 -4
  330. package/dist/CollectionEditorDialog-Bo86h-d-.js +0 -4574
  331. package/dist/CollectionEditorDialog-Bo86h-d-.js.map +0 -1
  332. package/dist/CollectionsStudioView-bsg4AT_Z.js +0 -217
  333. package/dist/CollectionsStudioView-bsg4AT_Z.js.map +0 -1
  334. package/dist/ExportCollectionAction-Cf-Id5uO.js +0 -446
  335. package/dist/ExportCollectionAction-Cf-Id5uO.js.map +0 -1
  336. package/dist/ImportCollectionAction-LN5sreK9.js +0 -685
  337. package/dist/ImportCollectionAction-LN5sreK9.js.map +0 -1
  338. package/dist/PropertyEditView-jCWCxmCz.js +0 -8197
  339. package/dist/PropertyEditView-jCWCxmCz.js.map +0 -1
  340. package/dist/collection_editor_ui.js.map +0 -1
  341. package/dist/index-BrqSvMG0.js +0 -8
  342. package/dist/index-BrqSvMG0.js.map +0 -1
  343. package/dist/index-Cb0bPnzZ.js +0 -12
  344. package/dist/index-Cb0bPnzZ.js.map +0 -1
  345. package/dist/index-z3H8iqsj.js +0 -462
  346. package/dist/index-z3H8iqsj.js.map +0 -1
  347. package/dist/index.js.map +0 -1
  348. package/dist/markdown-DD2JDU1X.js +0 -618
  349. package/dist/markdown-DD2JDU1X.js.map +0 -1
  350. package/dist/useEntityHistory-UVsSclfZ.js +0 -123
  351. package/dist/useEntityHistory-UVsSclfZ.js.map +0 -1
  352. package/dist/util-CvNp6A-r.js +0 -30505
  353. package/dist/util-CvNp6A-r.js.map +0 -1
@@ -0,0 +1,3660 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
+ import { Bt as ArrayContainer, Ct as getFieldConfig, Zt as FieldCaption, a as namespaceToPropertiesPath, bt as DEFAULT_FIELD_CONFIGS, i as namespaceToPropertiesOrderPath, kn as useCollectionRegistryController, n as getFullIdPath, r as idToPropertiesPath, t as getFullId, wt as getFieldId, yt as PropertyConfigBadge } from "./src-BJ8fkM8y.js";
3
+ import React, { createContext, useCallback, useContext, useDeferredValue, useEffect, useMemo, useRef, useState } from "react";
4
+ import { deepEqual } from "fast-equals";
5
+ import { AlertTriangleIcon, ArrowDownToLineIcon, ArrowUpToLineIcon, Badge, BooleanSwitchWithLabel, Button, Card, CheckSquareIcon, CircularProgress, DebouncedTextField, Dialog, DialogActions, DialogContent, DialogTitle, ErrorBoundary, ExpandablePanel, FileSearchIcon, FunctionSquareIcon, IconButton, InfoLabel, ListIcon, Menu, MenuItem, MinusCircleIcon, MoreVerticalIcon, MultiSelect, MultiSelectItem, Paper, PlusIcon, RefreshCcwIcon, Select, SelectItem, SettingsIcon, TextField, Tooltip, Trash2Icon, Typography, UploadCloudIcon, cls, defaultBorderMixin, iconSize } from "@rebasepro/ui";
6
+ import { isPropertyBuilder, resolveEnumValues } from "@rebasepro/common";
7
+ import { AIModifiedIndicator, ConfirmationDialog, IconForView, useCustomizationController, useSnackbarController, useTranslation } from "@rebasepro/core";
8
+ import { Field, Formex, getIn, useCreateFormex, useFormex } from "@rebasepro/formex";
9
+ import { isValidRegExp, mergeDeep, prettifyIdentifier, serializeRegExp, toSnakeCase } from "@rebasepro/utils";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
12
+ import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
13
+ import { SortableContext, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
14
+ import { CSS } from "@dnd-kit/utilities";
15
+ import { extractEnumFromValues } from "@rebasepro/schema-inference";
16
+ //#region src/collection_editor/ui/collection_editor/EnumForm.tsx
17
+ function EnumForm({ enumValues, onValuesChanged, onError, updateIds, disabled, allowDataInference, getData }) {
18
+ const formex = useCreateFormex({
19
+ initialValues: { enum: enumValues },
20
+ validateOnChange: true,
21
+ validation: (values) => {
22
+ const enumErrors = [];
23
+ let hasAnyError = false;
24
+ if (values.enum) values.enum.forEach((enumValue, index) => {
25
+ const fieldError = {};
26
+ if (!enumValue?.label) {
27
+ fieldError.label = "You must specify a label for this enum value entry";
28
+ hasAnyError = true;
29
+ }
30
+ if (!enumValue?.id) {
31
+ fieldError.id = "You must specify an ID for this enum value entry";
32
+ hasAnyError = true;
33
+ }
34
+ enumErrors[index] = fieldError;
35
+ });
36
+ const errors = hasAnyError ? { enum: enumErrors } : {};
37
+ onError?.(hasAnyError);
38
+ return errors;
39
+ }
40
+ });
41
+ const { values, errors } = formex;
42
+ useEffect(() => {
43
+ if (onValuesChanged) onValuesChanged(values.enum);
44
+ }, [values.enum]);
45
+ return /* @__PURE__ */ jsx(Formex, {
46
+ value: formex,
47
+ children: /* @__PURE__ */ jsx(EnumFormFields, {
48
+ enumValuesPath: "enum",
49
+ values,
50
+ errors,
51
+ shouldUpdateId: updateIds,
52
+ disabled,
53
+ allowDataInference,
54
+ getData
55
+ })
56
+ });
57
+ }
58
+ function EnumFormFields({ values, errors, disabled, enumValuesPath, shouldUpdateId, allowDataInference, getData }) {
59
+ const { setFieldValue } = useFormex();
60
+ const [lastInternalIdAdded, setLastInternalIdAdded] = React.useState();
61
+ const [editDialogIndex, setEditDialogIndex] = React.useState();
62
+ const [inferring, setInferring] = React.useState(false);
63
+ const inferredValues = React.useRef(/* @__PURE__ */ new Set()).current;
64
+ const buildEntry = ({ index, internalId }) => {
65
+ const justAdded = lastInternalIdAdded === internalId;
66
+ const entryError = errors?.enum?.[index];
67
+ return /* @__PURE__ */ jsx(EnumEntry, {
68
+ index,
69
+ disabled,
70
+ enumValuesPath,
71
+ autoFocus: justAdded,
72
+ entryError,
73
+ shouldUpdateId: shouldUpdateId || justAdded,
74
+ onDialogOpen: () => setEditDialogIndex(index),
75
+ inferredEntry: inferredValues.has(values.enum[index]?.id)
76
+ }, `${internalId}`);
77
+ };
78
+ const inferValues = async () => {
79
+ if (!getData) return;
80
+ setInferring(true);
81
+ getData?.().then((data) => {
82
+ if (!data) return;
83
+ const flatData = data.flat();
84
+ const fieldData = Array.from(new Set(flatData));
85
+ const currentEnumValues = values.enum;
86
+ const newEnumValues = extractEnumFromValues(fieldData).filter((enumValue) => {
87
+ if (!enumValue) return false;
88
+ return !currentEnumValues?.some((v) => v.id === enumValue.id);
89
+ });
90
+ newEnumValues.forEach((enumValue) => {
91
+ if (enumValue) inferredValues.add(enumValue.id);
92
+ });
93
+ setFieldValue(enumValuesPath, [...newEnumValues, ...currentEnumValues], true);
94
+ }).catch((e) => {
95
+ console.error(e);
96
+ }).finally(() => setInferring(false));
97
+ };
98
+ return /* @__PURE__ */ jsxs("div", {
99
+ className: "col-span-12",
100
+ children: [/* @__PURE__ */ jsxs("div", {
101
+ className: "ml-3.5 flex flex-row items-center",
102
+ children: [
103
+ /* @__PURE__ */ jsx(ListIcon, {}),
104
+ /* @__PURE__ */ jsx(Typography, {
105
+ variant: "subtitle2",
106
+ className: "ml-2 grow",
107
+ children: "Values"
108
+ }),
109
+ allowDataInference && /* @__PURE__ */ jsxs(Button, {
110
+ loading: inferring,
111
+ disabled: disabled || inferring,
112
+ variant: "text",
113
+ size: "small",
114
+ onClick: inferValues,
115
+ children: [inferring ? /* @__PURE__ */ jsx(CircularProgress, { size: "smallest" }) : /* @__PURE__ */ jsx(RefreshCcwIcon, {}), "Infer values from data"]
116
+ })
117
+ ]
118
+ }), /* @__PURE__ */ jsxs(Paper, {
119
+ className: "p-4 m-1",
120
+ children: [/* @__PURE__ */ jsx(ArrayContainer, {
121
+ droppableId: enumValuesPath,
122
+ addLabel: "Add enum value",
123
+ value: values.enum,
124
+ disabled,
125
+ size: "small",
126
+ buildEntry,
127
+ onInternalIdAdded: setLastInternalIdAdded,
128
+ canAddElements: true,
129
+ onValueChange: (value) => setFieldValue(enumValuesPath, value),
130
+ newDefaultEntry: {
131
+ id: "",
132
+ label: ""
133
+ }
134
+ }), /* @__PURE__ */ jsx(EnumEntryDialog, {
135
+ index: editDialogIndex,
136
+ open: editDialogIndex !== void 0,
137
+ enumValuesPath,
138
+ onClose: () => setEditDialogIndex(void 0)
139
+ })]
140
+ })]
141
+ });
142
+ }
143
+ var EnumEntry = React.memo(function EnumEntryInternal({ index, shouldUpdateId: updateId, enumValuesPath, autoFocus, onDialogOpen, disabled, inferredEntry, entryError }) {
144
+ const { values, handleChange, errors, setFieldValue, touched } = useFormex();
145
+ const shouldUpdateIdRef = React.useRef(!getIn(values, `${enumValuesPath}[${index}].id`));
146
+ const shouldUpdateId = updateId || shouldUpdateIdRef.current;
147
+ const idValue = getIn(values, `${enumValuesPath}[${index}].id`);
148
+ const labelValue = getIn(values, `${enumValuesPath}[${index}].label`);
149
+ const currentLabelRef = React.useRef(labelValue);
150
+ React.useEffect(() => {
151
+ if ((currentLabelRef.current === idValue || !idValue) && shouldUpdateId) setFieldValue(`${enumValuesPath}[${index}].id`, labelValue);
152
+ currentLabelRef.current = labelValue;
153
+ }, [labelValue]);
154
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
155
+ /* @__PURE__ */ jsxs("div", {
156
+ className: "flex w-full align-center justify-center",
157
+ children: [/* @__PURE__ */ jsx(Field, {
158
+ name: `${enumValuesPath}[${index}].label`,
159
+ as: DebouncedTextField,
160
+ className: "grow",
161
+ required: true,
162
+ disabled,
163
+ size: "small",
164
+ autoFocus,
165
+ autoComplete: "off",
166
+ endAdornment: inferredEntry && /* @__PURE__ */ jsx(RefreshCcwIcon, { size: iconSize.small }),
167
+ error: Boolean(entryError?.label)
168
+ }), !disabled && /* @__PURE__ */ jsx(Badge, {
169
+ color: "error",
170
+ invisible: !entryError?.id,
171
+ children: /* @__PURE__ */ jsx(IconButton, {
172
+ size: "small",
173
+ "aria-label": "edit",
174
+ className: "m-1",
175
+ onClick: () => onDialogOpen(),
176
+ children: /* @__PURE__ */ jsx(SettingsIcon, { size: iconSize.small })
177
+ })
178
+ })]
179
+ }),
180
+ entryError?.label && /* @__PURE__ */ jsx(Typography, {
181
+ variant: "caption",
182
+ className: "ml-3.5 text-red-500 dark:text-red-500",
183
+ children: entryError?.label
184
+ }),
185
+ entryError?.id && /* @__PURE__ */ jsx(Typography, {
186
+ variant: "caption",
187
+ className: "ml-3.5 text-red-500 dark:text-red-500",
188
+ children: entryError?.id
189
+ })
190
+ ] });
191
+ }, function areEqual(prevProps, nextProps) {
192
+ return prevProps.index === nextProps.index && prevProps.enumValuesPath === nextProps.enumValuesPath && prevProps.shouldUpdateId === nextProps.shouldUpdateId && prevProps.inferredEntry === nextProps.inferredEntry && deepEqual(prevProps.entryError, nextProps.entryError) && prevProps.autoFocus === nextProps.autoFocus;
193
+ });
194
+ function EnumEntryDialog({ index, open, onClose, enumValuesPath }) {
195
+ const { errors } = useFormex();
196
+ const idError = index !== void 0 ? getIn(errors, `${enumValuesPath}[${index}].id`) : void 0;
197
+ return /* @__PURE__ */ jsxs(Dialog, {
198
+ maxWidth: "md",
199
+ "aria-labelledby": "enum-edit-dialog",
200
+ open,
201
+ onOpenChange: (open) => !open ? onClose() : void 0,
202
+ children: [
203
+ /* @__PURE__ */ jsx(DialogTitle, {
204
+ hidden: true,
205
+ children: "Enum form dialog"
206
+ }),
207
+ /* @__PURE__ */ jsx(DialogContent, { children: index !== void 0 && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Field, {
208
+ name: `${enumValuesPath}[${index}].id`,
209
+ as: DebouncedTextField,
210
+ required: true,
211
+ label: "ID",
212
+ size: "small",
213
+ autoComplete: "off",
214
+ error: Boolean(idError)
215
+ }), /* @__PURE__ */ jsx(FieldCaption, {
216
+ error: Boolean(idError),
217
+ children: idError ?? "Value saved in the data source"
218
+ })] }) }),
219
+ /* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */ jsx(Button, {
220
+ autoFocus: true,
221
+ onClick: onClose,
222
+ children: "Ok"
223
+ }) })
224
+ ]
225
+ });
226
+ }
227
+ //#endregion
228
+ //#region src/collection_editor/ui/collection_editor/SwitchControl.tsx
229
+ function SwitchControl({ field, form, label, tooltip, disabled, size = "small", allowIndeterminate }) {
230
+ const formControlLabel = /* @__PURE__ */ jsx(BooleanSwitchWithLabel, {
231
+ label,
232
+ size,
233
+ position: "start",
234
+ value: field.value,
235
+ disabled,
236
+ allowIndeterminate,
237
+ onValueChange: (checked) => form.setFieldValue(field.name, checked)
238
+ });
239
+ if (tooltip) return /* @__PURE__ */ jsx(Tooltip, {
240
+ title: tooltip,
241
+ children: formControlLabel
242
+ });
243
+ return formControlLabel;
244
+ }
245
+ //#endregion
246
+ //#region src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx
247
+ function GeneralPropertyValidation({ disabled }) {
248
+ const { values, handleChange } = useFormex();
249
+ const { t } = useTranslation();
250
+ const validationRequired = "validation.required";
251
+ const validationRequiredMessage = "validation.requiredMessage";
252
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
253
+ /* @__PURE__ */ jsx("div", {
254
+ className: "col-span-6",
255
+ children: /* @__PURE__ */ jsx(Field, {
256
+ name: validationRequired,
257
+ type: "checkbox",
258
+ children: ({ field, form }) => {
259
+ return /* @__PURE__ */ jsx(SwitchControl, {
260
+ disabled,
261
+ label: t("required"),
262
+ tooltip: t("required_tooltip"),
263
+ form,
264
+ field
265
+ });
266
+ }
267
+ })
268
+ }),
269
+ /* @__PURE__ */ jsx("div", {
270
+ className: "col-span-6",
271
+ children: /* @__PURE__ */ jsx(Field, {
272
+ name: "validation.unique",
273
+ type: "checkbox",
274
+ children: ({ field, form }) => {
275
+ return /* @__PURE__ */ jsx(SwitchControl, {
276
+ disabled,
277
+ label: t("unique"),
278
+ tooltip: t("unique_tooltip"),
279
+ form,
280
+ field
281
+ });
282
+ }
283
+ })
284
+ }),
285
+ getIn(values, validationRequired) && /* @__PURE__ */ jsx("div", {
286
+ className: "col-span-12",
287
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
288
+ disabled,
289
+ value: getIn(values, validationRequiredMessage),
290
+ label: t("required_message"),
291
+ name: validationRequiredMessage,
292
+ size: "small",
293
+ onChange: handleChange
294
+ })
295
+ })
296
+ ] });
297
+ }
298
+ //#endregion
299
+ //#region src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx
300
+ function StringPropertyValidation({ length, lowercase, matches, max, min, trim, uppercase, disabled, showErrors }) {
301
+ const { values, handleChange, errors } = useFormex();
302
+ const { t } = useTranslation();
303
+ const validationLength = "validation.length";
304
+ const validationMin = "validation.min";
305
+ const validationMax = "validation.max";
306
+ const validationTrim = "validation.trim";
307
+ const validationMatches = "validation.matches";
308
+ const validationLowercase = "validation.lowercase";
309
+ const validationUppercase = "validation.uppercase";
310
+ const matchesError = getIn(errors, validationMatches);
311
+ const matchesValue = getIn(values, validationMatches);
312
+ const matchesStringValue = typeof matchesValue === "string" ? matchesValue : serializeRegExp(matchesValue);
313
+ return /* @__PURE__ */ jsxs("div", {
314
+ className: "grid grid-cols-12 gap-2",
315
+ children: [
316
+ /* @__PURE__ */ jsx(GeneralPropertyValidation, { disabled }),
317
+ /* @__PURE__ */ jsxs("div", {
318
+ className: "grid grid-cols-12 gap-2 col-span-12",
319
+ children: [
320
+ lowercase && /* @__PURE__ */ jsx("div", {
321
+ className: "col-span-4",
322
+ children: /* @__PURE__ */ jsx(Field, {
323
+ name: validationLowercase,
324
+ type: "checkbox",
325
+ children: ({ field, form }) => {
326
+ return /* @__PURE__ */ jsx(SwitchControl, {
327
+ label: t("lowercase"),
328
+ disabled,
329
+ form,
330
+ field
331
+ });
332
+ }
333
+ })
334
+ }),
335
+ uppercase && /* @__PURE__ */ jsx("div", {
336
+ className: "col-span-4",
337
+ children: /* @__PURE__ */ jsx(Field, {
338
+ name: validationUppercase,
339
+ type: "checkbox",
340
+ children: ({ field, form }) => {
341
+ return /* @__PURE__ */ jsx(SwitchControl, {
342
+ label: t("uppercase"),
343
+ disabled,
344
+ form,
345
+ field
346
+ });
347
+ }
348
+ })
349
+ }),
350
+ trim && /* @__PURE__ */ jsx("div", {
351
+ className: "col-span-4",
352
+ children: /* @__PURE__ */ jsx(Field, {
353
+ name: validationTrim,
354
+ type: "checkbox",
355
+ children: ({ field, form }) => {
356
+ return /* @__PURE__ */ jsx(SwitchControl, {
357
+ label: t("trim"),
358
+ disabled,
359
+ form,
360
+ field
361
+ });
362
+ }
363
+ })
364
+ })
365
+ ]
366
+ }),
367
+ /* @__PURE__ */ jsxs("div", {
368
+ className: "grid grid-cols-12 gap-2 col-span-12",
369
+ children: [
370
+ length && /* @__PURE__ */ jsx("div", {
371
+ className: "col-span-4",
372
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
373
+ value: getIn(values, validationLength),
374
+ label: t("exact_length"),
375
+ name: validationLength,
376
+ type: "number",
377
+ size: "small",
378
+ disabled,
379
+ onChange: handleChange
380
+ })
381
+ }),
382
+ min && /* @__PURE__ */ jsx("div", {
383
+ className: "col-span-4",
384
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
385
+ value: getIn(values, validationMin),
386
+ label: t("min_length"),
387
+ name: validationMin,
388
+ type: "number",
389
+ size: "small",
390
+ disabled,
391
+ onChange: handleChange
392
+ })
393
+ }),
394
+ max && /* @__PURE__ */ jsx("div", {
395
+ className: "col-span-4",
396
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
397
+ value: getIn(values, validationMax),
398
+ label: t("max_length"),
399
+ name: validationMax,
400
+ type: "number",
401
+ size: "small",
402
+ disabled,
403
+ onChange: handleChange
404
+ })
405
+ })
406
+ ]
407
+ }),
408
+ matches && /* @__PURE__ */ jsxs("div", {
409
+ className: "col-span-12",
410
+ children: [/* @__PURE__ */ jsx(Field, {
411
+ name: validationMatches,
412
+ as: DebouncedTextField,
413
+ label: t("matches_regex"),
414
+ size: "small",
415
+ disabled,
416
+ value: matchesStringValue,
417
+ error: Boolean(matchesError)
418
+ }), /* @__PURE__ */ jsx(FieldCaption, {
419
+ error: Boolean(matchesError),
420
+ children: matchesError ? t("not_valid_regexp") : t("regex_helper")
421
+ })]
422
+ })
423
+ ]
424
+ });
425
+ }
426
+ //#endregion
427
+ //#region src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx
428
+ function ArrayPropertyValidation({ max = true, min = true, disabled }) {
429
+ const { values, handleChange } = useFormex();
430
+ const { t } = useTranslation();
431
+ const validationMin = "validation.min";
432
+ const validationMax = "validation.max";
433
+ return /* @__PURE__ */ jsxs("div", {
434
+ className: "grid grid-cols-12 gap-2",
435
+ children: [
436
+ /* @__PURE__ */ jsx(GeneralPropertyValidation, { disabled }),
437
+ min && /* @__PURE__ */ jsx("div", {
438
+ className: "col-span-6",
439
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
440
+ value: getIn(values, validationMin),
441
+ disabled,
442
+ label: t("min_length"),
443
+ name: validationMin,
444
+ type: "number",
445
+ size: "small",
446
+ onChange: handleChange
447
+ })
448
+ }),
449
+ max && /* @__PURE__ */ jsx("div", {
450
+ className: "col-span-6",
451
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
452
+ value: getIn(values, validationMax),
453
+ disabled,
454
+ label: t("max_length"),
455
+ name: validationMax,
456
+ type: "number",
457
+ size: "small",
458
+ onChange: handleChange
459
+ })
460
+ })
461
+ ]
462
+ });
463
+ }
464
+ //#endregion
465
+ //#region src/collection_editor/ui/collection_editor/properties/validation/ValidationPanel.tsx
466
+ function ValidationPanel({ children }) {
467
+ return /* @__PURE__ */ jsx(ExpandablePanel, {
468
+ initiallyExpanded: false,
469
+ asField: true,
470
+ innerClassName: "p-4",
471
+ title: /* @__PURE__ */ jsxs("div", {
472
+ className: "flex flex-row text-surface-500 text-text-secondary dark:text-text-secondary-dark",
473
+ children: [/* @__PURE__ */ jsx(CheckSquareIcon, {}), /* @__PURE__ */ jsx(Typography, {
474
+ variant: "subtitle2",
475
+ className: "ml-4",
476
+ children: "Validation"
477
+ })]
478
+ }),
479
+ children
480
+ });
481
+ }
482
+ //#endregion
483
+ //#region src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx
484
+ function EnumPropertyField({ multiselect, updateIds, disabled, showErrors, allowDataInference, getData, propertyNamespace }) {
485
+ const { values, setFieldError, setFieldValue } = useFormex();
486
+ const snackbarContext = useSnackbarController();
487
+ const { t } = useTranslation();
488
+ const enumValuesPath = multiselect ? "of.enum" : "enum";
489
+ const defaultValue = getIn(values, "defaultValue");
490
+ const valuesEnumValues = getIn(values, enumValuesPath);
491
+ const enumValues = useMemo(() => {
492
+ if (!valuesEnumValues || typeof valuesEnumValues === "boolean") return [];
493
+ return resolveEnumValues(valuesEnumValues) ?? [];
494
+ }, [valuesEnumValues]);
495
+ const onValuesChanged = (value) => {
496
+ if (!values) return;
497
+ setFieldValue(enumValuesPath, value);
498
+ if (!multiselect) {
499
+ const enumIds = value.filter((v) => Boolean(v?.id)).map((v) => v.id);
500
+ if (defaultValue && !enumIds.includes(defaultValue)) {
501
+ setFieldValue("defaultValue", void 0);
502
+ snackbarContext.open({
503
+ type: "warning",
504
+ message: "Default value was cleared"
505
+ });
506
+ }
507
+ }
508
+ };
509
+ const fullPropertyPath = values.id ? propertyNamespace ? `${propertyNamespace}.${values.id}` : values.id : void 0;
510
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
511
+ /* @__PURE__ */ jsx("div", {
512
+ className: "col-span-12",
513
+ children: /* @__PURE__ */ jsx(EnumForm, {
514
+ enumValues,
515
+ updateIds,
516
+ disabled,
517
+ allowDataInference,
518
+ onError: (hasError) => {
519
+ setFieldError(enumValuesPath, hasError ? "This enum property is missing some values" : void 0);
520
+ },
521
+ getData: getData && fullPropertyPath ? () => getData().then((res) => res.map((entry) => getIn(entry, fullPropertyPath)).filter(Boolean)) : void 0,
522
+ onValuesChanged
523
+ })
524
+ }),
525
+ /* @__PURE__ */ jsx("div", {
526
+ className: "col-span-12",
527
+ children: /* @__PURE__ */ jsxs(ValidationPanel, { children: [!multiselect && /* @__PURE__ */ jsx(StringPropertyValidation, {
528
+ disabled,
529
+ showErrors
530
+ }), multiselect && /* @__PURE__ */ jsx(ArrayPropertyValidation, { disabled })] })
531
+ }),
532
+ !multiselect && /* @__PURE__ */ jsx("div", {
533
+ className: "col-span-12",
534
+ children: /* @__PURE__ */ jsx(Select, {
535
+ disabled,
536
+ position: "item-aligned",
537
+ fullWidth: true,
538
+ onValueChange: (value) => {
539
+ setFieldValue("defaultValue", value);
540
+ },
541
+ label: t("default_value"),
542
+ value: defaultValue?.toString() ?? "",
543
+ children: enumValues.filter((enumValue) => Boolean(enumValue?.id)).map((enumValue) => /* @__PURE__ */ jsx(SelectItem, {
544
+ value: enumValue.id?.toString(),
545
+ children: enumValue.label
546
+ }, enumValue.id))
547
+ })
548
+ })
549
+ ] });
550
+ }
551
+ //#endregion
552
+ //#region src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx
553
+ var fileTypes = {
554
+ "image/*": "Images",
555
+ "video/*": "Videos",
556
+ "audio/*": "Audio files",
557
+ "application/*": "Files (pdf, zip, csv, excel...)",
558
+ "text/*": "Text files"
559
+ };
560
+ function StoragePropertyField({ multiple, existing, disabled }) {
561
+ const { values, setFieldValue } = useFormex();
562
+ const { t } = useTranslation();
563
+ const baseStoragePath = multiple ? "of.storage" : "storage";
564
+ const acceptedFiles = `${baseStoragePath}.acceptedFiles`;
565
+ `${baseStoragePath}`;
566
+ const fileName = `${baseStoragePath}.fileName`;
567
+ const maxSize = `${baseStoragePath}.maxSize`;
568
+ const storagePath = `${baseStoragePath}.storagePath`;
569
+ const storeUrl = `${baseStoragePath}.storeUrl`;
570
+ const includeBucketUrl = `${baseStoragePath}.includeBucketUrl`;
571
+ const imageResize = `${baseStoragePath}.imageResize`;
572
+ const imageResizeMaxWidth = `${imageResize}.maxWidth`;
573
+ const imageResizeMaxHeight = `${imageResize}.maxHeight`;
574
+ const imageResizeMode = `${imageResize}.mode`;
575
+ const imageResizeFormat = `${imageResize}.format`;
576
+ const imageResizeQuality = `${imageResize}.quality`;
577
+ const fileNameValue = getIn(values, fileName) ?? "{rand}_{file}";
578
+ const storagePathValue = getIn(values, storagePath) ?? "/";
579
+ const maxSizeValue = getIn(values, maxSize);
580
+ const imageResizeMaxWidthValue = getIn(values, imageResizeMaxWidth);
581
+ const imageResizeMaxHeightValue = getIn(values, imageResizeMaxHeight);
582
+ const imageResizeModeValue = getIn(values, imageResizeMode) ?? "cover";
583
+ const imageResizeFormatValue = getIn(values, imageResizeFormat) ?? "original";
584
+ const imageResizeQualityValue = getIn(values, imageResizeQuality);
585
+ const storedValue = getIn(values, acceptedFiles);
586
+ const fileTypesValue = Array.isArray(storedValue) ? storedValue : void 0;
587
+ const allFileTypesSelected = !fileTypesValue || fileTypesValue.length === 0;
588
+ const handleTypesChange = (value) => {
589
+ if (!value) setFieldValue(acceptedFiles, void 0);
590
+ else setFieldValue(acceptedFiles, value);
591
+ };
592
+ const hasFilenameCallback = typeof fileNameValue === "function";
593
+ const hasStoragePathCallback = typeof storagePathValue === "function";
594
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
595
+ className: "col-span-12",
596
+ children: /* @__PURE__ */ jsx(ExpandablePanel, {
597
+ title: /* @__PURE__ */ jsxs("div", {
598
+ className: "flex flex-row text-surface-500 text-text-secondary dark:text-text-secondary-dark",
599
+ children: [/* @__PURE__ */ jsx(UploadCloudIcon, {}), /* @__PURE__ */ jsx(Typography, {
600
+ variant: "subtitle2",
601
+ className: "ml-4",
602
+ children: "File upload config"
603
+ })]
604
+ }),
605
+ children: /* @__PURE__ */ jsxs("div", {
606
+ className: "grid grid-cols-12 gap-2 p-4",
607
+ children: [
608
+ /* @__PURE__ */ jsx("div", {
609
+ className: "col-span-12",
610
+ children: /* @__PURE__ */ jsx(MultiSelect, {
611
+ className: "w-full",
612
+ placeholder: "All file types allowed",
613
+ disabled,
614
+ name: acceptedFiles,
615
+ value: fileTypesValue ?? [],
616
+ onValueChange: handleTypesChange,
617
+ label: allFileTypesSelected ? void 0 : "Allowed file types",
618
+ renderValues: (selected) => {
619
+ if (!selected || selected.length === 0) return "All file types allowed";
620
+ return selected.map((v) => fileTypes[v]).filter((v) => Boolean(v)).join(", ");
621
+ },
622
+ children: Object.entries(fileTypes).map(([value, label]) => /* @__PURE__ */ jsxs(MultiSelectItem, {
623
+ value,
624
+ className: "flex items-center gap-2",
625
+ children: [/* @__PURE__ */ jsx("div", {
626
+ className: "grow",
627
+ children: label
628
+ }), /* @__PURE__ */ jsx(Button, {
629
+ size: "small",
630
+ variant: "text",
631
+ onClick: (e) => {
632
+ e.preventDefault();
633
+ e.stopPropagation();
634
+ return setFieldValue(acceptedFiles, [value]);
635
+ },
636
+ children: "Only"
637
+ })]
638
+ }, value))
639
+ })
640
+ }),
641
+ /* @__PURE__ */ jsx("div", {
642
+ className: "col-span-12",
643
+ children: /* @__PURE__ */ jsx(Field, {
644
+ name: fileName,
645
+ as: DebouncedTextField,
646
+ label: t("storage_file_name"),
647
+ size: "small",
648
+ disabled: hasFilenameCallback || disabled,
649
+ value: hasFilenameCallback ? "-" : fileNameValue
650
+ })
651
+ }),
652
+ /* @__PURE__ */ jsxs("div", {
653
+ className: "col-span-12",
654
+ children: [
655
+ /* @__PURE__ */ jsx(Field, {
656
+ name: storagePath,
657
+ as: DebouncedTextField,
658
+ label: t("storage_path"),
659
+ disabled: hasStoragePathCallback || disabled,
660
+ size: "small",
661
+ value: hasStoragePathCallback ? "-" : storagePathValue
662
+ }),
663
+ /* @__PURE__ */ jsxs(Typography, {
664
+ variant: "caption",
665
+ className: "ml-3.5 mt-1 mb-2",
666
+ children: [/* @__PURE__ */ jsx("p", { children: "You can use the following placeholders in the file name and storage path values:" }), /* @__PURE__ */ jsxs("ul", { children: [
667
+ /* @__PURE__ */ jsx("li", { children: "{file} - Full name of the uploaded file" }),
668
+ /* @__PURE__ */ jsx("li", { children: "{file.name} - Name of the uploaded file without extension" }),
669
+ /* @__PURE__ */ jsx("li", { children: "{file.ext} - Extension of the uploaded file" }),
670
+ /* @__PURE__ */ jsx("li", { children: "{entityId} - ID of the entity" }),
671
+ /* @__PURE__ */ jsx("li", { children: "{propertyKey} - ID of this field" }),
672
+ /* @__PURE__ */ jsx("li", { children: "{path} - Path of this entity" }),
673
+ /* @__PURE__ */ jsx("li", { children: "{rand} - Random value used to avoid name collisions" })
674
+ ] })]
675
+ }),
676
+ /* @__PURE__ */ jsx(Field, {
677
+ name: includeBucketUrl,
678
+ type: "checkbox",
679
+ children: ({ field, form }) => {
680
+ return /* @__PURE__ */ jsx(SwitchControl, {
681
+ label: t("storage_include_bucket_url"),
682
+ disabled: existing || disabled,
683
+ form,
684
+ field
685
+ });
686
+ }
687
+ }),
688
+ /* @__PURE__ */ jsxs(Typography, {
689
+ variant: "caption",
690
+ className: "ml-3.5 mt-1 mb-2",
691
+ children: [
692
+ "Turn this setting on if you want to save a fully-qualified storage URL (e.g. ",
693
+ /* @__PURE__ */ jsx("code", { children: "s3://my-bucket/path/to/file" }),
694
+ ") instead of just the storage path. You can only change this prop upon creation."
695
+ ]
696
+ }),
697
+ /* @__PURE__ */ jsx(Field, {
698
+ name: storeUrl,
699
+ type: "checkbox",
700
+ children: ({ field, form }) => {
701
+ return /* @__PURE__ */ jsx(SwitchControl, {
702
+ label: t("storage_save_url"),
703
+ disabled: existing || disabled,
704
+ form,
705
+ field
706
+ });
707
+ }
708
+ }),
709
+ /* @__PURE__ */ jsx(Typography, {
710
+ variant: "caption",
711
+ className: "ml-3.5 mt-1 mb-2",
712
+ children: "Turn this setting on, if you prefer to save the download URL of the uploaded file instead of the storage path. You can only change this prop upon creation."
713
+ })
714
+ ]
715
+ }),
716
+ /* @__PURE__ */ jsx("div", {
717
+ className: "col-span-12",
718
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
719
+ name: maxSize,
720
+ type: "number",
721
+ label: t("storage_max_size"),
722
+ size: "small",
723
+ value: maxSizeValue !== void 0 && maxSizeValue !== null ? maxSizeValue.toString() : "",
724
+ onChange: (e) => {
725
+ const value = e.target.value;
726
+ if (value === "") setFieldValue(maxSize, void 0);
727
+ else setFieldValue(maxSize, parseInt(value));
728
+ }
729
+ })
730
+ }),
731
+ /* @__PURE__ */ jsxs("div", {
732
+ className: "col-span-12 mt-4",
733
+ children: [/* @__PURE__ */ jsx(Typography, {
734
+ variant: "subtitle2",
735
+ color: "secondary",
736
+ className: "mb-2 block",
737
+ children: "Image Resize Configuration"
738
+ }), /* @__PURE__ */ jsx(Typography, {
739
+ variant: "caption",
740
+ className: "mb-2 block text-xs",
741
+ children: "Automatically resize and optimize images before upload (JPEG, PNG, WebP only)"
742
+ })]
743
+ }),
744
+ /* @__PURE__ */ jsx("div", {
745
+ className: "col-span-6",
746
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
747
+ name: imageResizeMaxWidth,
748
+ type: "number",
749
+ label: t("storage_max_width"),
750
+ size: "small",
751
+ disabled,
752
+ value: imageResizeMaxWidthValue !== void 0 && imageResizeMaxWidthValue !== null ? imageResizeMaxWidthValue.toString() : "",
753
+ onChange: (e) => {
754
+ const value = e.target.value;
755
+ if (value === "") setFieldValue(imageResizeMaxWidth, void 0);
756
+ else setFieldValue(imageResizeMaxWidth, parseInt(value));
757
+ }
758
+ })
759
+ }),
760
+ /* @__PURE__ */ jsx("div", {
761
+ className: "col-span-6",
762
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
763
+ name: imageResizeMaxHeight,
764
+ type: "number",
765
+ label: t("storage_max_height"),
766
+ size: "small",
767
+ disabled,
768
+ value: imageResizeMaxHeightValue !== void 0 && imageResizeMaxHeightValue !== null ? imageResizeMaxHeightValue.toString() : "",
769
+ onChange: (e) => {
770
+ const value = e.target.value;
771
+ if (value === "") setFieldValue(imageResizeMaxHeight, void 0);
772
+ else setFieldValue(imageResizeMaxHeight, parseInt(value));
773
+ }
774
+ })
775
+ }),
776
+ /* @__PURE__ */ jsx("div", {
777
+ className: "col-span-6",
778
+ children: /* @__PURE__ */ jsxs(Select, {
779
+ disabled,
780
+ name: imageResizeMode,
781
+ fullWidth: true,
782
+ size: "medium",
783
+ value: imageResizeModeValue || "cover",
784
+ onValueChange: (value) => setFieldValue(imageResizeMode, value || "cover"),
785
+ label: t("storage_resize_mode"),
786
+ renderValue: (selected) => {
787
+ if (!selected) return "Cover";
788
+ return selected === "contain" ? "Contain (fit within bounds)" : "Cover (fill bounds, may crop)";
789
+ },
790
+ children: [/* @__PURE__ */ jsx(SelectItem, {
791
+ value: "contain",
792
+ children: "Contain (fit within bounds)"
793
+ }), /* @__PURE__ */ jsx(SelectItem, {
794
+ value: "cover",
795
+ children: "Cover (fill bounds, may crop)"
796
+ })]
797
+ })
798
+ }),
799
+ /* @__PURE__ */ jsx("div", {
800
+ className: "col-span-6",
801
+ children: /* @__PURE__ */ jsxs(Select, {
802
+ disabled,
803
+ size: "medium",
804
+ fullWidth: true,
805
+ name: imageResizeFormat,
806
+ value: imageResizeFormatValue || "original",
807
+ onValueChange: (value) => setFieldValue(imageResizeFormat, value || "original"),
808
+ label: t("storage_output_format"),
809
+ renderValue: (selected) => {
810
+ if (!selected) return "Original";
811
+ return selected.charAt(0).toUpperCase() + selected.slice(1);
812
+ },
813
+ children: [
814
+ /* @__PURE__ */ jsx(SelectItem, {
815
+ value: "original",
816
+ children: "Original (keep same format)"
817
+ }),
818
+ /* @__PURE__ */ jsx(SelectItem, {
819
+ value: "jpeg",
820
+ children: "JPEG"
821
+ }),
822
+ /* @__PURE__ */ jsx(SelectItem, {
823
+ value: "png",
824
+ children: "PNG"
825
+ }),
826
+ /* @__PURE__ */ jsx(SelectItem, {
827
+ value: "webp",
828
+ children: "WebP (best compression)"
829
+ })
830
+ ]
831
+ })
832
+ }),
833
+ /* @__PURE__ */ jsxs("div", {
834
+ className: "col-span-12",
835
+ children: [/* @__PURE__ */ jsx(DebouncedTextField, {
836
+ name: imageResizeQuality,
837
+ type: "number",
838
+ label: t("storage_quality"),
839
+ size: "small",
840
+ disabled,
841
+ value: imageResizeQualityValue !== void 0 && imageResizeQualityValue !== null ? imageResizeQualityValue.toString() : "",
842
+ onChange: (e) => {
843
+ const value = e.target.value;
844
+ if (value === "") setFieldValue(imageResizeQuality, void 0);
845
+ else {
846
+ const numValue = parseInt(value);
847
+ if (numValue >= 0 && numValue <= 100) setFieldValue(imageResizeQuality, numValue);
848
+ }
849
+ }
850
+ }), /* @__PURE__ */ jsx(Typography, {
851
+ variant: "caption",
852
+ className: "ml-3.5 mt-1 mb-2",
853
+ children: "Higher quality = larger file size. Recommended: 80-90 for photos, 90-100 for graphics"
854
+ })]
855
+ })
856
+ ]
857
+ })
858
+ })
859
+ }), /* @__PURE__ */ jsx("div", {
860
+ className: "col-span-12",
861
+ children: /* @__PURE__ */ jsxs(ValidationPanel, { children: [!multiple && /* @__PURE__ */ jsx("div", {
862
+ className: "grid grid-cols-12 gap-2",
863
+ children: /* @__PURE__ */ jsx(GeneralPropertyValidation, { disabled })
864
+ }), multiple && /* @__PURE__ */ jsx("div", {
865
+ className: "col-span-12",
866
+ children: /* @__PURE__ */ jsx(ArrayPropertyValidation, { disabled })
867
+ })] })
868
+ })] });
869
+ }
870
+ //#endregion
871
+ //#region src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx
872
+ function PropertyFieldPreview({ property, propertyKey, onClick, hasError, includeName, includeEditButton, selected }) {
873
+ const { propertyConfigs } = useCustomizationController();
874
+ const propertyConfig = getFieldConfig(property, propertyConfigs);
875
+ return /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx("div", {
876
+ onClick,
877
+ className: onClick ? "cursor-pointer" : "",
878
+ children: /* @__PURE__ */ jsxs(Paper, {
879
+ className: cls("w-full flex flex-row gap-3 items-center px-3 py-2 rounded-lg transition-all duration-200 border bg-white dark:bg-surface-800 shadow-xs", (hasError ? "border-red-500 dark:border-red-500 border-red-500/100 dark:border-red-500/100 ring-0 dark:ring-0" : selected ? "border-primary" : "") || "border-surface-200 dark:border-surface-700", selected ? "bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light ring-1 ring-inset ring-primary border-primary/30" : "hover:bg-surface-50 dark:hover:bg-surface-700"),
880
+ children: [
881
+ /* @__PURE__ */ jsx(PropertyConfigBadge, {
882
+ propertyConfig,
883
+ size: "small"
884
+ }),
885
+ /* @__PURE__ */ jsxs("div", {
886
+ className: "flex-1 flex flex-col min-w-0 pr-8",
887
+ children: [includeName && /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxs("div", {
888
+ className: "flex items-center gap-2",
889
+ children: [/* @__PURE__ */ jsx(Typography, {
890
+ variant: "body2",
891
+ component: "span",
892
+ children: property.name || propertyKey || "\xA0"
893
+ }), property.name && propertyKey && property.name !== propertyKey && /* @__PURE__ */ jsx(Typography, {
894
+ variant: "caption",
895
+ component: "span",
896
+ color: "secondary",
897
+ className: "font-mono",
898
+ children: propertyKey
899
+ })]
900
+ }) }), /* @__PURE__ */ jsx("div", {
901
+ className: "flex flex-row items-center gap-2 mt-0.5",
902
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Typography, {
903
+ variant: "caption",
904
+ component: "span",
905
+ className: "text-text-secondary dark:text-text-secondary-dark font-medium",
906
+ children: propertyConfig?.name
907
+ }) })
908
+ })]
909
+ }),
910
+ /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Typography, {
911
+ variant: "caption",
912
+ component: "span",
913
+ className: "ml-auto shrink-0 text-text-disabled dark:text-text-disabled-dark font-mono bg-surface-100 dark:bg-surface-900 px-1.5 py-0.5 rounded mr-8",
914
+ children: "columnType" in property ? property.columnType ?? property.type : property.type
915
+ }) }),
916
+ includeEditButton && /* @__PURE__ */ jsx(Typography, {
917
+ variant: "button",
918
+ children: "EDIT"
919
+ })
920
+ ]
921
+ })
922
+ }) });
923
+ }
924
+ function NonEditablePropertyPreview({ name, selected, onClick, property }) {
925
+ const { propertyConfigs } = useCustomizationController();
926
+ const propertyConfig = !isPropertyBuilder(property) && property ? getFieldConfig(property, propertyConfigs) : void 0;
927
+ return /* @__PURE__ */ jsx("div", {
928
+ onClick,
929
+ className: onClick ? "cursor-pointer" : "",
930
+ children: /* @__PURE__ */ jsxs(Paper, {
931
+ className: cls("w-full flex flex-row gap-3 items-center px-3 py-2 rounded-lg transition-all duration-200 border bg-white dark:bg-surface-800 border-surface-200 dark:border-surface-700 shadow-xs", selected ? "bg-primary/10 text-primary dark:bg-primary/20 dark:text-primary-light ring-1 ring-inset ring-primary border-primary/30" : "hover:bg-surface-50 dark:hover:bg-surface-700"),
932
+ children: [
933
+ /* @__PURE__ */ jsxs("div", {
934
+ className: "relative shrink-0",
935
+ children: [
936
+ propertyConfig && /* @__PURE__ */ jsx(PropertyConfigBadge, {
937
+ propertyConfig,
938
+ size: "small"
939
+ }),
940
+ !propertyConfig && /* @__PURE__ */ jsx("div", {
941
+ className: "h-8 w-8 flex items-center justify-center rounded-full shadow-2xs text-white bg-surface-500",
942
+ children: /* @__PURE__ */ jsx(FunctionSquareIcon, {
943
+ className: "text-inherit",
944
+ size: iconSize.small
945
+ })
946
+ }),
947
+ /* @__PURE__ */ jsx(MinusCircleIcon, {
948
+ className: "text-surface-accent-400 absolute -right-2 -top-2 bg-surface-50 dark:bg-surface-900 rounded-full",
949
+ size: iconSize.small
950
+ })
951
+ ]
952
+ }),
953
+ /* @__PURE__ */ jsxs("div", {
954
+ className: "flex-1 flex flex-col min-w-0 pr-8",
955
+ children: [/* @__PURE__ */ jsx(Typography, {
956
+ variant: "label",
957
+ component: "span",
958
+ className: "grow pr-2",
959
+ children: property?.name ? property.name : name
960
+ }), /* @__PURE__ */ jsxs("div", {
961
+ className: "flex flex-row items-center gap-2 mt-0.5",
962
+ children: [
963
+ propertyConfig && /* @__PURE__ */ jsx(Typography, {
964
+ variant: "caption",
965
+ component: "span",
966
+ className: "text-text-secondary dark:text-text-secondary-dark font-medium",
967
+ children: propertyConfig?.name
968
+ }),
969
+ property && isPropertyBuilder(property) && /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Typography, {
970
+ variant: "caption",
971
+ component: "span",
972
+ className: "text-text-disabled dark:text-text-disabled-dark",
973
+ children: "Defined in code"
974
+ }) }),
975
+ !property && /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Typography, {
976
+ variant: "caption",
977
+ component: "span",
978
+ className: "text-text-disabled dark:text-text-disabled-dark",
979
+ children: "Additional field"
980
+ }) })
981
+ ]
982
+ })]
983
+ }),
984
+ property && !isPropertyBuilder(property) && /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Typography, {
985
+ variant: "caption",
986
+ component: "span",
987
+ className: "ml-auto shrink-0 text-text-disabled dark:text-text-disabled-dark font-mono bg-surface-100 dark:bg-surface-900 px-1.5 py-0.5 rounded mr-8",
988
+ children: "columnType" in property ? property.columnType ?? property.type : property.type
989
+ }) })
990
+ ]
991
+ })
992
+ });
993
+ }
994
+ //#endregion
995
+ //#region src/collection_editor/ui/collection_editor/AIModifiedPathsContext.tsx
996
+ var AIModifiedPathsContext = createContext(null);
997
+ function AIModifiedPathsProvider({ children }) {
998
+ const [modifiedPaths, setModifiedPaths] = useState(/* @__PURE__ */ new Set());
999
+ const [generationCounter, setGenerationCounter] = useState(0);
1000
+ const addModifiedPaths = useCallback((operations) => {
1001
+ setModifiedPaths((prev) => {
1002
+ const newSet = new Set(prev);
1003
+ operations.forEach((op) => {
1004
+ newSet.add(op.path);
1005
+ const parts = op.path.split(".");
1006
+ if (parts[0] === "properties" && parts.length >= 2) newSet.add(`properties.${parts[1]}`);
1007
+ });
1008
+ return newSet;
1009
+ });
1010
+ setGenerationCounter((prev) => prev + 1);
1011
+ }, []);
1012
+ const clearPath = useCallback((path) => {
1013
+ setModifiedPaths((prev) => {
1014
+ const newSet = new Set(prev);
1015
+ for (const p of newSet) if (p === path || p.startsWith(path + ".")) newSet.delete(p);
1016
+ return newSet;
1017
+ });
1018
+ }, []);
1019
+ const clearAllPaths = useCallback(() => {
1020
+ setModifiedPaths(/* @__PURE__ */ new Set());
1021
+ }, []);
1022
+ const isPathModified = useCallback((path) => {
1023
+ if (modifiedPaths.has(path)) return true;
1024
+ for (const p of modifiedPaths) if (p.startsWith(path + ".")) return true;
1025
+ return false;
1026
+ }, [modifiedPaths]);
1027
+ const contextValue = useMemo(() => ({
1028
+ modifiedPaths,
1029
+ generationCounter,
1030
+ addModifiedPaths,
1031
+ clearPath,
1032
+ clearAllPaths,
1033
+ isPathModified
1034
+ }), [
1035
+ modifiedPaths,
1036
+ generationCounter,
1037
+ addModifiedPaths,
1038
+ clearPath,
1039
+ clearAllPaths,
1040
+ isPathModified
1041
+ ]);
1042
+ return /* @__PURE__ */ jsx(AIModifiedPathsContext.Provider, {
1043
+ value: contextValue,
1044
+ children
1045
+ });
1046
+ }
1047
+ function useAIModifiedPaths() {
1048
+ return useContext(AIModifiedPathsContext);
1049
+ }
1050
+ //#endregion
1051
+ //#region src/collection_editor/ui/collection_editor/PropertyTree.tsx
1052
+ var PropertyTree = React.memo(function PropertyTree({ namespace, selectedPropertyKey, onPropertyClick, properties, propertiesOrder: propertiesOrderProp, additionalFields, errors, onPropertyMove, onPropertyRemove, className, inferredPropertyKeys }) {
1053
+ const propertyKeys = Object.keys(properties);
1054
+ const filteredOrder = (propertiesOrderProp ?? propertyKeys).filter((key) => !key.includes(".") && properties[key]);
1055
+ const missingKeys = propertyKeys.filter((key) => !filteredOrder.includes(key));
1056
+ const propertiesOrder = [...filteredOrder, ...missingKeys];
1057
+ const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
1058
+ const handleDragEnd = (event) => {
1059
+ const { active, over } = event;
1060
+ if (!over || active.id === over.id) return;
1061
+ const activeId = String(active.id);
1062
+ const overId = String(over.id);
1063
+ const activeKey = activeId.includes(".") ? activeId.split(".").pop() : activeId;
1064
+ const overKey = overId.includes(".") ? overId.split(".").pop() : overId;
1065
+ if (!activeKey || !overKey) return;
1066
+ const oldIndex = propertiesOrder.indexOf(activeKey);
1067
+ const newIndex = propertiesOrder.indexOf(overKey);
1068
+ if (oldIndex !== -1 && newIndex !== -1) {
1069
+ const newPropertiesOrder = [...propertiesOrder];
1070
+ const [removed] = newPropertiesOrder.splice(oldIndex, 1);
1071
+ newPropertiesOrder.splice(newIndex, 0, removed);
1072
+ if (onPropertyMove) onPropertyMove(newPropertiesOrder, namespace);
1073
+ }
1074
+ };
1075
+ const items = propertiesOrder.map((key) => getFullId(key, namespace));
1076
+ return /* @__PURE__ */ jsx(DndContext, {
1077
+ sensors,
1078
+ collisionDetection: closestCenter,
1079
+ onDragEnd: handleDragEnd,
1080
+ modifiers: [restrictToVerticalAxis],
1081
+ children: /* @__PURE__ */ jsx(SortableContext, {
1082
+ items,
1083
+ strategy: verticalListSortingStrategy,
1084
+ children: /* @__PURE__ */ jsx("div", {
1085
+ className: cls("flex flex-col gap-0.5", className),
1086
+ children: propertiesOrder && propertiesOrder.map((propertyKey, index) => {
1087
+ const property = properties[propertyKey];
1088
+ const additionalField = additionalFields?.find((field) => field.key === propertyKey);
1089
+ if (!property && !additionalField) {
1090
+ console.warn(`Property ${propertyKey} not found in properties or additionalFields`);
1091
+ return null;
1092
+ }
1093
+ const id = getFullId(propertyKey, namespace);
1094
+ return /* @__PURE__ */ jsx(PropertyTreeEntry, {
1095
+ id,
1096
+ propertyKey,
1097
+ property,
1098
+ additionalField,
1099
+ errors,
1100
+ namespace,
1101
+ propertiesOrder,
1102
+ inferredPropertyKeys,
1103
+ onPropertyMove,
1104
+ onPropertyRemove,
1105
+ onPropertyClick,
1106
+ selectedPropertyKey
1107
+ }, id);
1108
+ }).filter(Boolean)
1109
+ })
1110
+ })
1111
+ });
1112
+ }, deepEqual);
1113
+ function PropertyTreeEntry({ id, propertyKey, namespace, property, additionalField, selectedPropertyKey, errors, propertiesOrder, onPropertyClick, onPropertyMove, onPropertyRemove, inferredPropertyKeys }) {
1114
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
1115
+ const style = {
1116
+ transform: CSS.Translate.toString(transform),
1117
+ transition,
1118
+ zIndex: isDragging ? 10 : void 0,
1119
+ position: "relative"
1120
+ };
1121
+ const isPropertyInferred = inferredPropertyKeys?.includes(namespace ? `${namespace}.${propertyKey}` : propertyKey);
1122
+ const fullId = id;
1123
+ const hasError = getFullIdPath(propertyKey, namespace) in errors;
1124
+ let subtree;
1125
+ if (typeof property === "object") {
1126
+ if (property.type === "map" && property.properties) subtree = /* @__PURE__ */ jsx(PropertyTree, {
1127
+ selectedPropertyKey,
1128
+ namespace: fullId,
1129
+ properties: property.properties,
1130
+ propertiesOrder: property.propertiesOrder,
1131
+ errors,
1132
+ onPropertyClick,
1133
+ onPropertyMove,
1134
+ onPropertyRemove,
1135
+ inferredPropertyKeys
1136
+ });
1137
+ }
1138
+ const selected = selectedPropertyKey === fullId;
1139
+ const editable = property && !isPropertyBuilder(property);
1140
+ const isAIModified = useAIModifiedPaths()?.isPathModified(`properties.${propertyKey}`) ?? false;
1141
+ return /* @__PURE__ */ jsx("div", {
1142
+ ref: setNodeRef,
1143
+ style,
1144
+ className: "relative cursor-grab",
1145
+ ...attributes,
1146
+ ...listeners,
1147
+ children: /* @__PURE__ */ jsxs("div", {
1148
+ className: "relative",
1149
+ children: [
1150
+ subtree && /* @__PURE__ */ jsx("div", {
1151
+ className: "absolute border-l " + defaultBorderMixin,
1152
+ style: {
1153
+ left: "24px",
1154
+ top: "40px",
1155
+ bottom: "16px"
1156
+ }
1157
+ }),
1158
+ /* @__PURE__ */ jsx("div", { children: !isPropertyBuilder(property) && !additionalField && editable ? /* @__PURE__ */ jsx(PropertyFieldPreview, {
1159
+ property,
1160
+ onClick: onPropertyClick ? () => onPropertyClick(propertyKey, namespace) : void 0,
1161
+ includeName: true,
1162
+ selected,
1163
+ hasError
1164
+ }) : /* @__PURE__ */ jsx(NonEditablePropertyPreview, {
1165
+ name: propertyKey,
1166
+ property,
1167
+ onClick: onPropertyClick ? () => onPropertyClick(propertyKey, namespace) : void 0,
1168
+ selected
1169
+ }) }),
1170
+ /* @__PURE__ */ jsxs("div", {
1171
+ className: "absolute top-1/2 -translate-y-1/2 right-3 flex flex-row items-center gap-1",
1172
+ children: [
1173
+ isAIModified && /* @__PURE__ */ jsx(AIModifiedIndicator, {}),
1174
+ isPropertyInferred && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Tooltip, {
1175
+ title: "Inferred property",
1176
+ asChild: true,
1177
+ children: /* @__PURE__ */ jsx(IconButton, {
1178
+ size: "smallest",
1179
+ disabled: true,
1180
+ children: /* @__PURE__ */ jsx(FileSearchIcon, { size: iconSize.smallest })
1181
+ })
1182
+ }), onPropertyRemove && /* @__PURE__ */ jsx(Tooltip, {
1183
+ title: "Remove inferred property",
1184
+ asChild: true,
1185
+ children: /* @__PURE__ */ jsx(IconButton, {
1186
+ size: "smallest",
1187
+ color: "inherit",
1188
+ onClick: (e) => {
1189
+ e.stopPropagation();
1190
+ onPropertyRemove(propertyKey, namespace);
1191
+ },
1192
+ children: /* @__PURE__ */ jsx(Trash2Icon, { size: iconSize.smallest })
1193
+ })
1194
+ })] }),
1195
+ /* @__PURE__ */ jsxs(Menu, {
1196
+ trigger: /* @__PURE__ */ jsx(IconButton, {
1197
+ size: "smallest",
1198
+ children: /* @__PURE__ */ jsx(MoreVerticalIcon, { size: iconSize.smallest })
1199
+ }),
1200
+ children: [
1201
+ /* @__PURE__ */ jsxs(MenuItem, {
1202
+ dense: true,
1203
+ onClick: () => {
1204
+ if (propertiesOrder.indexOf(propertyKey) > 0) {
1205
+ const newOrder = propertiesOrder.filter((k) => k !== propertyKey);
1206
+ newOrder.unshift(propertyKey);
1207
+ onPropertyMove?.(newOrder, namespace);
1208
+ }
1209
+ },
1210
+ children: [/* @__PURE__ */ jsx(ArrowUpToLineIcon, { size: iconSize.smallest }), "Move to top"]
1211
+ }),
1212
+ /* @__PURE__ */ jsxs(MenuItem, {
1213
+ dense: true,
1214
+ onClick: () => {
1215
+ if (propertiesOrder.indexOf(propertyKey) < propertiesOrder.length - 1) {
1216
+ const newOrder = propertiesOrder.filter((k) => k !== propertyKey);
1217
+ newOrder.push(propertyKey);
1218
+ onPropertyMove?.(newOrder, namespace);
1219
+ }
1220
+ },
1221
+ children: [/* @__PURE__ */ jsx(ArrowDownToLineIcon, { size: iconSize.smallest }), "Move to bottom"]
1222
+ }),
1223
+ /* @__PURE__ */ jsxs(MenuItem, {
1224
+ dense: true,
1225
+ onClick: () => onPropertyRemove?.(propertyKey, namespace),
1226
+ children: [/* @__PURE__ */ jsx(Trash2Icon, { size: iconSize.smallest }), "Delete"]
1227
+ })
1228
+ ]
1229
+ })
1230
+ ]
1231
+ }),
1232
+ subtree && /* @__PURE__ */ jsx("div", {
1233
+ className: "ml-12",
1234
+ children: subtree
1235
+ })
1236
+ ]
1237
+ })
1238
+ });
1239
+ }
1240
+ //#endregion
1241
+ //#region src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx
1242
+ function MapPropertyField({ disabled, getData, allowDataInference, propertyConfigs }) {
1243
+ const { values, setFieldValue } = useFormex();
1244
+ const { t } = useTranslation();
1245
+ const [propertyDialogOpen, setPropertyDialogOpen] = useState(false);
1246
+ const [selectedPropertyKey, setSelectedPropertyKey] = useState();
1247
+ const [selectedPropertyNamespace, setSelectedPropertyNamespace] = useState();
1248
+ const propertiesOrder = values.propertiesOrder ?? Object.keys(values.properties ?? {});
1249
+ const onPropertyCreated = ({ id, property }) => {
1250
+ if (!id) throw Error();
1251
+ setFieldValue("properties", {
1252
+ ...values.properties ?? {},
1253
+ [id]: property
1254
+ }, false);
1255
+ const currentPropertiesOrder = values.propertiesOrder ?? Object.keys(values.properties ?? {});
1256
+ setFieldValue("propertiesOrder", currentPropertiesOrder.includes(id) ? currentPropertiesOrder : [...currentPropertiesOrder, id], false);
1257
+ setPropertyDialogOpen(false);
1258
+ };
1259
+ const deleteProperty = (propertyKey, namespace) => {
1260
+ const fullId = propertyKey ? getFullId(propertyKey, namespace) : void 0;
1261
+ if (!fullId) throw Error("collection editor miss config");
1262
+ const propertiesPath = idToPropertiesPath(fullId);
1263
+ const propertiesOrderPath = namespaceToPropertiesOrderPath(namespace);
1264
+ const currentPropertiesOrder = getIn(values, propertiesOrderPath) ?? Object.keys(getIn(values, namespaceToPropertiesPath(namespace)) ?? {});
1265
+ setFieldValue(propertiesPath, void 0, false);
1266
+ setFieldValue(propertiesOrderPath, currentPropertiesOrder.filter((p) => p !== propertyKey), false);
1267
+ setPropertyDialogOpen(false);
1268
+ setSelectedPropertyKey(void 0);
1269
+ setSelectedPropertyNamespace(void 0);
1270
+ };
1271
+ const selectedPropertyFullId = selectedPropertyKey ? getFullId(selectedPropertyKey, selectedPropertyNamespace) : void 0;
1272
+ const selectedProperty = selectedPropertyFullId ? getIn(values.properties, selectedPropertyFullId.replaceAll(".", ".properties.")) : void 0;
1273
+ const empty = !propertiesOrder || propertiesOrder.length < 1;
1274
+ const onPropertyMove = (propertiesOrder, namespace) => {
1275
+ setFieldValue(namespaceToPropertiesOrderPath(namespace), propertiesOrder, false);
1276
+ };
1277
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1278
+ /* @__PURE__ */ jsxs("div", {
1279
+ className: "col-span-12",
1280
+ children: [/* @__PURE__ */ jsxs("div", {
1281
+ className: "flex justify-between items-end my-4",
1282
+ children: [/* @__PURE__ */ jsx(Typography, {
1283
+ variant: "subtitle2",
1284
+ children: t("properties_in_this_group")
1285
+ }), /* @__PURE__ */ jsxs(Button, {
1286
+ onClick: () => setPropertyDialogOpen(true),
1287
+ startIcon: /* @__PURE__ */ jsx(PlusIcon, {}),
1288
+ children: ["Add property to ", values.name ?? "this group"]
1289
+ })]
1290
+ }), /* @__PURE__ */ jsxs(Paper, {
1291
+ className: "p-2 pl-8",
1292
+ children: [/* @__PURE__ */ jsx(PropertyTree, {
1293
+ properties: values.properties ?? {},
1294
+ propertiesOrder,
1295
+ errors: {},
1296
+ onPropertyClick: (propertyKey, namespace) => {
1297
+ setSelectedPropertyKey(propertyKey);
1298
+ setSelectedPropertyNamespace(namespace);
1299
+ setPropertyDialogOpen(true);
1300
+ },
1301
+ onPropertyMove
1302
+ }), empty && /* @__PURE__ */ jsx(Typography, {
1303
+ variant: "label",
1304
+ className: "h-full flex items-center justify-center p-4",
1305
+ children: "Add the first property to this group"
1306
+ })]
1307
+ })]
1308
+ }),
1309
+ /* @__PURE__ */ jsxs("div", {
1310
+ className: "col-span-12",
1311
+ children: [/* @__PURE__ */ jsx(BooleanSwitchWithLabel, {
1312
+ position: "start",
1313
+ size: "medium",
1314
+ label: t("spread_children_as_columns"),
1315
+ onValueChange: (v) => setFieldValue("ui.spreadChildren", v),
1316
+ value: values.ui?.spreadChildren ?? false
1317
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Set this flag to true if you want to display the children of this group as individual columns. This will only work for top level groups." })]
1318
+ }),
1319
+ /* @__PURE__ */ jsx(PropertyFormDialog, {
1320
+ inArray: false,
1321
+ forceShowErrors: false,
1322
+ open: propertyDialogOpen,
1323
+ allowDataInference,
1324
+ onCancel: () => {
1325
+ setPropertyDialogOpen(false);
1326
+ setSelectedPropertyKey(void 0);
1327
+ setSelectedPropertyNamespace(void 0);
1328
+ },
1329
+ onOkClicked: () => {
1330
+ setPropertyDialogOpen(false);
1331
+ setSelectedPropertyKey(void 0);
1332
+ setSelectedPropertyNamespace(void 0);
1333
+ },
1334
+ getData,
1335
+ onDelete: deleteProperty,
1336
+ propertyKey: selectedPropertyKey,
1337
+ propertyNamespace: selectedPropertyNamespace,
1338
+ property: selectedProperty,
1339
+ existingProperty: Boolean(selectedPropertyKey),
1340
+ autoUpdateId: !selectedPropertyKey,
1341
+ autoOpenTypeSelect: !selectedPropertyKey,
1342
+ onPropertyChanged: onPropertyCreated,
1343
+ existingPropertyKeys: selectedPropertyKey ? void 0 : propertiesOrder,
1344
+ propertyConfigs
1345
+ })
1346
+ ] });
1347
+ }
1348
+ //#endregion
1349
+ //#region src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx
1350
+ function RepeatPropertyField({ showErrors, existing, disabled, getData, allowDataInference, propertyConfigs }) {
1351
+ const { values, handleChange, errors, setFieldValue, touched } = useFormex();
1352
+ const [propertyDialogOpen, setPropertyDialogOpen] = useState(false);
1353
+ const ofProperty = getIn(values, "of");
1354
+ const ofPropertyError = getIn(touched, "of") && getIn(errors, "of");
1355
+ const onPropertyChanged = ({ id, property, namespace }) => {
1356
+ setFieldValue("of", property);
1357
+ };
1358
+ const widget = ofProperty && getFieldConfig(ofProperty, propertyConfigs);
1359
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
1360
+ className: "col-span-12",
1361
+ children: [/* @__PURE__ */ jsx(Typography, {
1362
+ variant: "subtitle2",
1363
+ children: "Repeat component"
1364
+ }), /* @__PURE__ */ jsx(Field, {
1365
+ name: "of",
1366
+ value: ofProperty,
1367
+ children: ({}) => /* @__PURE__ */ jsxs(Paper, {
1368
+ className: "p-2 mt-4",
1369
+ children: [
1370
+ ofProperty && /* @__PURE__ */ jsx(PropertyFieldPreview, {
1371
+ property: ofProperty,
1372
+ onClick: disabled ? void 0 : () => setPropertyDialogOpen(true),
1373
+ includeName: false,
1374
+ includeEditButton: true,
1375
+ selected: false,
1376
+ hasError: false
1377
+ }),
1378
+ !disabled && !ofProperty && /* @__PURE__ */ jsxs(Button, {
1379
+ variant: "text",
1380
+ color: ofPropertyError ? "error" : "primary",
1381
+ onClick: () => setPropertyDialogOpen(true),
1382
+ children: ["Edit ", `${widget ? widget.name : "repeat component"}`]
1383
+ }),
1384
+ /* @__PURE__ */ jsx(PropertyFormDialog, {
1385
+ inArray: true,
1386
+ open: propertyDialogOpen,
1387
+ existingProperty: existing,
1388
+ getData,
1389
+ autoUpdateId: !existing,
1390
+ autoOpenTypeSelect: !existing,
1391
+ onOkClicked: () => setPropertyDialogOpen(false),
1392
+ allowDataInference,
1393
+ property: ofProperty,
1394
+ includeIdAndName: false,
1395
+ onPropertyChanged,
1396
+ forceShowErrors: showErrors,
1397
+ propertyConfigs
1398
+ })
1399
+ ]
1400
+ })
1401
+ })]
1402
+ }), /* @__PURE__ */ jsx("div", {
1403
+ className: "col-span-12",
1404
+ children: /* @__PURE__ */ jsx(ValidationPanel, { children: /* @__PURE__ */ jsx(ArrayPropertyValidation, { disabled }) })
1405
+ })] });
1406
+ }
1407
+ //#endregion
1408
+ //#region src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx
1409
+ var CommonPropertyFields = React.forwardRef(function CommonPropertyFields({ showErrors, disabledId, disabled, autoUpdateId, isNewProperty }, ref) {
1410
+ const { errors, values, setFieldValue, setFieldTouched, touched, validate } = useFormex();
1411
+ const { t } = useTranslation();
1412
+ const name = "name";
1413
+ const nameError = showErrors && getIn(errors, name);
1414
+ const id = "id";
1415
+ const idError = showErrors && getIn(errors, id);
1416
+ const description = "description";
1417
+ const descriptionError = showErrors && getIn(errors, description);
1418
+ return /* @__PURE__ */ jsxs("div", {
1419
+ className: "flex flex-col gap-2 col-span-12",
1420
+ children: [
1421
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Field, {
1422
+ name,
1423
+ inputRef: ref,
1424
+ as: DebouncedTextField,
1425
+ value: values[name],
1426
+ onChange: (e) => {
1427
+ const newNameValue = e.target.value;
1428
+ if (!getIn(touched, id) && autoUpdateId) setFieldValue(id, newNameValue ? toSnakeCase(newNameValue) : "", false);
1429
+ setFieldValue(name, newNameValue, true);
1430
+ setFieldTouched(name, true);
1431
+ },
1432
+ style: { fontSize: 20 },
1433
+ placeholder: t("field_name"),
1434
+ required: true,
1435
+ disabled,
1436
+ error: Boolean(nameError)
1437
+ }), /* @__PURE__ */ jsx(FieldCaption, {
1438
+ error: Boolean(nameError),
1439
+ children: nameError
1440
+ })] }),
1441
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(DebouncedTextField, {
1442
+ name: id,
1443
+ label: "ID",
1444
+ value: values[id],
1445
+ onChange: (e) => {
1446
+ const newIdValue = e.target.value;
1447
+ if (!getIn(touched, name) && autoUpdateId) setFieldValue(name, newIdValue ? prettifyIdentifier(newIdValue) : "");
1448
+ setFieldValue(id, newIdValue, true);
1449
+ setFieldTouched(id, true);
1450
+ },
1451
+ disabled: disabledId || disabled,
1452
+ required: true,
1453
+ size: "small",
1454
+ error: Boolean(idError)
1455
+ }), /* @__PURE__ */ jsx(FieldCaption, {
1456
+ error: Boolean(idError),
1457
+ children: idError
1458
+ })] }),
1459
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Field, {
1460
+ name: description,
1461
+ as: DebouncedTextField,
1462
+ label: t("description"),
1463
+ disabled,
1464
+ error: Boolean(descriptionError)
1465
+ }), /* @__PURE__ */ jsx(FieldCaption, {
1466
+ error: Boolean(descriptionError),
1467
+ children: descriptionError
1468
+ })] })
1469
+ ]
1470
+ });
1471
+ });
1472
+ //#endregion
1473
+ //#region src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx
1474
+ function StringPropertyField({ widgetId, disabled, showErrors }) {
1475
+ const { values, setFieldValue, touched, errors } = useFormex();
1476
+ const { t } = useTranslation();
1477
+ const columnTypePath = "columnType";
1478
+ const columnTypeValue = getIn(values, columnTypePath);
1479
+ const columnTypeError = getIn(touched, columnTypePath) && getIn(errors, columnTypePath);
1480
+ const isIdPath = "isId";
1481
+ const isIdValue = getIn(values, isIdPath);
1482
+ const isIdError = getIn(touched, isIdPath) && getIn(errors, isIdPath);
1483
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1484
+ /* @__PURE__ */ jsx("div", {
1485
+ className: "col-span-12",
1486
+ children: /* @__PURE__ */ jsxs(ValidationPanel, { children: [
1487
+ widgetId === "text_field" && /* @__PURE__ */ jsx(StringPropertyValidation, {
1488
+ disabled,
1489
+ length: true,
1490
+ lowercase: true,
1491
+ matches: true,
1492
+ max: true,
1493
+ min: true,
1494
+ trim: true,
1495
+ uppercase: true,
1496
+ showErrors
1497
+ }),
1498
+ widgetId === "user_select" && /* @__PURE__ */ jsx(StringPropertyValidation, {
1499
+ disabled,
1500
+ showErrors
1501
+ }),
1502
+ widgetId === "multiline" && /* @__PURE__ */ jsx(StringPropertyValidation, {
1503
+ disabled,
1504
+ length: true,
1505
+ lowercase: true,
1506
+ max: true,
1507
+ min: true,
1508
+ trim: true,
1509
+ uppercase: true,
1510
+ showErrors
1511
+ }),
1512
+ widgetId === "email" && /* @__PURE__ */ jsx(StringPropertyValidation, {
1513
+ disabled,
1514
+ max: true,
1515
+ min: true,
1516
+ trim: true,
1517
+ showErrors
1518
+ })
1519
+ ] })
1520
+ }),
1521
+ /* @__PURE__ */ jsxs("div", {
1522
+ className: "col-span-12",
1523
+ children: [/* @__PURE__ */ jsxs(Select, {
1524
+ name: columnTypePath,
1525
+ disabled: disabled || Boolean(isIdValue),
1526
+ fullWidth: true,
1527
+ value: isIdValue === "uuid" ? "uuid" : columnTypeValue ?? "_default_",
1528
+ onValueChange: (v) => setFieldValue(columnTypePath, v === "_default_" ? void 0 : v),
1529
+ renderValue: (v) => {
1530
+ if (isIdValue === "uuid") return "uuid (forced by Primary Key)";
1531
+ switch (v) {
1532
+ case "text": return "text (unlimited)";
1533
+ case "char": return "char (fixed length)";
1534
+ case "varchar": return "varchar (variable length)";
1535
+ case "_default_": return "Default (varchar)";
1536
+ default: return "Default (varchar)";
1537
+ }
1538
+ },
1539
+ error: Boolean(columnTypeError),
1540
+ label: t("db_column_type"),
1541
+ children: [
1542
+ isIdValue === "uuid" && /* @__PURE__ */ jsx(SelectItem, {
1543
+ value: "uuid",
1544
+ children: " uuid (forced by Primary Key) "
1545
+ }),
1546
+ /* @__PURE__ */ jsx(SelectItem, {
1547
+ value: "_default_",
1548
+ children: " Default (varchar) "
1549
+ }),
1550
+ /* @__PURE__ */ jsx(SelectItem, {
1551
+ value: "varchar",
1552
+ children: " varchar (variable length) "
1553
+ }),
1554
+ /* @__PURE__ */ jsx(SelectItem, {
1555
+ value: "text",
1556
+ children: " text (unlimited) "
1557
+ }),
1558
+ /* @__PURE__ */ jsx(SelectItem, {
1559
+ value: "char",
1560
+ children: " char (fixed length) "
1561
+ })
1562
+ ]
1563
+ }), /* @__PURE__ */ jsx(FieldCaption, {
1564
+ error: Boolean(columnTypeError),
1565
+ children: columnTypeError ?? "Optional database override for this string field."
1566
+ })]
1567
+ }),
1568
+ /* @__PURE__ */ jsxs("div", {
1569
+ className: "col-span-12",
1570
+ children: [/* @__PURE__ */ jsxs(Select, {
1571
+ name: isIdPath,
1572
+ disabled,
1573
+ fullWidth: true,
1574
+ value: isIdValue === true ? "true" : isIdValue === false ? "false" : isIdValue ?? "_default_",
1575
+ onValueChange: (v) => {
1576
+ if (v === "_default_" || v === "false") setFieldValue(isIdPath, void 0);
1577
+ else if (v === "true") setFieldValue(isIdPath, true);
1578
+ else setFieldValue(isIdPath, v);
1579
+ },
1580
+ renderValue: (v) => {
1581
+ switch (v) {
1582
+ case "true": return "Yes (Auto-generated UUID/String)";
1583
+ case "manual": return "Yes (Manual input)";
1584
+ case "uuid": return "Yes (UUID)";
1585
+ case "cuid": return "Yes (CUID)";
1586
+ case "false":
1587
+ case "_default_": return "No";
1588
+ default: return `Yes (${v})`;
1589
+ }
1590
+ },
1591
+ error: Boolean(isIdError),
1592
+ label: t("primary_key_unique_id"),
1593
+ children: [
1594
+ /* @__PURE__ */ jsx(SelectItem, {
1595
+ value: "_default_",
1596
+ children: " No "
1597
+ }),
1598
+ /* @__PURE__ */ jsx(SelectItem, {
1599
+ value: "manual",
1600
+ children: " Yes (Manual input) "
1601
+ }),
1602
+ /* @__PURE__ */ jsx(SelectItem, {
1603
+ value: "true",
1604
+ children: " Yes (Auto-generated UUID/String) "
1605
+ }),
1606
+ /* @__PURE__ */ jsx(SelectItem, {
1607
+ value: "uuid",
1608
+ children: " Yes (UUID) "
1609
+ }),
1610
+ /* @__PURE__ */ jsx(SelectItem, {
1611
+ value: "cuid",
1612
+ children: " Yes (CUID) "
1613
+ })
1614
+ ]
1615
+ }), /* @__PURE__ */ jsx(FieldCaption, {
1616
+ error: Boolean(isIdError),
1617
+ children: isIdError ?? "Set as Primary Key and configure ID generation strategy."
1618
+ })]
1619
+ }),
1620
+ /* @__PURE__ */ jsx("div", {
1621
+ className: "col-span-12",
1622
+ children: /* @__PURE__ */ jsx(TextField, {
1623
+ name: "defaultValue",
1624
+ disabled,
1625
+ onChange: (e) => {
1626
+ setFieldValue("defaultValue", e.target.value === "" ? void 0 : e.target.value);
1627
+ },
1628
+ label: t("default_value"),
1629
+ value: getIn(values, "defaultValue") ?? ""
1630
+ })
1631
+ })
1632
+ ] });
1633
+ }
1634
+ //#endregion
1635
+ //#region src/collection_editor/ui/collection_editor/properties/BooleanPropertyField.tsx
1636
+ function BooleanPropertyField({ disabled }) {
1637
+ const { values } = useFormex();
1638
+ const defaultValue = getIn(values, "defaultValue");
1639
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
1640
+ className: "col-span-12",
1641
+ children: /* @__PURE__ */ jsx(ValidationPanel, { children: /* @__PURE__ */ jsx(GeneralPropertyValidation, { disabled }) })
1642
+ }), /* @__PURE__ */ jsx("div", {
1643
+ className: "col-span-12",
1644
+ children: /* @__PURE__ */ jsx(Field, {
1645
+ name: "defaultValue",
1646
+ children: ({ field, form }) => {
1647
+ return /* @__PURE__ */ jsx(SwitchControl, {
1648
+ size: "medium",
1649
+ label: defaultValue === null || defaultValue === void 0 ? "Default value not set" : "Default value is " + defaultValue.toString(),
1650
+ disabled,
1651
+ allowIndeterminate: true,
1652
+ field,
1653
+ form
1654
+ });
1655
+ }
1656
+ })
1657
+ })] });
1658
+ }
1659
+ //#endregion
1660
+ //#region src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx
1661
+ function BlockPropertyField({ disabled, getData, allowDataInference, propertyConfigs }) {
1662
+ const { values, setFieldValue } = useFormex();
1663
+ const [propertyDialogOpen, setPropertyDialogOpen] = useState(false);
1664
+ const [selectedPropertyKey, setSelectedPropertyKey] = useState();
1665
+ const [selectedPropertyNamespace, setSelectedPropertyNamespace] = useState();
1666
+ const onPropertyChanged = ({ id, namespace, property }) => {
1667
+ if (!id) throw Error();
1668
+ setFieldValue("oneOf." + getFullIdPath(id, namespace), property, false);
1669
+ const currentPropertiesOrder = values.oneOf?.propertiesOrder ?? Object.keys(values.oneOf?.properties ?? {});
1670
+ const newPropertiesOrder = currentPropertiesOrder.includes(id) ? currentPropertiesOrder : [...currentPropertiesOrder, id];
1671
+ setFieldValue("oneOf." + namespaceToPropertiesOrderPath(namespace), newPropertiesOrder, false);
1672
+ setPropertyDialogOpen(false);
1673
+ };
1674
+ const selectedPropertyFullId = selectedPropertyKey ? getFullId(selectedPropertyKey, selectedPropertyNamespace) : void 0;
1675
+ const selectedProperty = selectedPropertyFullId ? getIn(values.oneOf?.properties, selectedPropertyFullId.replaceAll(".", ".properties.")) : void 0;
1676
+ const deleteProperty = (propertyKey, namespace) => {
1677
+ const fullId = propertyKey ? getFullId(propertyKey, namespace) : void 0;
1678
+ if (!fullId) throw Error("collection editor miss config");
1679
+ setFieldValue(`oneOf.${idToPropertiesPath(fullId)}`, void 0, false);
1680
+ const propertiesOrderPath = `oneOf.${namespaceToPropertiesOrderPath(namespace)}`;
1681
+ setFieldValue(propertiesOrderPath, (getIn(values, propertiesOrderPath) ?? Object.keys(getIn(values, namespaceToPropertiesPath(namespace)) ?? {})).filter((p) => p !== propertyKey), false);
1682
+ setPropertyDialogOpen(false);
1683
+ setSelectedPropertyKey(void 0);
1684
+ setSelectedPropertyNamespace(void 0);
1685
+ };
1686
+ const addChildButton = /* @__PURE__ */ jsxs(Button, {
1687
+ autoFocus: true,
1688
+ onClick: () => setPropertyDialogOpen(true),
1689
+ startIcon: /* @__PURE__ */ jsx(PlusIcon, {}),
1690
+ children: ["Add property to ", values.name ?? "this block"]
1691
+ });
1692
+ const onPropertyMove = (propertiesOrder, namespace) => {
1693
+ setFieldValue(`oneOf.${namespaceToPropertiesOrderPath(namespace)}`, propertiesOrder, false);
1694
+ };
1695
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
1696
+ className: "col-span-12",
1697
+ children: [/* @__PURE__ */ jsxs("div", {
1698
+ className: "flex justify-between items-end mt-8 mb-4",
1699
+ children: [/* @__PURE__ */ jsx(Typography, {
1700
+ variant: "subtitle2",
1701
+ children: "Properties in this block"
1702
+ }), addChildButton]
1703
+ }), /* @__PURE__ */ jsxs(Paper, {
1704
+ className: "p-2 pl-8",
1705
+ children: [/* @__PURE__ */ jsx(PropertyTree, {
1706
+ properties: values.oneOf?.properties ?? {},
1707
+ propertiesOrder: values.oneOf?.propertiesOrder,
1708
+ errors: {},
1709
+ onPropertyClick: disabled ? void 0 : (propertyKey, namespace) => {
1710
+ setSelectedPropertyKey(propertyKey);
1711
+ setSelectedPropertyNamespace(namespace);
1712
+ setPropertyDialogOpen(true);
1713
+ },
1714
+ onPropertyMove: disabled ? void 0 : onPropertyMove
1715
+ }), !disabled && values.oneOf?.propertiesOrder?.length === 0 && /* @__PURE__ */ jsx("div", {
1716
+ className: "h-full flex items-center justify-center p-4",
1717
+ children: "Add the first property to this block"
1718
+ })]
1719
+ })]
1720
+ }), !disabled && /* @__PURE__ */ jsx(PropertyFormDialog, {
1721
+ inArray: false,
1722
+ forceShowErrors: false,
1723
+ open: propertyDialogOpen,
1724
+ getData,
1725
+ allowDataInference,
1726
+ onCancel: () => {
1727
+ setPropertyDialogOpen(false);
1728
+ setSelectedPropertyKey(void 0);
1729
+ setSelectedPropertyNamespace(void 0);
1730
+ },
1731
+ onOkClicked: () => {
1732
+ setPropertyDialogOpen(false);
1733
+ setSelectedPropertyKey(void 0);
1734
+ setSelectedPropertyNamespace(void 0);
1735
+ },
1736
+ onDelete: deleteProperty,
1737
+ propertyKey: selectedPropertyKey,
1738
+ propertyNamespace: selectedPropertyNamespace,
1739
+ property: selectedProperty,
1740
+ existingProperty: Boolean(selectedPropertyKey),
1741
+ autoUpdateId: !selectedPropertyKey,
1742
+ autoOpenTypeSelect: !selectedPropertyKey,
1743
+ onPropertyChanged,
1744
+ existingPropertyKeys: selectedPropertyKey ? void 0 : values.oneOf?.propertiesOrder,
1745
+ propertyConfigs
1746
+ })] });
1747
+ }
1748
+ //#endregion
1749
+ //#region src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx
1750
+ function NumberPropertyValidation({ disabled }) {
1751
+ const { values, handleChange } = useFormex();
1752
+ const { t } = useTranslation();
1753
+ const validationMin = "validation.min";
1754
+ const validationMax = "validation.max";
1755
+ const validationLessThan = "validation.lessThan";
1756
+ const validationMoreThan = "validation.moreThan";
1757
+ return /* @__PURE__ */ jsxs("div", {
1758
+ className: "grid grid-cols-12 gap-2",
1759
+ children: [
1760
+ /* @__PURE__ */ jsx(GeneralPropertyValidation, { disabled }),
1761
+ /* @__PURE__ */ jsx("div", {
1762
+ className: "col-span-6",
1763
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
1764
+ value: getIn(values, validationMin),
1765
+ label: t("min_value"),
1766
+ name: validationMin,
1767
+ type: "number",
1768
+ size: "small",
1769
+ disabled,
1770
+ onChange: handleChange
1771
+ })
1772
+ }),
1773
+ /* @__PURE__ */ jsx("div", {
1774
+ className: "col-span-6",
1775
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
1776
+ value: getIn(values, validationMax),
1777
+ label: t("max_value"),
1778
+ name: validationMax,
1779
+ type: "number",
1780
+ size: "small",
1781
+ disabled,
1782
+ onChange: handleChange
1783
+ })
1784
+ }),
1785
+ /* @__PURE__ */ jsx("div", {
1786
+ className: "col-span-6",
1787
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
1788
+ value: getIn(values, validationLessThan),
1789
+ label: t("less_than"),
1790
+ name: validationLessThan,
1791
+ type: "number",
1792
+ size: "small",
1793
+ disabled,
1794
+ onChange: handleChange
1795
+ })
1796
+ }),
1797
+ /* @__PURE__ */ jsx("div", {
1798
+ className: "col-span-6",
1799
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
1800
+ value: getIn(values, validationMoreThan),
1801
+ label: t("more_than"),
1802
+ name: validationMoreThan,
1803
+ type: "number",
1804
+ size: "small",
1805
+ disabled,
1806
+ onChange: handleChange
1807
+ })
1808
+ }),
1809
+ /* @__PURE__ */ jsx("div", {
1810
+ className: "col-span-4",
1811
+ children: /* @__PURE__ */ jsx(Field, {
1812
+ name: "validation.positive",
1813
+ type: "checkbox",
1814
+ children: ({ field, form }) => {
1815
+ return /* @__PURE__ */ jsx(SwitchControl, {
1816
+ label: t("positive_value"),
1817
+ disabled,
1818
+ form,
1819
+ field
1820
+ });
1821
+ }
1822
+ })
1823
+ }),
1824
+ /* @__PURE__ */ jsx("div", {
1825
+ className: "col-span-4",
1826
+ children: /* @__PURE__ */ jsx(Field, {
1827
+ name: "validation.negative",
1828
+ type: "checkbox",
1829
+ children: ({ field, form }) => {
1830
+ return /* @__PURE__ */ jsx(SwitchControl, {
1831
+ label: t("negative_value"),
1832
+ disabled,
1833
+ form,
1834
+ field
1835
+ });
1836
+ }
1837
+ })
1838
+ }),
1839
+ /* @__PURE__ */ jsx("div", {
1840
+ className: "col-span-4",
1841
+ children: /* @__PURE__ */ jsx(Field, {
1842
+ name: "validation.integer",
1843
+ type: "checkbox",
1844
+ children: ({ field, form }) => {
1845
+ return /* @__PURE__ */ jsx(SwitchControl, {
1846
+ label: t("integer_value"),
1847
+ disabled,
1848
+ form,
1849
+ field
1850
+ });
1851
+ }
1852
+ })
1853
+ })
1854
+ ]
1855
+ });
1856
+ }
1857
+ //#endregion
1858
+ //#region src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx
1859
+ function NumberPropertyField({ disabled }) {
1860
+ const { values, setFieldValue, touched, errors } = useFormex();
1861
+ const { t } = useTranslation();
1862
+ const columnTypePath = "columnType";
1863
+ const columnTypeValue = getIn(values, columnTypePath);
1864
+ const columnTypeError = getIn(touched, columnTypePath) && getIn(errors, columnTypePath);
1865
+ const isIdPath = "isId";
1866
+ const isIdValue = getIn(values, isIdPath);
1867
+ const isIdError = getIn(touched, isIdPath) && getIn(errors, isIdPath);
1868
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1869
+ /* @__PURE__ */ jsx("div", {
1870
+ className: "col-span-12",
1871
+ children: /* @__PURE__ */ jsx(ValidationPanel, { children: /* @__PURE__ */ jsx(NumberPropertyValidation, { disabled }) })
1872
+ }),
1873
+ /* @__PURE__ */ jsxs("div", {
1874
+ className: "col-span-12",
1875
+ children: [/* @__PURE__ */ jsxs(Select, {
1876
+ name: columnTypePath,
1877
+ disabled: disabled || Boolean(isIdValue),
1878
+ fullWidth: true,
1879
+ value: columnTypeValue ?? "_default_",
1880
+ onValueChange: (v) => setFieldValue(columnTypePath, v === "_default_" ? void 0 : v),
1881
+ renderValue: (v) => {
1882
+ switch (v) {
1883
+ case "integer": return "integer";
1884
+ case "real": return "real (float4)";
1885
+ case "double precision": return "double precision (float8)";
1886
+ case "numeric": return "numeric / decimal";
1887
+ case "bigint": return "bigint";
1888
+ case "serial": return "serial";
1889
+ case "bigserial": return "bigserial";
1890
+ case "_default_": return "Default (integer/numeric)";
1891
+ default: return "Default (integer/numeric)";
1892
+ }
1893
+ },
1894
+ error: Boolean(columnTypeError),
1895
+ label: t("db_column_type"),
1896
+ children: [
1897
+ /* @__PURE__ */ jsx(SelectItem, {
1898
+ value: "_default_",
1899
+ children: " Default (integer/numeric) "
1900
+ }),
1901
+ /* @__PURE__ */ jsx(SelectItem, {
1902
+ value: "integer",
1903
+ children: " integer "
1904
+ }),
1905
+ /* @__PURE__ */ jsx(SelectItem, {
1906
+ value: "real",
1907
+ children: " real (float4) "
1908
+ }),
1909
+ /* @__PURE__ */ jsx(SelectItem, {
1910
+ value: "double precision",
1911
+ children: " double precision (float8) "
1912
+ }),
1913
+ /* @__PURE__ */ jsx(SelectItem, {
1914
+ value: "numeric",
1915
+ children: " numeric / decimal "
1916
+ }),
1917
+ /* @__PURE__ */ jsx(SelectItem, {
1918
+ value: "bigint",
1919
+ children: " bigint "
1920
+ }),
1921
+ /* @__PURE__ */ jsx(SelectItem, {
1922
+ value: "serial",
1923
+ children: " serial "
1924
+ }),
1925
+ /* @__PURE__ */ jsx(SelectItem, {
1926
+ value: "bigserial",
1927
+ children: " bigserial "
1928
+ })
1929
+ ]
1930
+ }), /* @__PURE__ */ jsx(FieldCaption, {
1931
+ error: Boolean(columnTypeError),
1932
+ children: columnTypeError ?? "Optional database override for this number field."
1933
+ })]
1934
+ }),
1935
+ /* @__PURE__ */ jsxs("div", {
1936
+ className: "col-span-12",
1937
+ children: [/* @__PURE__ */ jsxs(Select, {
1938
+ name: isIdPath,
1939
+ disabled,
1940
+ fullWidth: true,
1941
+ value: isIdValue === true ? "true" : isIdValue === false ? "false" : isIdValue ?? "_default_",
1942
+ onValueChange: (v) => {
1943
+ if (v === "_default_" || v === "false") setFieldValue(isIdPath, void 0);
1944
+ else if (v === "true") setFieldValue(isIdPath, true);
1945
+ else setFieldValue(isIdPath, v);
1946
+ },
1947
+ renderValue: (v) => {
1948
+ switch (v) {
1949
+ case "true": return "Yes (Auto-increment/identity)";
1950
+ case "increment": return "Yes (Increment)";
1951
+ case "manual": return "Yes (Manual input)";
1952
+ case "false":
1953
+ case "_default_": return "No";
1954
+ default: return `Yes (${v})`;
1955
+ }
1956
+ },
1957
+ error: Boolean(isIdError),
1958
+ label: t("primary_key_unique_id"),
1959
+ children: [
1960
+ /* @__PURE__ */ jsx(SelectItem, {
1961
+ value: "_default_",
1962
+ children: " No "
1963
+ }),
1964
+ /* @__PURE__ */ jsx(SelectItem, {
1965
+ value: "manual",
1966
+ children: " Yes (Manual input) "
1967
+ }),
1968
+ /* @__PURE__ */ jsx(SelectItem, {
1969
+ value: "true",
1970
+ children: " Yes (Auto-increment/identity) "
1971
+ }),
1972
+ /* @__PURE__ */ jsx(SelectItem, {
1973
+ value: "increment",
1974
+ children: " Yes (Increment) "
1975
+ })
1976
+ ]
1977
+ }), /* @__PURE__ */ jsx(FieldCaption, {
1978
+ error: Boolean(isIdError),
1979
+ children: isIdError ?? "Set as Primary Key and configure ID generation strategy."
1980
+ })]
1981
+ }),
1982
+ /* @__PURE__ */ jsx("div", {
1983
+ className: "col-span-12",
1984
+ children: /* @__PURE__ */ jsx(TextField, {
1985
+ name: "defaultValue",
1986
+ disabled,
1987
+ type: "number",
1988
+ onChange: (e) => {
1989
+ setFieldValue("defaultValue", e.target.value === "" ? void 0 : parseFloat(e.target.value));
1990
+ },
1991
+ label: t("default_value"),
1992
+ value: getIn(values, "defaultValue") ?? ""
1993
+ })
1994
+ })
1995
+ ] });
1996
+ }
1997
+ //#endregion
1998
+ //#region src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx
1999
+ function ReferencePropertyField({ existing, multiple, disabled, showErrors, asString }) {
2000
+ const { values, errors, setFieldValue } = useFormex();
2001
+ if (!useCollectionRegistryController().initialised) return /* @__PURE__ */ jsx("div", {
2002
+ className: "col-span-12",
2003
+ children: /* @__PURE__ */ jsx(CircularProgress, {})
2004
+ });
2005
+ const pathPath = asString ? "reference.slug" : multiple ? "of.slug" : "path";
2006
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", {
2007
+ className: "col-span-12",
2008
+ children: /* @__PURE__ */ jsx(Field, {
2009
+ name: pathPath,
2010
+ pathPath,
2011
+ type: "select",
2012
+ disabled,
2013
+ value: getIn(values, pathPath),
2014
+ error: showErrors && getIn(errors, pathPath),
2015
+ setFieldValue,
2016
+ as: CollectionsSelect
2017
+ })
2018
+ }) });
2019
+ }
2020
+ function CollectionsSelect({ disabled, pathPath, value, setFieldValue, error, ...props }) {
2021
+ const collectionRegistry = useCollectionRegistryController();
2022
+ const { t } = useTranslation();
2023
+ if (!collectionRegistry.initialised) return /* @__PURE__ */ jsx("div", {
2024
+ className: "col-span-12",
2025
+ children: /* @__PURE__ */ jsx(CircularProgress, {})
2026
+ });
2027
+ const collections = collectionRegistry.collections ?? [];
2028
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Select, {
2029
+ error: Boolean(error),
2030
+ disabled,
2031
+ value: value ?? "",
2032
+ position: "item-aligned",
2033
+ name: pathPath,
2034
+ fullWidth: true,
2035
+ onChange: (e) => setFieldValue(pathPath, e.target.value),
2036
+ label: t("target_collection"),
2037
+ renderValue: (selected) => {
2038
+ const selectedCollection = collections.find((collection) => collection.slug === selected);
2039
+ if (!selectedCollection) return null;
2040
+ return /* @__PURE__ */ jsxs("div", {
2041
+ className: "flex flex-row",
2042
+ children: [/* @__PURE__ */ jsx(IconForView, { collectionOrView: selectedCollection }), /* @__PURE__ */ jsx(Typography, {
2043
+ variant: "subtitle2",
2044
+ className: "ml-4",
2045
+ children: selectedCollection?.name.toUpperCase()
2046
+ })]
2047
+ });
2048
+ },
2049
+ ...props,
2050
+ children: collections.map((collection) => {
2051
+ return /* @__PURE__ */ jsx(SelectItem, {
2052
+ value: collection.slug,
2053
+ children: /* @__PURE__ */ jsxs("div", {
2054
+ className: "flex flex-row",
2055
+ children: [/* @__PURE__ */ jsx(IconForView, { collectionOrView: collection }), /* @__PURE__ */ jsx(Typography, {
2056
+ variant: "subtitle2",
2057
+ className: "ml-4",
2058
+ children: collection?.name.toUpperCase()
2059
+ })]
2060
+ })
2061
+ }, collection.slug);
2062
+ })
2063
+ }) });
2064
+ }
2065
+ //#endregion
2066
+ //#region src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx
2067
+ var TIMEZONES = [
2068
+ {
2069
+ value: "UTC",
2070
+ label: "UTC (Coordinated Universal Time)"
2071
+ },
2072
+ {
2073
+ value: "America/New_York",
2074
+ label: "New York (US Eastern)"
2075
+ },
2076
+ {
2077
+ value: "America/Chicago",
2078
+ label: "Chicago (US Central)"
2079
+ },
2080
+ {
2081
+ value: "America/Denver",
2082
+ label: "Denver (US Mountain)"
2083
+ },
2084
+ {
2085
+ value: "America/Los_Angeles",
2086
+ label: "Los Angeles (US Pacific)"
2087
+ },
2088
+ {
2089
+ value: "America/Anchorage",
2090
+ label: "Anchorage (Alaska)"
2091
+ },
2092
+ {
2093
+ value: "America/Toronto",
2094
+ label: "Toronto (Canada Eastern)"
2095
+ },
2096
+ {
2097
+ value: "America/Vancouver",
2098
+ label: "Vancouver (Canada Pacific)"
2099
+ },
2100
+ {
2101
+ value: "America/Mexico_City",
2102
+ label: "Mexico City"
2103
+ },
2104
+ {
2105
+ value: "America/Sao_Paulo",
2106
+ label: "São Paulo (Brazil)"
2107
+ },
2108
+ {
2109
+ value: "America/Buenos_Aires",
2110
+ label: "Buenos Aires (Argentina)"
2111
+ },
2112
+ {
2113
+ value: "Europe/London",
2114
+ label: "London (UK)"
2115
+ },
2116
+ {
2117
+ value: "Europe/Paris",
2118
+ label: "Paris (France)"
2119
+ },
2120
+ {
2121
+ value: "Europe/Berlin",
2122
+ label: "Berlin (Germany)"
2123
+ },
2124
+ {
2125
+ value: "Europe/Madrid",
2126
+ label: "Madrid (Spain)"
2127
+ },
2128
+ {
2129
+ value: "Europe/Rome",
2130
+ label: "Rome (Italy)"
2131
+ },
2132
+ {
2133
+ value: "Europe/Amsterdam",
2134
+ label: "Amsterdam (Netherlands)"
2135
+ },
2136
+ {
2137
+ value: "Europe/Brussels",
2138
+ label: "Brussels (Belgium)"
2139
+ },
2140
+ {
2141
+ value: "Europe/Zurich",
2142
+ label: "Zurich (Switzerland)"
2143
+ },
2144
+ {
2145
+ value: "Europe/Stockholm",
2146
+ label: "Stockholm (Sweden)"
2147
+ },
2148
+ {
2149
+ value: "Europe/Vienna",
2150
+ label: "Vienna (Austria)"
2151
+ },
2152
+ {
2153
+ value: "Europe/Warsaw",
2154
+ label: "Warsaw (Poland)"
2155
+ },
2156
+ {
2157
+ value: "Europe/Prague",
2158
+ label: "Prague (Czech Republic)"
2159
+ },
2160
+ {
2161
+ value: "Europe/Athens",
2162
+ label: "Athens (Greece)"
2163
+ },
2164
+ {
2165
+ value: "Europe/Moscow",
2166
+ label: "Moscow (Russia)"
2167
+ },
2168
+ {
2169
+ value: "Europe/Istanbul",
2170
+ label: "Istanbul (Turkey)"
2171
+ },
2172
+ {
2173
+ value: "Asia/Dubai",
2174
+ label: "Dubai (UAE)"
2175
+ },
2176
+ {
2177
+ value: "Asia/Kolkata",
2178
+ label: "Mumbai / Delhi (India)"
2179
+ },
2180
+ {
2181
+ value: "Asia/Bangkok",
2182
+ label: "Bangkok (Thailand)"
2183
+ },
2184
+ {
2185
+ value: "Asia/Singapore",
2186
+ label: "Singapore"
2187
+ },
2188
+ {
2189
+ value: "Asia/Hong_Kong",
2190
+ label: "Hong Kong"
2191
+ },
2192
+ {
2193
+ value: "Asia/Shanghai",
2194
+ label: "Shanghai (China)"
2195
+ },
2196
+ {
2197
+ value: "Asia/Tokyo",
2198
+ label: "Tokyo (Japan)"
2199
+ },
2200
+ {
2201
+ value: "Asia/Seoul",
2202
+ label: "Seoul (South Korea)"
2203
+ },
2204
+ {
2205
+ value: "Asia/Jakarta",
2206
+ label: "Jakarta (Indonesia)"
2207
+ },
2208
+ {
2209
+ value: "Australia/Sydney",
2210
+ label: "Sydney (Australia Eastern)"
2211
+ },
2212
+ {
2213
+ value: "Australia/Melbourne",
2214
+ label: "Melbourne (Australia)"
2215
+ },
2216
+ {
2217
+ value: "Australia/Brisbane",
2218
+ label: "Brisbane (Australia)"
2219
+ },
2220
+ {
2221
+ value: "Australia/Perth",
2222
+ label: "Perth (Australia Western)"
2223
+ },
2224
+ {
2225
+ value: "Pacific/Auckland",
2226
+ label: "Auckland (New Zealand)"
2227
+ },
2228
+ {
2229
+ value: "Africa/Cairo",
2230
+ label: "Cairo (Egypt)"
2231
+ },
2232
+ {
2233
+ value: "Africa/Johannesburg",
2234
+ label: "Johannesburg (South Africa)"
2235
+ },
2236
+ {
2237
+ value: "Africa/Lagos",
2238
+ label: "Lagos (Nigeria)"
2239
+ }
2240
+ ];
2241
+ function DateTimePropertyField({ disabled }) {
2242
+ const { values, errors, touched, setFieldValue } = useFormex();
2243
+ const { t } = useTranslation();
2244
+ const modePath = "mode";
2245
+ const modeValue = getIn(values, modePath);
2246
+ const modeError = getIn(touched, modePath) && getIn(errors, modePath);
2247
+ const autoValuePath = "autoValue";
2248
+ const autoValueValue = getIn(values, autoValuePath);
2249
+ const autoValueError = getIn(touched, autoValuePath) && getIn(errors, autoValuePath);
2250
+ const timezonePath = "timezone";
2251
+ const timezoneValue = getIn(values, timezonePath);
2252
+ const timezoneError = getIn(touched, timezonePath) && getIn(errors, timezonePath);
2253
+ const columnTypePath = "columnType";
2254
+ const columnTypeValue = getIn(values, columnTypePath);
2255
+ const columnTypeError = getIn(touched, columnTypePath) && getIn(errors, columnTypePath);
2256
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2257
+ /* @__PURE__ */ jsxs("div", {
2258
+ className: "flex flex-col col-span-12 gap-2",
2259
+ children: [
2260
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs(Select, {
2261
+ name: modePath,
2262
+ value: modeValue ?? "date",
2263
+ error: Boolean(modeError),
2264
+ onValueChange: (v) => setFieldValue(modePath, v),
2265
+ label: t("mode"),
2266
+ fullWidth: true,
2267
+ renderValue: (v) => {
2268
+ switch (v) {
2269
+ case "date_time": return "Date/Time";
2270
+ case "date": return "Date";
2271
+ default: return "";
2272
+ }
2273
+ },
2274
+ disabled,
2275
+ children: [/* @__PURE__ */ jsx(SelectItem, {
2276
+ value: "date_time",
2277
+ children: " Date/Time "
2278
+ }), /* @__PURE__ */ jsx(SelectItem, {
2279
+ value: "date",
2280
+ children: " Date "
2281
+ })]
2282
+ }), /* @__PURE__ */ jsx(FieldCaption, {
2283
+ error: Boolean(modeError),
2284
+ children: modeError
2285
+ })] }),
2286
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs(Select, {
2287
+ name: autoValuePath,
2288
+ disabled,
2289
+ fullWidth: true,
2290
+ value: autoValueValue ?? "",
2291
+ onValueChange: (v) => setFieldValue(autoValuePath, v === "none" ? null : v),
2292
+ renderValue: (v) => {
2293
+ switch (v) {
2294
+ case "on_create": return "On create";
2295
+ case "on_update": return "On any update";
2296
+ default: return "None";
2297
+ }
2298
+ },
2299
+ error: Boolean(autoValueError),
2300
+ label: t("datetime_automatic_value"),
2301
+ children: [
2302
+ /* @__PURE__ */ jsx(SelectItem, {
2303
+ value: "none",
2304
+ children: " None "
2305
+ }),
2306
+ /* @__PURE__ */ jsx(SelectItem, {
2307
+ value: "on_create",
2308
+ children: " On create "
2309
+ }),
2310
+ /* @__PURE__ */ jsx(SelectItem, {
2311
+ value: "on_update",
2312
+ children: " On any update "
2313
+ })
2314
+ ]
2315
+ }), /* @__PURE__ */ jsx(FieldCaption, {
2316
+ error: Boolean(autoValueError),
2317
+ children: autoValueError ?? "Update this field automatically when creating or updating the entity"
2318
+ })] }),
2319
+ /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs(Select, {
2320
+ name: timezonePath,
2321
+ disabled,
2322
+ fullWidth: true,
2323
+ value: timezoneValue ?? "__local__",
2324
+ onValueChange: (v) => setFieldValue(timezonePath, v === "__local__" ? void 0 : v),
2325
+ renderValue: (v) => {
2326
+ if (!v || v === "__local__") return "Local timezone";
2327
+ return TIMEZONES.find((t) => t.value === v)?.label ?? v;
2328
+ },
2329
+ error: Boolean(timezoneError),
2330
+ label: t("timezone"),
2331
+ children: [/* @__PURE__ */ jsx(SelectItem, {
2332
+ value: "__local__",
2333
+ children: " Local timezone "
2334
+ }), TIMEZONES.map((tz) => /* @__PURE__ */ jsx(SelectItem, {
2335
+ value: tz.value,
2336
+ children: tz.label
2337
+ }, tz.value))]
2338
+ }), /* @__PURE__ */ jsx(FieldCaption, {
2339
+ error: Boolean(timezoneError),
2340
+ children: timezoneError ?? "Timezone for displaying and inputting dates. Values are always stored in UTC."
2341
+ })] })
2342
+ ]
2343
+ }),
2344
+ /* @__PURE__ */ jsxs("div", {
2345
+ className: "col-span-12",
2346
+ children: [/* @__PURE__ */ jsxs(Select, {
2347
+ name: columnTypePath,
2348
+ disabled,
2349
+ fullWidth: true,
2350
+ value: columnTypeValue ?? "_default_",
2351
+ onValueChange: (v) => setFieldValue(columnTypePath, v === "_default_" ? void 0 : v),
2352
+ renderValue: (v) => {
2353
+ switch (v) {
2354
+ case "timestamp": return "timestamp (with timezone)";
2355
+ case "date": return "date";
2356
+ case "time": return "time";
2357
+ case "_default_": return "Default (timestamp)";
2358
+ default: return "Default (timestamp)";
2359
+ }
2360
+ },
2361
+ error: Boolean(columnTypeError),
2362
+ label: t("db_column_type"),
2363
+ children: [
2364
+ /* @__PURE__ */ jsx(SelectItem, {
2365
+ value: "_default_",
2366
+ children: " Default (timestamp) "
2367
+ }),
2368
+ /* @__PURE__ */ jsx(SelectItem, {
2369
+ value: "timestamp",
2370
+ children: " timestamp (with timezone) "
2371
+ }),
2372
+ /* @__PURE__ */ jsx(SelectItem, {
2373
+ value: "date",
2374
+ children: " date "
2375
+ }),
2376
+ /* @__PURE__ */ jsx(SelectItem, {
2377
+ value: "time",
2378
+ children: " time "
2379
+ })
2380
+ ]
2381
+ }), /* @__PURE__ */ jsx(FieldCaption, {
2382
+ error: Boolean(columnTypeError),
2383
+ children: columnTypeError ?? "Optional database override for this date field."
2384
+ })]
2385
+ }),
2386
+ /* @__PURE__ */ jsx("div", {
2387
+ className: "col-span-12",
2388
+ children: /* @__PURE__ */ jsx(ValidationPanel, { children: /* @__PURE__ */ jsx(GeneralPropertyValidation, { disabled }) })
2389
+ })
2390
+ ] });
2391
+ }
2392
+ //#endregion
2393
+ //#region src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx
2394
+ function AdvancedPropertyValidation({ disabled }) {
2395
+ return /* @__PURE__ */ jsxs("div", {
2396
+ className: "grid grid-cols-12 gap-2",
2397
+ children: [/* @__PURE__ */ jsx("div", {
2398
+ className: "col-span-12",
2399
+ children: /* @__PURE__ */ jsx(Field, {
2400
+ type: "checkbox",
2401
+ name: "ui.hideFromCollection",
2402
+ children: ({ field, form }) => {
2403
+ return /* @__PURE__ */ jsx(SwitchControl, {
2404
+ label: "Hide from collection",
2405
+ size: "small",
2406
+ disabled,
2407
+ form,
2408
+ tooltip: "Hide this field from the collection view. It will still be visible in the form view",
2409
+ field
2410
+ });
2411
+ }
2412
+ })
2413
+ }), /* @__PURE__ */ jsx("div", {
2414
+ className: "col-span-12",
2415
+ children: /* @__PURE__ */ jsx(Field, {
2416
+ name: "ui.readOnly",
2417
+ type: "checkbox",
2418
+ children: ({ field, form }) => {
2419
+ return /* @__PURE__ */ jsx(SwitchControl, {
2420
+ label: "Read only",
2421
+ size: "small",
2422
+ disabled,
2423
+ tooltip: "Is this a read only field. Display only as a preview",
2424
+ form,
2425
+ field
2426
+ });
2427
+ }
2428
+ })
2429
+ })]
2430
+ });
2431
+ }
2432
+ //#endregion
2433
+ //#region src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx
2434
+ function VectorPropertyField({ disabled }) {
2435
+ const { values, setFieldValue, touched, errors } = useFormex();
2436
+ const dimensionsPath = "dimensions";
2437
+ const dimensionsValue = getIn(values, dimensionsPath);
2438
+ const dimensionsError = getIn(touched, dimensionsPath) && getIn(errors, dimensionsPath);
2439
+ return /* @__PURE__ */ jsxs("div", {
2440
+ className: "col-span-12",
2441
+ children: [/* @__PURE__ */ jsx(TextField, {
2442
+ name: dimensionsPath,
2443
+ disabled,
2444
+ type: "number",
2445
+ onChange: (e) => {
2446
+ const parsedVal = parseInt(e.target.value);
2447
+ setFieldValue(dimensionsPath, isNaN(parsedVal) ? void 0 : parsedVal);
2448
+ },
2449
+ label: "Vector Dimensions",
2450
+ value: dimensionsValue ?? "",
2451
+ error: Boolean(dimensionsError)
2452
+ }), /* @__PURE__ */ jsx(FieldCaption, {
2453
+ error: Boolean(dimensionsError),
2454
+ children: dimensionsError ?? "The dimension size of the vector embeddings (e.g., 1536 for OpenAI text-embedding-3-small)."
2455
+ })]
2456
+ });
2457
+ }
2458
+ //#endregion
2459
+ //#region src/collection_editor/ui/collection_editor/properties/KeyValuePropertyField.tsx
2460
+ function KeyValuePropertyField({ disabled }) {
2461
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("div", {
2462
+ className: "col-span-12",
2463
+ children: /* @__PURE__ */ jsx(ValidationPanel, { children: /* @__PURE__ */ jsx(GeneralPropertyValidation, { disabled }) })
2464
+ }) });
2465
+ }
2466
+ //#endregion
2467
+ //#region src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx
2468
+ var ON_ACTION_OPTIONS = [
2469
+ "cascade",
2470
+ "restrict",
2471
+ "no action",
2472
+ "set null",
2473
+ "set default"
2474
+ ];
2475
+ function getTargetSlug(target) {
2476
+ if (!target) return "";
2477
+ if (typeof target === "string") return target;
2478
+ try {
2479
+ const resolved = target();
2480
+ if (typeof resolved === "string") return resolved;
2481
+ if (resolved && typeof resolved === "object" && "slug" in resolved && typeof resolved.slug === "string") return resolved.slug;
2482
+ return "";
2483
+ } catch {
2484
+ return "";
2485
+ }
2486
+ }
2487
+ /**
2488
+ * Property editor form for `type: "relation"` properties.
2489
+ *
2490
+ * This component edits the `RelationProperty` fields on the property itself (target, relationName, etc.)
2491
+ */
2492
+ function RelationPropertyField({ disabled, showErrors }) {
2493
+ const { values, errors, setFieldValue } = useFormex();
2494
+ const collectionRegistry = useCollectionRegistryController();
2495
+ const relationName = values.relationName ?? "";
2496
+ const targetSlug = getTargetSlug(values.target);
2497
+ const cardinality = values.cardinality ?? "one";
2498
+ const direction = values.direction ?? "owning";
2499
+ const localKey = values.localKey ?? "";
2500
+ const foreignKeyOnTarget = values.foreignKeyOnTarget ?? "";
2501
+ const through = values.through;
2502
+ const throughTable = through?.table ?? "";
2503
+ const throughSourceColumn = through?.sourceColumn ?? "";
2504
+ const throughTargetColumn = through?.targetColumn ?? "";
2505
+ const onUpdate = values.onUpdate ?? "no action";
2506
+ const onDelete = values.onDelete ?? "no action";
2507
+ const showThrough = cardinality === "many" && direction === "owning";
2508
+ const showLocalKey = direction === "owning" && cardinality === "one";
2509
+ const showForeignKey = direction === "inverse";
2510
+ const updateThrough = useCallback((patch) => {
2511
+ setFieldValue("through", {
2512
+ ...values.through ?? {
2513
+ table: "",
2514
+ sourceColumn: "",
2515
+ targetColumn: ""
2516
+ },
2517
+ ...patch
2518
+ });
2519
+ }, [values.through, setFieldValue]);
2520
+ useEffect(() => {
2521
+ if (targetSlug && !relationName) setFieldValue("relationName", targetSlug);
2522
+ }, [
2523
+ targetSlug,
2524
+ relationName,
2525
+ setFieldValue
2526
+ ]);
2527
+ collectionRegistry?.collections;
2528
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2529
+ /* @__PURE__ */ jsxs("div", {
2530
+ className: "col-span-12",
2531
+ children: [/* @__PURE__ */ jsx(CollectionsSelect, {
2532
+ disabled,
2533
+ pathPath: "target",
2534
+ value: targetSlug,
2535
+ setFieldValue: (_, value) => {
2536
+ setFieldValue("target", value);
2537
+ if (!relationName || relationName === targetSlug) setFieldValue("relationName", value);
2538
+ },
2539
+ error: showErrors && !targetSlug ? "You must select a target collection" : void 0
2540
+ }), /* @__PURE__ */ jsx(FieldCaption, {
2541
+ error: showErrors && !targetSlug,
2542
+ children: showErrors && !targetSlug ? "You must select a target collection" : "The collection this relation points to"
2543
+ })]
2544
+ }),
2545
+ /* @__PURE__ */ jsxs("div", {
2546
+ className: "col-span-12",
2547
+ children: [/* @__PURE__ */ jsx(TextField, {
2548
+ value: relationName,
2549
+ onChange: (e) => setFieldValue("relationName", e.target.value),
2550
+ label: "Relation name",
2551
+ disabled,
2552
+ error: showErrors && !relationName
2553
+ }), /* @__PURE__ */ jsx(FieldCaption, {
2554
+ error: showErrors && !relationName,
2555
+ children: showErrors && !relationName ? "Required" : "Identifier for this relation (used to link the property to the relation config)"
2556
+ })]
2557
+ }),
2558
+ /* @__PURE__ */ jsxs("div", {
2559
+ className: "col-span-12 sm:col-span-6",
2560
+ children: [/* @__PURE__ */ jsxs(Select, {
2561
+ value: cardinality,
2562
+ onValueChange: (v) => setFieldValue("cardinality", v),
2563
+ label: "Cardinality",
2564
+ disabled,
2565
+ fullWidth: true,
2566
+ renderValue: (v) => v === "one" ? "One (has-one)" : "Many (has-many)",
2567
+ children: [/* @__PURE__ */ jsx(SelectItem, {
2568
+ value: "one",
2569
+ children: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
2570
+ variant: "body2",
2571
+ children: "One (has-one)"
2572
+ }), /* @__PURE__ */ jsx(Typography, {
2573
+ variant: "caption",
2574
+ color: "secondary",
2575
+ children: "This property references a single record"
2576
+ })] })
2577
+ }), /* @__PURE__ */ jsx(SelectItem, {
2578
+ value: "many",
2579
+ children: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
2580
+ variant: "body2",
2581
+ children: "Many (has-many)"
2582
+ }), /* @__PURE__ */ jsx(Typography, {
2583
+ variant: "caption",
2584
+ color: "secondary",
2585
+ children: "This property references multiple records"
2586
+ })] })
2587
+ })]
2588
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Whether the relation returns one or multiple records" })]
2589
+ }),
2590
+ /* @__PURE__ */ jsxs("div", {
2591
+ className: "col-span-12 sm:col-span-6",
2592
+ children: [/* @__PURE__ */ jsxs(Select, {
2593
+ value: direction,
2594
+ onValueChange: (v) => setFieldValue("direction", v),
2595
+ label: "Direction",
2596
+ disabled,
2597
+ fullWidth: true,
2598
+ renderValue: (v) => v === "owning" ? "Owning" : "Inverse",
2599
+ children: [/* @__PURE__ */ jsx(SelectItem, {
2600
+ value: "owning",
2601
+ children: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
2602
+ variant: "body2",
2603
+ children: "Owning"
2604
+ }), /* @__PURE__ */ jsx(Typography, {
2605
+ variant: "caption",
2606
+ color: "secondary",
2607
+ children: "This table stores the foreign key (or owns the junction table)"
2608
+ })] })
2609
+ }), /* @__PURE__ */ jsx(SelectItem, {
2610
+ value: "inverse",
2611
+ children: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
2612
+ variant: "body2",
2613
+ children: "Inverse"
2614
+ }), /* @__PURE__ */ jsx(Typography, {
2615
+ variant: "caption",
2616
+ color: "secondary",
2617
+ children: "The target table stores the foreign key pointing back here"
2618
+ })] })
2619
+ })]
2620
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Which side of the relation owns the persistence" })]
2621
+ }),
2622
+ showLocalKey && /* @__PURE__ */ jsxs("div", {
2623
+ className: "col-span-12",
2624
+ children: [/* @__PURE__ */ jsx(TextField, {
2625
+ value: localKey,
2626
+ onChange: (e) => setFieldValue("localKey", e.target.value),
2627
+ label: "Local key (foreign key column on this table)",
2628
+ disabled,
2629
+ placeholder: "e.g. author_id"
2630
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Column on this table that references the target's primary key" })]
2631
+ }),
2632
+ showForeignKey && /* @__PURE__ */ jsxs("div", {
2633
+ className: "col-span-12",
2634
+ children: [/* @__PURE__ */ jsx(TextField, {
2635
+ value: foreignKeyOnTarget,
2636
+ onChange: (e) => setFieldValue("foreignKeyOnTarget", e.target.value),
2637
+ label: "Foreign key on target table",
2638
+ disabled,
2639
+ placeholder: "e.g. post_id"
2640
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Column on the target table that references this table's primary key" })]
2641
+ }),
2642
+ showThrough && /* @__PURE__ */ jsxs("div", {
2643
+ className: "col-span-12",
2644
+ children: [/* @__PURE__ */ jsx(Typography, {
2645
+ variant: "label",
2646
+ className: "mb-2",
2647
+ children: "Junction table (many-to-many)"
2648
+ }), /* @__PURE__ */ jsxs("div", {
2649
+ className: "grid grid-cols-12 gap-4",
2650
+ children: [
2651
+ /* @__PURE__ */ jsxs("div", {
2652
+ className: "col-span-12",
2653
+ children: [/* @__PURE__ */ jsx(TextField, {
2654
+ value: throughTable,
2655
+ onChange: (e) => updateThrough({ table: e.target.value }),
2656
+ label: "Junction table name",
2657
+ disabled,
2658
+ placeholder: "e.g. user_roles"
2659
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Name of the intermediate table that connects both collections" })]
2660
+ }),
2661
+ /* @__PURE__ */ jsxs("div", {
2662
+ className: "col-span-12 sm:col-span-6",
2663
+ children: [/* @__PURE__ */ jsx(TextField, {
2664
+ value: throughSourceColumn,
2665
+ onChange: (e) => updateThrough({ sourceColumn: e.target.value }),
2666
+ label: "Source column",
2667
+ disabled,
2668
+ placeholder: "e.g. user_id"
2669
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Column in the junction table referencing this table" })]
2670
+ }),
2671
+ /* @__PURE__ */ jsxs("div", {
2672
+ className: "col-span-12 sm:col-span-6",
2673
+ children: [/* @__PURE__ */ jsx(TextField, {
2674
+ value: throughTargetColumn,
2675
+ onChange: (e) => updateThrough({ targetColumn: e.target.value }),
2676
+ label: "Target column",
2677
+ disabled,
2678
+ placeholder: "e.g. role_id"
2679
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Column in the junction table referencing the target table" })]
2680
+ })
2681
+ ]
2682
+ })]
2683
+ }),
2684
+ /* @__PURE__ */ jsxs("div", {
2685
+ className: "col-span-12 sm:col-span-6",
2686
+ children: [/* @__PURE__ */ jsx(Select, {
2687
+ value: onUpdate,
2688
+ onValueChange: (v) => setFieldValue("onUpdate", v),
2689
+ label: "On update",
2690
+ disabled,
2691
+ fullWidth: true,
2692
+ renderValue: (v) => String(v),
2693
+ children: ON_ACTION_OPTIONS.map((action) => /* @__PURE__ */ jsx(SelectItem, {
2694
+ value: action,
2695
+ children: action
2696
+ }, action))
2697
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Action when the referenced record is updated" })]
2698
+ }),
2699
+ /* @__PURE__ */ jsxs("div", {
2700
+ className: "col-span-12 sm:col-span-6",
2701
+ children: [/* @__PURE__ */ jsx(Select, {
2702
+ value: onDelete,
2703
+ onValueChange: (v) => setFieldValue("onDelete", v),
2704
+ label: "On delete",
2705
+ disabled,
2706
+ fullWidth: true,
2707
+ renderValue: (v) => String(v),
2708
+ children: ON_ACTION_OPTIONS.map((action) => /* @__PURE__ */ jsx(SelectItem, {
2709
+ value: action,
2710
+ children: action
2711
+ }, action))
2712
+ }), /* @__PURE__ */ jsx(FieldCaption, { children: "Action when the referenced record is deleted" })]
2713
+ })
2714
+ ] });
2715
+ }
2716
+ //#endregion
2717
+ //#region src/collection_editor/ui/collection_editor/utils/update_property_for_widget.ts
2718
+ function updatePropertyFromWidget(propertyData, selectedWidgetId, propertyConfigs) {
2719
+ let updatedProperty;
2720
+ if (selectedWidgetId === "text_field") updatedProperty = mergeDeep(propertyData, {
2721
+ type: "string",
2722
+ propertyConfig: "text_field",
2723
+ storage: void 0,
2724
+ multiline: void 0,
2725
+ markdown: void 0,
2726
+ email: void 0,
2727
+ url: void 0,
2728
+ enum: void 0,
2729
+ userSelect: void 0
2730
+ });
2731
+ else if (selectedWidgetId === "user_select") updatedProperty = mergeDeep(propertyData, {
2732
+ type: "string",
2733
+ propertyConfig: "user_select",
2734
+ storage: void 0,
2735
+ multiline: void 0,
2736
+ markdown: void 0,
2737
+ email: void 0,
2738
+ url: void 0,
2739
+ enum: void 0,
2740
+ userSelect: true
2741
+ });
2742
+ else if (selectedWidgetId === "multiline") updatedProperty = mergeDeep(propertyData, {
2743
+ type: "string",
2744
+ propertyConfig: "multiline",
2745
+ multiline: true,
2746
+ storage: void 0,
2747
+ markdown: void 0,
2748
+ email: void 0,
2749
+ url: void 0,
2750
+ enum: void 0,
2751
+ userSelect: void 0
2752
+ });
2753
+ else if (selectedWidgetId === "markdown") updatedProperty = mergeDeep(propertyData, {
2754
+ type: "string",
2755
+ propertyConfig: "markdown",
2756
+ storage: void 0,
2757
+ multiline: void 0,
2758
+ markdown: true,
2759
+ email: void 0,
2760
+ url: void 0,
2761
+ userSelect: void 0
2762
+ });
2763
+ else if (selectedWidgetId === "url") updatedProperty = mergeDeep(propertyData, {
2764
+ type: "string",
2765
+ propertyConfig: "url",
2766
+ storage: void 0,
2767
+ multiline: void 0,
2768
+ markdown: void 0,
2769
+ email: void 0,
2770
+ url: true,
2771
+ enum: void 0,
2772
+ userSelect: void 0
2773
+ });
2774
+ else if (selectedWidgetId === "email") updatedProperty = mergeDeep(propertyData, {
2775
+ type: "string",
2776
+ propertyConfig: "email",
2777
+ storage: void 0,
2778
+ multiline: void 0,
2779
+ markdown: void 0,
2780
+ email: true,
2781
+ url: void 0,
2782
+ enum: void 0,
2783
+ userSelect: void 0
2784
+ });
2785
+ else if (selectedWidgetId === "select") updatedProperty = mergeDeep(propertyData, {
2786
+ type: "string",
2787
+ propertyConfig: "select",
2788
+ storage: void 0,
2789
+ multiline: void 0,
2790
+ markdown: void 0,
2791
+ email: void 0,
2792
+ url: void 0,
2793
+ enum: propertyData.enum ?? [],
2794
+ userSelect: void 0
2795
+ });
2796
+ else if (selectedWidgetId === "multi_select") updatedProperty = mergeDeep(propertyData, {
2797
+ type: "array",
2798
+ propertyConfig: "multi_select",
2799
+ of: {
2800
+ type: "string",
2801
+ enum: propertyData.of?.enum ?? []
2802
+ }
2803
+ });
2804
+ else if (selectedWidgetId === "number_input") updatedProperty = mergeDeep(propertyData, {
2805
+ type: "number",
2806
+ propertyConfig: "number_input",
2807
+ enum: void 0
2808
+ });
2809
+ else if (selectedWidgetId === "number_select") updatedProperty = mergeDeep(propertyData, {
2810
+ type: "number",
2811
+ propertyConfig: "number_select",
2812
+ enum: propertyData.enum ?? []
2813
+ });
2814
+ else if (selectedWidgetId === "multi_number_select") updatedProperty = mergeDeep(propertyData, {
2815
+ type: "array",
2816
+ propertyConfig: "multi_number_select",
2817
+ of: {
2818
+ type: "number",
2819
+ enum: propertyData.of?.enum ?? []
2820
+ }
2821
+ });
2822
+ else if (selectedWidgetId === "file_upload") updatedProperty = mergeDeep(propertyData, {
2823
+ type: "string",
2824
+ propertyConfig: "file_upload",
2825
+ storage: { storagePath: "/" }
2826
+ });
2827
+ else if (selectedWidgetId === "multi_file_upload") updatedProperty = mergeDeep(propertyData, {
2828
+ type: "array",
2829
+ propertyConfig: "multi_file_upload",
2830
+ of: {
2831
+ type: "string",
2832
+ storage: propertyData.of?.storage ?? { storagePath: "/" }
2833
+ }
2834
+ });
2835
+ else if (selectedWidgetId === "group") updatedProperty = mergeDeep(propertyData, {
2836
+ type: "map",
2837
+ propertyConfig: "group",
2838
+ keyValue: false,
2839
+ properties: propertyData.properties ?? {}
2840
+ });
2841
+ else if (selectedWidgetId === "key_value") updatedProperty = mergeDeep(propertyData, {
2842
+ type: "map",
2843
+ propertyConfig: "key_value",
2844
+ keyValue: true,
2845
+ properties: void 0
2846
+ });
2847
+ else if (selectedWidgetId === "reference") updatedProperty = mergeDeep(propertyData, {
2848
+ type: "reference",
2849
+ propertyConfig: "reference"
2850
+ });
2851
+ else if (selectedWidgetId === "reference_as_string") updatedProperty = mergeDeep(propertyData, {
2852
+ type: "string",
2853
+ propertyConfig: "reference_as_string"
2854
+ });
2855
+ else if (selectedWidgetId === "multi_references") updatedProperty = mergeDeep(propertyData, {
2856
+ type: "array",
2857
+ propertyConfig: "multi_references",
2858
+ of: { type: "reference" }
2859
+ });
2860
+ else if (selectedWidgetId === "switch") updatedProperty = mergeDeep(propertyData, {
2861
+ type: "boolean",
2862
+ propertyConfig: "switch"
2863
+ });
2864
+ else if (selectedWidgetId === "date_time") updatedProperty = mergeDeep(propertyData, {
2865
+ type: "date",
2866
+ propertyConfig: "date_time",
2867
+ mode: "date_time"
2868
+ });
2869
+ else if (selectedWidgetId === "relation") updatedProperty = mergeDeep(propertyData, {
2870
+ type: "relation",
2871
+ propertyConfig: "relation",
2872
+ relationName: propertyData.relationName ?? ""
2873
+ });
2874
+ else if (selectedWidgetId === "repeat") updatedProperty = mergeDeep(propertyData, {
2875
+ type: "array",
2876
+ propertyConfig: "repeat"
2877
+ });
2878
+ else if (selectedWidgetId === "block") updatedProperty = mergeDeep(propertyData, {
2879
+ type: "array",
2880
+ propertyConfig: "block",
2881
+ oneOf: { properties: {} }
2882
+ });
2883
+ else if (selectedWidgetId && propertyConfigs[selectedWidgetId]) updatedProperty = {
2884
+ ...propertyConfigs[selectedWidgetId].property,
2885
+ propertyConfig: selectedWidgetId
2886
+ };
2887
+ return updatedProperty;
2888
+ }
2889
+ //#endregion
2890
+ //#region src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx
2891
+ function UrlPropertyField({ disabled, showErrors }) {
2892
+ const { values, setFieldValue } = useFormex();
2893
+ const urlRawValue = getIn(values, "url");
2894
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2895
+ /* @__PURE__ */ jsx("div", {
2896
+ className: "col-span-12",
2897
+ children: /* @__PURE__ */ jsxs(Select, {
2898
+ disabled,
2899
+ position: "item-aligned",
2900
+ fullWidth: true,
2901
+ onValueChange: (value) => {
2902
+ if (value === "[NONE]") setFieldValue("url", true);
2903
+ else setFieldValue("url", value);
2904
+ },
2905
+ label: "Preview type",
2906
+ renderValue: (value) => {
2907
+ switch (value) {
2908
+ case "image": return "Image";
2909
+ case "video": return "Video";
2910
+ case "audio": return "Audio";
2911
+ default: return "Display URL";
2912
+ }
2913
+ },
2914
+ value: (typeof urlRawValue === "string" ? urlRawValue : "[NONE]") ?? "[NONE]",
2915
+ children: [
2916
+ /* @__PURE__ */ jsx(SelectItem, {
2917
+ value: "[NONE]",
2918
+ children: "Display URL"
2919
+ }),
2920
+ /* @__PURE__ */ jsx(SelectItem, {
2921
+ value: "image",
2922
+ children: "Image"
2923
+ }),
2924
+ /* @__PURE__ */ jsx(SelectItem, {
2925
+ value: "video",
2926
+ children: "Video"
2927
+ }),
2928
+ /* @__PURE__ */ jsx(SelectItem, {
2929
+ value: "audio",
2930
+ children: "Audio"
2931
+ })
2932
+ ]
2933
+ })
2934
+ }),
2935
+ /* @__PURE__ */ jsx("div", {
2936
+ className: "col-span-12",
2937
+ children: /* @__PURE__ */ jsx(ValidationPanel, { children: /* @__PURE__ */ jsx(StringPropertyValidation, {
2938
+ disabled,
2939
+ max: true,
2940
+ min: true,
2941
+ trim: true,
2942
+ showErrors
2943
+ }) })
2944
+ }),
2945
+ /* @__PURE__ */ jsx("div", {
2946
+ className: "col-span-12",
2947
+ children: /* @__PURE__ */ jsx(TextField, {
2948
+ name: "defaultValue",
2949
+ disabled,
2950
+ onChange: (e) => {
2951
+ setFieldValue("defaultValue", e.target.value === "" ? void 0 : e.target.value);
2952
+ },
2953
+ label: "Default value",
2954
+ value: getIn(values, "defaultValue") ?? ""
2955
+ })
2956
+ })
2957
+ ] });
2958
+ }
2959
+ //#endregion
2960
+ //#region src/collection_editor/ui/collection_editor/utils/supported_fields.tsx
2961
+ var supportedFieldsIds = [
2962
+ "text_field",
2963
+ "multiline",
2964
+ "markdown",
2965
+ "url",
2966
+ "email",
2967
+ "user_select",
2968
+ "select",
2969
+ "multi_select",
2970
+ "number_input",
2971
+ "number_select",
2972
+ "multi_number_select",
2973
+ "file_upload",
2974
+ "multi_file_upload",
2975
+ "reference",
2976
+ "reference_as_string",
2977
+ "multi_references",
2978
+ "relation",
2979
+ "switch",
2980
+ "date_time",
2981
+ "group",
2982
+ "key_value",
2983
+ "repeat",
2984
+ "block"
2985
+ ];
2986
+ var supportedFields = Object.entries(DEFAULT_FIELD_CONFIGS).filter(([id]) => supportedFieldsIds.includes(id)).map(([id, config]) => ({ [id]: config })).reduce((a, b) => ({
2987
+ ...a,
2988
+ ...b
2989
+ }), {});
2990
+ //#endregion
2991
+ //#region src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx
2992
+ function MarkdownPropertyField({ disabled, showErrors }) {
2993
+ const { values, setFieldValue } = useFormex();
2994
+ const { t } = useTranslation();
2995
+ const baseStoragePath = "storage";
2996
+ const fileName = `${baseStoragePath}.fileName`;
2997
+ const maxSize = `${baseStoragePath}.maxSize`;
2998
+ const storagePath = `${baseStoragePath}.storagePath`;
2999
+ const fileNameValue = getIn(values, fileName) ?? "{rand}_{file}";
3000
+ const storagePathValue = getIn(values, storagePath) ?? "/";
3001
+ const maxSizeValue = getIn(values, maxSize);
3002
+ const markdownValue = getIn(values, "markdown");
3003
+ const isMarkdownObject = typeof markdownValue === "object" && markdownValue !== null;
3004
+ const htmlValue = isMarkdownObject ? markdownValue.html ?? true : true;
3005
+ const transformPastedTextValue = isMarkdownObject ? markdownValue.transformPastedText ?? false : false;
3006
+ const hasFilenameCallback = typeof fileNameValue === "function";
3007
+ const hasStoragePathCallback = typeof storagePathValue === "function";
3008
+ const updateMarkdownConfig = useCallback((key, value) => {
3009
+ const currentMarkdown = getIn(values, "markdown");
3010
+ if (typeof currentMarkdown === "object" && currentMarkdown !== null) setFieldValue(`markdown.${key}`, value);
3011
+ else setFieldValue("markdown", {
3012
+ html: true,
3013
+ transformPastedText: false,
3014
+ [key]: value
3015
+ });
3016
+ }, [values, setFieldValue]);
3017
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3018
+ /* @__PURE__ */ jsx("div", {
3019
+ className: "col-span-12",
3020
+ children: /* @__PURE__ */ jsx(ValidationPanel, { children: /* @__PURE__ */ jsx(StringPropertyValidation, {
3021
+ disabled,
3022
+ length: true,
3023
+ lowercase: true,
3024
+ max: true,
3025
+ min: true,
3026
+ trim: true,
3027
+ uppercase: true,
3028
+ showErrors
3029
+ }) })
3030
+ }),
3031
+ /* @__PURE__ */ jsx("div", {
3032
+ className: "col-span-12",
3033
+ children: /* @__PURE__ */ jsx(ExpandablePanel, {
3034
+ title: /* @__PURE__ */ jsxs("div", {
3035
+ className: "flex flex-row text-surface-500",
3036
+ children: [/* @__PURE__ */ jsx(SettingsIcon, {}), /* @__PURE__ */ jsx(Typography, {
3037
+ variant: "subtitle2",
3038
+ className: "ml-4",
3039
+ children: "Paste behavior"
3040
+ })]
3041
+ }),
3042
+ children: /* @__PURE__ */ jsxs("div", {
3043
+ className: "flex flex-col gap-2 p-4",
3044
+ children: [
3045
+ /* @__PURE__ */ jsx(BooleanSwitchWithLabel, {
3046
+ size: "small",
3047
+ disabled,
3048
+ value: !htmlValue,
3049
+ onValueChange: (value) => updateMarkdownConfig("html", !value),
3050
+ label: t("markdown_strip_html")
3051
+ }),
3052
+ /* @__PURE__ */ jsx(Typography, {
3053
+ variant: "caption",
3054
+ className: "ml-3.5 mt-1 mb-2",
3055
+ children: "Remove HTML tags and inline styles when pasting content from external sources"
3056
+ }),
3057
+ /* @__PURE__ */ jsx(BooleanSwitchWithLabel, {
3058
+ size: "small",
3059
+ disabled,
3060
+ value: transformPastedTextValue,
3061
+ onValueChange: (value) => updateMarkdownConfig("transformPastedText", value),
3062
+ label: t("markdown_convert_pasted")
3063
+ }),
3064
+ /* @__PURE__ */ jsx(Typography, {
3065
+ variant: "caption",
3066
+ className: "ml-3.5 mt-1 mb-2",
3067
+ children: "Convert rich text (from Google Docs, Word, etc.) to clean markdown format"
3068
+ })
3069
+ ]
3070
+ })
3071
+ })
3072
+ }),
3073
+ /* @__PURE__ */ jsx("div", {
3074
+ className: "col-span-12",
3075
+ children: /* @__PURE__ */ jsx(ExpandablePanel, {
3076
+ title: /* @__PURE__ */ jsxs("div", {
3077
+ className: "flex flex-row text-surface-500",
3078
+ children: [/* @__PURE__ */ jsx(UploadCloudIcon, {}), /* @__PURE__ */ jsx(Typography, {
3079
+ variant: "subtitle2",
3080
+ className: "ml-4",
3081
+ children: "File upload config"
3082
+ })]
3083
+ }),
3084
+ children: /* @__PURE__ */ jsxs("div", {
3085
+ className: "grid grid-cols-12 gap-2 p-4",
3086
+ children: [
3087
+ /* @__PURE__ */ jsx("div", {
3088
+ className: "col-span-12",
3089
+ children: /* @__PURE__ */ jsx(Field, {
3090
+ name: fileName,
3091
+ as: DebouncedTextField,
3092
+ label: t("storage_file_name"),
3093
+ size: "small",
3094
+ disabled: hasFilenameCallback || disabled,
3095
+ value: hasFilenameCallback ? "-" : fileNameValue
3096
+ })
3097
+ }),
3098
+ /* @__PURE__ */ jsxs("div", {
3099
+ className: "col-span-12",
3100
+ children: [
3101
+ /* @__PURE__ */ jsx(Field, {
3102
+ name: storagePath,
3103
+ as: DebouncedTextField,
3104
+ label: t("storage_path"),
3105
+ disabled: hasStoragePathCallback || disabled,
3106
+ size: "small",
3107
+ value: hasStoragePathCallback ? "-" : storagePathValue
3108
+ }),
3109
+ /* @__PURE__ */ jsxs(Typography, {
3110
+ variant: "caption",
3111
+ className: "ml-3.5 mt-1 mb-2",
3112
+ children: [/* @__PURE__ */ jsx("p", { children: "You can use the following placeholders in the file name and storage path values:" }), /* @__PURE__ */ jsxs("ul", { children: [
3113
+ /* @__PURE__ */ jsx("li", { children: "{file} - Full name of the uploaded file" }),
3114
+ /* @__PURE__ */ jsx("li", { children: "{file.name} - Name of the uploaded file without extension" }),
3115
+ /* @__PURE__ */ jsx("li", { children: "{file.ext} - Extension of the uploaded file" }),
3116
+ /* @__PURE__ */ jsx("li", { children: "{entityId} - ID of the entity" }),
3117
+ /* @__PURE__ */ jsx("li", { children: "{propertyKey} - ID of this field" }),
3118
+ /* @__PURE__ */ jsx("li", { children: "{path} - Path of this entity" }),
3119
+ /* @__PURE__ */ jsx("li", { children: "{rand} - Random value used to avoid name collisions" })
3120
+ ] })]
3121
+ }),
3122
+ /* @__PURE__ */ jsx(Typography, {
3123
+ variant: "caption",
3124
+ className: "ml-3.5 mt-1 mb-2",
3125
+ children: "When using Markdown, the URL of the uploaded files are always saved in the text value (not the path)."
3126
+ })
3127
+ ]
3128
+ }),
3129
+ /* @__PURE__ */ jsx("div", {
3130
+ className: "col-span-12",
3131
+ children: /* @__PURE__ */ jsx(DebouncedTextField, {
3132
+ name: maxSize,
3133
+ type: "number",
3134
+ label: t("storage_max_size"),
3135
+ size: "small",
3136
+ value: maxSizeValue !== void 0 && maxSizeValue !== null ? maxSizeValue.toString() : "",
3137
+ onChange: (e) => {
3138
+ const value = e.target.value;
3139
+ if (value === "") setFieldValue(maxSize, void 0);
3140
+ else setFieldValue(maxSize, parseInt(value));
3141
+ }
3142
+ })
3143
+ })
3144
+ ]
3145
+ })
3146
+ })
3147
+ }),
3148
+ /* @__PURE__ */ jsx("div", {
3149
+ className: "col-span-12",
3150
+ children: /* @__PURE__ */ jsx(TextField, {
3151
+ name: "defaultValue",
3152
+ disabled,
3153
+ onChange: (e) => {
3154
+ setFieldValue("defaultValue", e.target.value === "" ? void 0 : e.target.value);
3155
+ },
3156
+ label: t("default_value"),
3157
+ value: getIn(values, "defaultValue") ?? ""
3158
+ })
3159
+ })
3160
+ ] });
3161
+ }
3162
+ //#endregion
3163
+ //#region src/collection_editor/ui/collection_editor/PropertyEditView.tsx
3164
+ var PropertyEditView_exports = /* @__PURE__ */ __exportAll({
3165
+ PropertyForm: () => PropertyForm,
3166
+ PropertyFormDialog: () => PropertyFormDialog,
3167
+ WidgetSelectViewItem: () => WidgetSelectViewItem
3168
+ });
3169
+ var PropertyForm = React.memo(function PropertyForm(props) {
3170
+ const { includeIdAndName = true, autoOpenTypeSelect, existingProperty, autoUpdateId, inArray, propertyKey, existingPropertyKeys, propertyNamespace, property, onPropertyChanged, onPropertyChangedImmediate = true, onDismiss, onDelete, onError, initialErrors, forceShowErrors, allowDataInference, getController, getData, propertyConfigs } = props;
3171
+ const initialValue = {
3172
+ id: "",
3173
+ name: ""
3174
+ };
3175
+ const disabled = Boolean(property && isPropertyBuilder(property));
3176
+ const lastSubmittedProperty = useRef(property ? {
3177
+ id: propertyKey,
3178
+ previousId: propertyKey,
3179
+ property
3180
+ } : void 0);
3181
+ const doOnPropertyChanged = ({ id, property }) => {
3182
+ const params = {
3183
+ id,
3184
+ previousId: lastSubmittedProperty.current?.id,
3185
+ property,
3186
+ namespace: propertyNamespace
3187
+ };
3188
+ lastSubmittedProperty.current = params;
3189
+ onPropertyChanged?.(params);
3190
+ };
3191
+ const formexController = useCreateFormex({
3192
+ debugId: "PROPERTY_FORM",
3193
+ initialValues: property ? {
3194
+ id: propertyKey,
3195
+ ...property
3196
+ } : initialValue,
3197
+ initialErrors,
3198
+ validateOnChange: true,
3199
+ validateOnInitialRender: true,
3200
+ onSubmit: (newPropertyWithId, controller) => {
3201
+ const { id, ...property } = newPropertyWithId;
3202
+ doOnPropertyChanged({
3203
+ id,
3204
+ property
3205
+ });
3206
+ if (!existingProperty) controller.resetForm({ values: initialValue });
3207
+ },
3208
+ validation: (values) => {
3209
+ const errors = {};
3210
+ if (includeIdAndName) {
3211
+ if (!values.name) errors.name = "Required";
3212
+ else {
3213
+ const nameError = validateName(values.name);
3214
+ if (nameError) errors.name = nameError;
3215
+ }
3216
+ if (!values.id) errors.id = "Required";
3217
+ else {
3218
+ const idError = validateId(values.id, existingPropertyKeys);
3219
+ if (idError) errors.id = idError;
3220
+ }
3221
+ }
3222
+ if (values.type === "string") {
3223
+ if (values.validation?.matches && !isValidRegExp(values.validation?.matches.toString())) errors.validation = { matches: "Invalid regular expression" };
3224
+ }
3225
+ if (values.type === "reference" && !values.path) errors.slug = "You must specify a target collection for the field";
3226
+ if (values.type === "vector" && (!values.dimensions || isNaN(Number(values.dimensions)) || Number(values.dimensions) <= 0)) errors.dimensions = "Vector dimensions must be a positive number";
3227
+ if (values.propertyConfig === "repeat") {
3228
+ if (!("of" in values) || !values.of) errors.of = "You need to specify a repeat field";
3229
+ }
3230
+ if (values.propertyConfig === "block") {
3231
+ if (!("oneOf" in values) || !values.oneOf) errors.oneOf = "You need to specify the properties of this block";
3232
+ }
3233
+ return errors;
3234
+ }
3235
+ });
3236
+ useEffect(() => {
3237
+ getController?.(formexController);
3238
+ }, [formexController, getController]);
3239
+ return /* @__PURE__ */ jsx(Formex, {
3240
+ value: formexController,
3241
+ children: /* @__PURE__ */ jsx(PropertyEditFormFields, {
3242
+ onPropertyChanged: onPropertyChangedImmediate ? doOnPropertyChanged : void 0,
3243
+ onDelete,
3244
+ includeIdAndTitle: includeIdAndName,
3245
+ propertyNamespace,
3246
+ onError,
3247
+ onDismiss,
3248
+ showErrors: forceShowErrors || formexController.submitCount > 0,
3249
+ existing: existingProperty,
3250
+ autoUpdateId,
3251
+ inArray,
3252
+ autoOpenTypeSelect,
3253
+ disabled,
3254
+ getData,
3255
+ allowDataInference,
3256
+ propertyConfigs,
3257
+ ...formexController
3258
+ })
3259
+ });
3260
+ }, (a, b) => a.getData === b.getData && a.propertyKey === b.propertyKey && a.propertyNamespace === b.propertyNamespace && a.includeIdAndName === b.includeIdAndName && a.autoOpenTypeSelect === b.autoOpenTypeSelect && a.autoUpdateId === b.autoUpdateId && a.existingPropertyKeys === b.existingPropertyKeys && a.existingProperty === b.existingProperty);
3261
+ function PropertyFormDialog({ open, onCancel, onOkClicked, onPropertyChanged, getData, ...formProps }) {
3262
+ const formexRef = useRef(void 0);
3263
+ const getController = (helpers) => {
3264
+ formexRef.current = helpers;
3265
+ };
3266
+ return /* @__PURE__ */ jsx(Dialog, {
3267
+ open: open ?? false,
3268
+ maxWidth: "xl",
3269
+ fullWidth: true,
3270
+ children: /* @__PURE__ */ jsxs("form", {
3271
+ noValidate: true,
3272
+ autoComplete: "off",
3273
+ onSubmit: (e) => {
3274
+ e.preventDefault();
3275
+ e.stopPropagation();
3276
+ formexRef.current?.handleSubmit(e);
3277
+ },
3278
+ children: [
3279
+ /* @__PURE__ */ jsx(DialogTitle, {
3280
+ hidden: true,
3281
+ children: "Property edit view"
3282
+ }),
3283
+ /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx(PropertyForm, {
3284
+ ...formProps,
3285
+ onDismiss: onCancel,
3286
+ onPropertyChanged: (params) => {
3287
+ onPropertyChanged?.(params);
3288
+ onOkClicked?.();
3289
+ },
3290
+ onPropertyChangedImmediate: false,
3291
+ getController,
3292
+ getData
3293
+ }) }),
3294
+ /* @__PURE__ */ jsxs(DialogActions, { children: [onCancel && /* @__PURE__ */ jsx(Button, {
3295
+ variant: "text",
3296
+ onClick: () => {
3297
+ onCancel();
3298
+ formexRef.current?.resetForm();
3299
+ },
3300
+ children: "Cancel"
3301
+ }), /* @__PURE__ */ jsx(Button, {
3302
+ type: "submit",
3303
+ children: "Ok"
3304
+ })] })
3305
+ ]
3306
+ })
3307
+ });
3308
+ }
3309
+ function PropertyEditFormFields({ values, errors, setValues, existing, autoUpdateId = false, autoOpenTypeSelect, includeIdAndTitle, onPropertyChanged, onDelete, propertyNamespace, onDismiss, onError, showErrors, disabled, inArray, getData, allowDataInference, propertyConfigs }) {
3310
+ const [selectOpen, setSelectOpen] = useState(autoOpenTypeSelect);
3311
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
3312
+ const [selectedFieldConfigId, setSelectedFieldConfigId] = useState(values?.type ? getFieldId(values) : void 0);
3313
+ const deferredValues = useDeferredValue(values);
3314
+ const nameFieldRef = useRef(null);
3315
+ const lastSubmittedProperty = useRef(values);
3316
+ const selectedWidgetError = showErrors && getIn(errors, "selectedWidget");
3317
+ useEffect(() => {
3318
+ if (onPropertyChanged) {
3319
+ if (!includeIdAndTitle || deferredValues.id) {
3320
+ const { id, ...property } = deferredValues;
3321
+ if (!deepEqual(deferredValues, lastSubmittedProperty.current)) {
3322
+ onPropertyChanged({
3323
+ id,
3324
+ property,
3325
+ namespace: propertyNamespace
3326
+ });
3327
+ lastSubmittedProperty.current = deferredValues;
3328
+ }
3329
+ }
3330
+ }
3331
+ }, [
3332
+ deferredValues,
3333
+ includeIdAndTitle,
3334
+ propertyNamespace
3335
+ ]);
3336
+ useEffect(() => {
3337
+ if (values?.id && onError) onError(values?.id, propertyNamespace, errors);
3338
+ }, [
3339
+ errors,
3340
+ propertyNamespace,
3341
+ values?.id
3342
+ ]);
3343
+ const onWidgetSelectChanged = (newSelectedWidgetId) => {
3344
+ setSelectedFieldConfigId(newSelectedWidgetId);
3345
+ setValues(updatePropertyFromWidget(values, newSelectedWidgetId, propertyConfigs));
3346
+ setTimeout(() => {
3347
+ nameFieldRef.current?.focus();
3348
+ }, 0);
3349
+ };
3350
+ let childComponent;
3351
+ if (selectedFieldConfigId === "text_field" || selectedFieldConfigId === "multiline" || selectedFieldConfigId === "user_select" || selectedFieldConfigId === "email") childComponent = /* @__PURE__ */ jsx(StringPropertyField, {
3352
+ widgetId: selectedFieldConfigId,
3353
+ disabled,
3354
+ showErrors
3355
+ });
3356
+ else if (selectedFieldConfigId === "url") childComponent = /* @__PURE__ */ jsx(UrlPropertyField, {
3357
+ disabled,
3358
+ showErrors
3359
+ });
3360
+ else if (selectedFieldConfigId === "markdown") childComponent = /* @__PURE__ */ jsx(MarkdownPropertyField, {
3361
+ disabled,
3362
+ showErrors
3363
+ });
3364
+ else if (selectedFieldConfigId === "select" || selectedFieldConfigId === "number_select") childComponent = /* @__PURE__ */ jsx(EnumPropertyField, {
3365
+ multiselect: false,
3366
+ allowDataInference,
3367
+ updateIds: !existing,
3368
+ disabled,
3369
+ getData,
3370
+ propertyNamespace,
3371
+ showErrors
3372
+ });
3373
+ else if (selectedFieldConfigId === "multi_select" || selectedFieldConfigId === "multi_number_select") childComponent = /* @__PURE__ */ jsx(EnumPropertyField, {
3374
+ multiselect: true,
3375
+ updateIds: !existing,
3376
+ disabled,
3377
+ allowDataInference,
3378
+ getData,
3379
+ propertyNamespace,
3380
+ showErrors
3381
+ });
3382
+ else if (selectedFieldConfigId === "file_upload") childComponent = /* @__PURE__ */ jsx(StoragePropertyField, {
3383
+ existing,
3384
+ multiple: false,
3385
+ disabled
3386
+ });
3387
+ else if (selectedFieldConfigId === "multi_file_upload") childComponent = /* @__PURE__ */ jsx(StoragePropertyField, {
3388
+ existing,
3389
+ multiple: true,
3390
+ disabled
3391
+ });
3392
+ else if (selectedFieldConfigId === "switch") childComponent = /* @__PURE__ */ jsx(BooleanPropertyField, { disabled });
3393
+ else if (selectedFieldConfigId === "number_input") childComponent = /* @__PURE__ */ jsx(NumberPropertyField, { disabled });
3394
+ else if (selectedFieldConfigId === "group") childComponent = /* @__PURE__ */ jsx(MapPropertyField, {
3395
+ disabled,
3396
+ getData,
3397
+ allowDataInference,
3398
+ propertyConfigs
3399
+ });
3400
+ else if (selectedFieldConfigId === "block") childComponent = /* @__PURE__ */ jsx(BlockPropertyField, {
3401
+ disabled,
3402
+ getData,
3403
+ allowDataInference,
3404
+ propertyConfigs
3405
+ });
3406
+ else if (selectedFieldConfigId === "reference") childComponent = /* @__PURE__ */ jsx(ReferencePropertyField, {
3407
+ showErrors,
3408
+ existing,
3409
+ multiple: false,
3410
+ disabled
3411
+ });
3412
+ else if (selectedFieldConfigId === "reference_as_string") childComponent = /* @__PURE__ */ jsx(ReferencePropertyField, {
3413
+ showErrors,
3414
+ existing,
3415
+ asString: true,
3416
+ multiple: false,
3417
+ disabled
3418
+ });
3419
+ else if (selectedFieldConfigId === "date_time") childComponent = /* @__PURE__ */ jsx(DateTimePropertyField, { disabled });
3420
+ else if (selectedFieldConfigId === "multi_references") childComponent = /* @__PURE__ */ jsx(ReferencePropertyField, {
3421
+ showErrors,
3422
+ existing,
3423
+ multiple: true,
3424
+ disabled
3425
+ });
3426
+ else if (selectedFieldConfigId === "repeat") childComponent = /* @__PURE__ */ jsx(RepeatPropertyField, {
3427
+ showErrors,
3428
+ existing,
3429
+ getData,
3430
+ allowDataInference,
3431
+ disabled,
3432
+ propertyConfigs
3433
+ });
3434
+ else if (selectedFieldConfigId === "key_value") childComponent = /* @__PURE__ */ jsx(KeyValuePropertyField, { disabled });
3435
+ else if (selectedFieldConfigId === "relation") childComponent = /* @__PURE__ */ jsx(RelationPropertyField, {
3436
+ showErrors,
3437
+ disabled
3438
+ });
3439
+ else if (selectedFieldConfigId === "vector_input") childComponent = /* @__PURE__ */ jsx(VectorPropertyField, { disabled });
3440
+ else childComponent = null;
3441
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3442
+ disabled && /* @__PURE__ */ jsxs(InfoLabel, {
3443
+ mode: "warn",
3444
+ children: [/* @__PURE__ */ jsx(Typography, { children: "This property can't be edited" }), /* @__PURE__ */ jsx(Typography, {
3445
+ variant: "caption",
3446
+ children: "You may not have permission to edit it or it is defined in code and cannot be modified."
3447
+ })]
3448
+ }),
3449
+ /* @__PURE__ */ jsxs("div", {
3450
+ className: "flex mt-2 items-start justify-between",
3451
+ children: [/* @__PURE__ */ jsxs("div", {
3452
+ className: "w-full flex flex-col gap-2",
3453
+ children: [/* @__PURE__ */ jsx(WidgetSelectView, {
3454
+ initialProperty: values,
3455
+ value: selectedFieldConfigId,
3456
+ onValueChange: (value) => onWidgetSelectChanged(value),
3457
+ open: selectOpen,
3458
+ onOpenChange: (open, hasValue) => {
3459
+ if (!hasValue) onDismiss?.();
3460
+ setSelectOpen(open);
3461
+ },
3462
+ disabled,
3463
+ showError: Boolean(selectedWidgetError),
3464
+ existing,
3465
+ propertyConfigs,
3466
+ inArray
3467
+ }), !!selectedWidgetError && /* @__PURE__ */ jsx(Typography, {
3468
+ variant: "caption",
3469
+ className: "ml-3.5",
3470
+ color: "error",
3471
+ children: "Required"
3472
+ })]
3473
+ }), onDelete && values?.id && /* @__PURE__ */ jsx(IconButton, {
3474
+ variant: "ghost",
3475
+ className: "mt-1 shrink-0",
3476
+ disabled,
3477
+ onClick: () => setDeleteDialogOpen(true),
3478
+ children: /* @__PURE__ */ jsx(Trash2Icon, { size: iconSize.small })
3479
+ })]
3480
+ }),
3481
+ /* @__PURE__ */ jsxs("div", {
3482
+ className: "grid grid-cols-12 gap-y-8 mt-6 mb-8",
3483
+ children: [
3484
+ includeIdAndTitle && /* @__PURE__ */ jsx(CommonPropertyFields, {
3485
+ showErrors,
3486
+ disabledId: existing,
3487
+ isNewProperty: !existing,
3488
+ disabled,
3489
+ autoUpdateId,
3490
+ ref: nameFieldRef
3491
+ }),
3492
+ childComponent,
3493
+ /* @__PURE__ */ jsx("div", {
3494
+ className: "col-span-12",
3495
+ children: /* @__PURE__ */ jsx(AdvancedPropertyValidation, { disabled })
3496
+ })
3497
+ ]
3498
+ }),
3499
+ onDelete && /* @__PURE__ */ jsx(ConfirmationDialog, {
3500
+ open: deleteDialogOpen,
3501
+ onAccept: () => onDelete(values?.id, propertyNamespace),
3502
+ onCancel: () => setDeleteDialogOpen(false),
3503
+ title: /* @__PURE__ */ jsx("div", { children: "Delete this property?" }),
3504
+ body: /* @__PURE__ */ jsxs("div", { children: [
3505
+ " This will ",
3506
+ /* @__PURE__ */ jsx("b", { children: "not delete any data" }),
3507
+ ", only modify the collection."
3508
+ ] })
3509
+ })
3510
+ ] });
3511
+ }
3512
+ var idRegEx = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
3513
+ function validateId(value, existingPropertyKeys) {
3514
+ let error;
3515
+ if (!value) error = "You must specify an id for the field";
3516
+ if (value && !value.match(idRegEx)) error = "The id can only contain letters, numbers and underscores (_), and not start with a number";
3517
+ if (value && existingPropertyKeys && existingPropertyKeys.includes(value)) error = "There is another field with this ID already";
3518
+ return error;
3519
+ }
3520
+ function validateName(value) {
3521
+ let error;
3522
+ if (!value) error = "You must specify a title for the field";
3523
+ return error;
3524
+ }
3525
+ var WIDGET_TYPE_MAP = {
3526
+ text_field: "Text",
3527
+ multiline: "Text",
3528
+ markdown: "Text",
3529
+ url: "Text",
3530
+ email: "Text",
3531
+ switch: "Boolean",
3532
+ user_select: "Users",
3533
+ select: "Select",
3534
+ multi_select: "Select",
3535
+ number_input: "Number",
3536
+ number_select: "Select",
3537
+ multi_number_select: "Select",
3538
+ file_upload: "File",
3539
+ multi_file_upload: "File",
3540
+ relation: "Relation",
3541
+ reference: "Reference",
3542
+ reference_as_string: "Text",
3543
+ multi_references: "Reference",
3544
+ date_time: "Date",
3545
+ group: "Group",
3546
+ key_value: "Group",
3547
+ repeat: "Array",
3548
+ custom_array: "Array",
3549
+ block: "Group",
3550
+ vector_input: "Number"
3551
+ };
3552
+ function WidgetSelectView({ initialProperty, value, onValueChange, open, onOpenChange, disabled, showError, existing, propertyConfigs, inArray }) {
3553
+ const allSupportedFields = Object.entries(supportedFields).concat(Object.entries(propertyConfigs));
3554
+ const displayedWidgets = (inArray ? allSupportedFields.filter(([_, propertyConfig]) => !isPropertyBuilder(propertyConfig.property) && propertyConfig.property?.type !== "array") : allSupportedFields).map(([key, propertyConfig]) => ({ [key]: propertyConfig })).reduce((a, b) => {
3555
+ return {
3556
+ ...a,
3557
+ ...b
3558
+ };
3559
+ }, {});
3560
+ const key = value;
3561
+ const propertyConfig = key ? DEFAULT_FIELD_CONFIGS[key] ?? propertyConfigs[key] : void 0;
3562
+ const baseProperty = propertyConfig?.property;
3563
+ const baseFieldConfig = baseProperty && !isPropertyBuilder(baseProperty) ? getFieldConfig(baseProperty, propertyConfigs) : void 0;
3564
+ const computedFieldConfig = baseFieldConfig && propertyConfig ? mergeDeep(baseFieldConfig, propertyConfig) : propertyConfig;
3565
+ const groups = [...new Set(Object.keys(displayedWidgets).map((key) => {
3566
+ const group = WIDGET_TYPE_MAP[key];
3567
+ if (group) return group;
3568
+ return "Custom/Other";
3569
+ }))];
3570
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
3571
+ onClick: () => {
3572
+ if (!disabled) onOpenChange(!open, Boolean(value));
3573
+ },
3574
+ className: cls("select-none rounded-md text-sm py-2 px-1 transition-colors duration-200", !disabled && "hover:bg-surface-50 dark:hover:bg-surface-800 cursor-pointer", "relative flex items-center mb-2"),
3575
+ children: [!value && /* @__PURE__ */ jsx("em", { children: "Select a property widget" }), value && computedFieldConfig && /* @__PURE__ */ jsxs("div", {
3576
+ className: cls("flex items-center"),
3577
+ children: [/* @__PURE__ */ jsx("div", {
3578
+ className: "mr-4",
3579
+ children: /* @__PURE__ */ jsx(PropertyConfigBadge, { propertyConfig: computedFieldConfig })
3580
+ }), /* @__PURE__ */ jsxs("div", {
3581
+ className: "flex flex-col items-start text-left",
3582
+ children: [/* @__PURE__ */ jsx("div", {
3583
+ className: "font-semibold text-text-primary dark:text-text-primary-dark tracking-tight",
3584
+ children: computedFieldConfig.name
3585
+ }), /* @__PURE__ */ jsx(Typography, {
3586
+ variant: "caption",
3587
+ className: "text-text-secondary dark:text-text-secondary-dark mt-0.5",
3588
+ children: computedFieldConfig.description
3589
+ })]
3590
+ })]
3591
+ })]
3592
+ }), /* @__PURE__ */ jsxs(Dialog, {
3593
+ open,
3594
+ onOpenChange: (open) => onOpenChange(open, Boolean(value)),
3595
+ maxWidth: "4xl",
3596
+ children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Select a property widget" }), /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx("div", { children: groups.map((group) => {
3597
+ return /* @__PURE__ */ jsxs("div", {
3598
+ className: "mt-4",
3599
+ children: [/* @__PURE__ */ jsx(Typography, {
3600
+ variant: "label",
3601
+ children: group
3602
+ }), /* @__PURE__ */ jsx("div", {
3603
+ className: "grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-2 mt-4",
3604
+ children: Object.entries(displayedWidgets).map(([key, propertyConfig]) => {
3605
+ if (WIDGET_TYPE_MAP[key] === group) return /* @__PURE__ */ jsx(WidgetSelectViewItem, {
3606
+ initialProperty,
3607
+ onClick: () => {
3608
+ onValueChange(key);
3609
+ onOpenChange(false, true);
3610
+ },
3611
+ propertyConfig,
3612
+ existing
3613
+ }, key);
3614
+ return null;
3615
+ })
3616
+ })]
3617
+ }, group);
3618
+ }) }) })]
3619
+ })] });
3620
+ }
3621
+ function WidgetSelectViewItem({ onClick, initialProperty, propertyConfig, existing }) {
3622
+ const baseProperty = propertyConfig.property;
3623
+ const shouldWarnChangingtype = existing && !isPropertyBuilder(baseProperty) && baseProperty.type !== initialProperty?.type;
3624
+ return /* @__PURE__ */ jsx(Card, {
3625
+ onClick,
3626
+ className: "flex flex-row items-center px-4 py-2 m-1",
3627
+ children: /* @__PURE__ */ jsxs("div", {
3628
+ className: cls("flex flex-row items-center text-base min-h-[48px]"),
3629
+ children: [/* @__PURE__ */ jsx("div", {
3630
+ className: "mr-8",
3631
+ children: /* @__PURE__ */ jsx(PropertyConfigBadge, {
3632
+ propertyConfig,
3633
+ disabled: shouldWarnChangingtype
3634
+ })
3635
+ }), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
3636
+ className: "flex flex-row gap-2 items-center",
3637
+ children: [shouldWarnChangingtype && /* @__PURE__ */ jsx(Tooltip, {
3638
+ title: "This widget uses a different data type than the initially selected widget. This can cause errors with existing data.",
3639
+ children: /* @__PURE__ */ jsx(AlertTriangleIcon, {
3640
+ size: iconSize.smallest,
3641
+ className: "w-4"
3642
+ })
3643
+ }), /* @__PURE__ */ jsx(Typography, {
3644
+ variant: "label",
3645
+ color: shouldWarnChangingtype ? "secondary" : void 0,
3646
+ children: propertyConfig.name
3647
+ })]
3648
+ }), /* @__PURE__ */ jsx(Typography, {
3649
+ variant: "caption",
3650
+ color: "secondary",
3651
+ className: "max-w-sm",
3652
+ children: propertyConfig.description
3653
+ })] })]
3654
+ })
3655
+ });
3656
+ }
3657
+ //#endregion
3658
+ export { updatePropertyFromWidget as a, useAIModifiedPaths as c, supportedFields as i, PropertyForm as n, PropertyTree as o, PropertyFormDialog as r, AIModifiedPathsProvider as s, PropertyEditView_exports as t };
3659
+
3660
+ //# sourceMappingURL=PropertyEditView-DEUddmg_.js.map