@maxal_studio/kratosjs-react 1.0.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 (529) hide show
  1. package/README.md +44 -0
  2. package/dist/FieldRenderer.d.ts +13 -0
  3. package/dist/FieldRenderer.js +62 -0
  4. package/dist/FormRenderer.d.ts +7 -0
  5. package/dist/FormRenderer.js +78 -0
  6. package/dist/TableRenderer.d.ts +2 -0
  7. package/dist/TableRenderer.js +1 -0
  8. package/dist/api/actionsApi.d.ts +23 -0
  9. package/dist/api/actionsApi.js +46 -0
  10. package/dist/api/authenticatedFetch.d.ts +8 -0
  11. package/dist/api/authenticatedFetch.js +31 -0
  12. package/dist/api/exportApi.d.ts +18 -0
  13. package/dist/api/exportApi.js +50 -0
  14. package/dist/api/http.d.ts +24 -0
  15. package/dist/api/http.js +52 -0
  16. package/dist/api/resourceApi.d.ts +37 -0
  17. package/dist/api/resourceApi.js +52 -0
  18. package/dist/api/tableApi.d.ts +83 -0
  19. package/dist/api/tableApi.js +51 -0
  20. package/dist/api/urls.d.ts +19 -0
  21. package/dist/api/urls.js +46 -0
  22. package/dist/app.d.ts +101 -0
  23. package/dist/app.js +89 -0
  24. package/dist/auth/AuthContext.d.ts +22 -0
  25. package/dist/auth/AuthContext.js +147 -0
  26. package/dist/auth/LoginPage.d.ts +10 -0
  27. package/dist/auth/LoginPage.js +179 -0
  28. package/dist/auth/ProtectedRoute.d.ts +12 -0
  29. package/dist/auth/ProtectedRoute.js +22 -0
  30. package/dist/auth/authApiClient.d.ts +24 -0
  31. package/dist/auth/authApiClient.js +95 -0
  32. package/dist/auth/types.d.ts +103 -0
  33. package/dist/auth/types.js +1 -0
  34. package/dist/components/ActionFormModal.d.ts +22 -0
  35. package/dist/components/ActionFormModal.js +8 -0
  36. package/dist/components/AdminPanel.d.ts +11 -0
  37. package/dist/components/AdminPanel.js +194 -0
  38. package/dist/components/Checkbox.d.ts +10 -0
  39. package/dist/components/Checkbox.js +8 -0
  40. package/dist/components/CheckboxField.d.ts +7 -0
  41. package/dist/components/CheckboxField.js +26 -0
  42. package/dist/components/ColorPickerField.d.ts +7 -0
  43. package/dist/components/ColorPickerField.js +26 -0
  44. package/dist/components/DateTimePickerField.d.ts +7 -0
  45. package/dist/components/DateTimePickerField.js +64 -0
  46. package/dist/components/FileUploadField.d.ts +9 -0
  47. package/dist/components/FileUploadField.js +478 -0
  48. package/dist/components/GlobalSearch.d.ts +22 -0
  49. package/dist/components/GlobalSearch.js +181 -0
  50. package/dist/components/GroupField.d.ts +7 -0
  51. package/dist/components/GroupField.js +23 -0
  52. package/dist/components/HiddenField.d.ts +3 -0
  53. package/dist/components/HiddenField.js +10 -0
  54. package/dist/components/ModalBreadcrumb.d.ts +5 -0
  55. package/dist/components/ModalBreadcrumb.js +33 -0
  56. package/dist/components/ModalDrawer.d.ts +15 -0
  57. package/dist/components/ModalDrawer.js +40 -0
  58. package/dist/components/RadioField.d.ts +7 -0
  59. package/dist/components/RadioField.js +26 -0
  60. package/dist/components/RepeaterField.d.ts +3 -0
  61. package/dist/components/RepeaterField.js +191 -0
  62. package/dist/components/ResourceModalRenderer.d.ts +10 -0
  63. package/dist/components/ResourceModalRenderer.js +80 -0
  64. package/dist/components/RichEditorField.d.ts +3 -0
  65. package/dist/components/RichEditorField.js +655 -0
  66. package/dist/components/SectionField.d.ts +9 -0
  67. package/dist/components/SectionField.js +111 -0
  68. package/dist/components/SelectField.d.ts +8 -0
  69. package/dist/components/SelectField.js +523 -0
  70. package/dist/components/TabsField.d.ts +10 -0
  71. package/dist/components/TabsField.js +214 -0
  72. package/dist/components/TagsInputField.d.ts +7 -0
  73. package/dist/components/TagsInputField.js +172 -0
  74. package/dist/components/TextInputField.d.ts +7 -0
  75. package/dist/components/TextInputField.js +44 -0
  76. package/dist/components/TextareaField.d.ts +7 -0
  77. package/dist/components/TextareaField.js +31 -0
  78. package/dist/components/ToggleField.d.ts +7 -0
  79. package/dist/components/ToggleField.js +57 -0
  80. package/dist/components/ViewModal.d.ts +25 -0
  81. package/dist/components/ViewModal.js +159 -0
  82. package/dist/components/blocks/BlockRenderer.d.ts +7 -0
  83. package/dist/components/blocks/BlockRenderer.js +36 -0
  84. package/dist/components/blocks/FormBlockRenderer.d.ts +6 -0
  85. package/dist/components/blocks/FormBlockRenderer.js +110 -0
  86. package/dist/components/blocks/TableBlockRenderer.d.ts +6 -0
  87. package/dist/components/blocks/TableBlockRenderer.js +12 -0
  88. package/dist/components/blocks/TabsBlockRenderer.d.ts +7 -0
  89. package/dist/components/blocks/TabsBlockRenderer.js +11 -0
  90. package/dist/components/blocks/WidgetBlockRenderer.d.ts +6 -0
  91. package/dist/components/blocks/WidgetBlockRenderer.js +11 -0
  92. package/dist/components/columns/CheckboxColumnComponent.d.ts +6 -0
  93. package/dist/components/columns/CheckboxColumnComponent.js +21 -0
  94. package/dist/components/columns/ColorColumnComponent.d.ts +3 -0
  95. package/dist/components/columns/ColorColumnComponent.js +11 -0
  96. package/dist/components/columns/DeeplinkWrapper.d.ts +15 -0
  97. package/dist/components/columns/DeeplinkWrapper.js +85 -0
  98. package/dist/components/columns/IconColumnComponent.d.ts +3 -0
  99. package/dist/components/columns/IconColumnComponent.js +52 -0
  100. package/dist/components/columns/ImageColumnComponent.d.ts +3 -0
  101. package/dist/components/columns/ImageColumnComponent.js +98 -0
  102. package/dist/components/columns/MediaColumnComponent.d.ts +3 -0
  103. package/dist/components/columns/MediaColumnComponent.js +160 -0
  104. package/dist/components/columns/SelectColumnComponent.d.ts +6 -0
  105. package/dist/components/columns/SelectColumnComponent.js +26 -0
  106. package/dist/components/columns/TagsColumnComponent.d.ts +3 -0
  107. package/dist/components/columns/TagsColumnComponent.js +18 -0
  108. package/dist/components/columns/TextColumnComponent.d.ts +11 -0
  109. package/dist/components/columns/TextColumnComponent.js +107 -0
  110. package/dist/components/columns/TextInputColumnComponent.d.ts +6 -0
  111. package/dist/components/columns/TextInputColumnComponent.js +18 -0
  112. package/dist/components/columns/ToggleColumnComponent.d.ts +6 -0
  113. package/dist/components/columns/ToggleColumnComponent.js +25 -0
  114. package/dist/components/columns/VideoColumnComponent.d.ts +3 -0
  115. package/dist/components/columns/VideoColumnComponent.js +125 -0
  116. package/dist/components/columns/ViewColumnComponent.d.ts +3 -0
  117. package/dist/components/columns/ViewColumnComponent.js +7 -0
  118. package/dist/components/errors/ErrorBoundary.d.ts +23 -0
  119. package/dist/components/errors/ErrorBoundary.js +33 -0
  120. package/dist/components/filters/CustomFilterComponent.d.ts +10 -0
  121. package/dist/components/filters/CustomFilterComponent.js +33 -0
  122. package/dist/components/filters/DateFilterComponent.d.ts +15 -0
  123. package/dist/components/filters/DateFilterComponent.js +132 -0
  124. package/dist/components/filters/QueryBuilderFilterComponent.d.ts +11 -0
  125. package/dist/components/filters/QueryBuilderFilterComponent.js +200 -0
  126. package/dist/components/layout/Header.d.ts +10 -0
  127. package/dist/components/layout/Header.js +70 -0
  128. package/dist/components/layout/PanelBrandMark.d.ts +8 -0
  129. package/dist/components/layout/PanelBrandMark.js +28 -0
  130. package/dist/components/layout/Sidebar.d.ts +35 -0
  131. package/dist/components/layout/Sidebar.js +125 -0
  132. package/dist/components/modals/RelationCreateModal.d.ts +19 -0
  133. package/dist/components/modals/RelationCreateModal.js +57 -0
  134. package/dist/components/modals/ResourceFormModal.d.ts +37 -0
  135. package/dist/components/modals/ResourceFormModal.js +44 -0
  136. package/dist/components/modals/useResourceForm.d.ts +40 -0
  137. package/dist/components/modals/useResourceForm.js +138 -0
  138. package/dist/components/modals/view/RecordActions.d.ts +17 -0
  139. package/dist/components/modals/view/RecordActions.js +16 -0
  140. package/dist/components/modals/view/RecordDetails.d.ts +13 -0
  141. package/dist/components/modals/view/RecordDetails.js +29 -0
  142. package/dist/components/modals/view/RelationPanel.d.ts +18 -0
  143. package/dist/components/modals/view/RelationPanel.js +16 -0
  144. package/dist/components/modals/view/RelationTabs.d.ts +32 -0
  145. package/dist/components/modals/view/RelationTabs.js +42 -0
  146. package/dist/components/modals/view/useRecordView.d.ts +18 -0
  147. package/dist/components/modals/view/useRecordView.js +114 -0
  148. package/dist/components/pages/PageRenderer.d.ts +6 -0
  149. package/dist/components/pages/PageRenderer.js +107 -0
  150. package/dist/components/table/ColumnTogglePopup.d.ts +11 -0
  151. package/dist/components/table/ColumnTogglePopup.js +16 -0
  152. package/dist/components/table/GridCard.d.ts +21 -0
  153. package/dist/components/table/GridCard.js +30 -0
  154. package/dist/components/table/GridView.d.ts +23 -0
  155. package/dist/components/table/GridView.js +49 -0
  156. package/dist/components/table/LayoutToggle.d.ts +7 -0
  157. package/dist/components/table/LayoutToggle.js +9 -0
  158. package/dist/components/table/TableActionsDropdown.d.ts +13 -0
  159. package/dist/components/table/TableActionsDropdown.js +46 -0
  160. package/dist/components/table/TableBulkActions.d.ts +11 -0
  161. package/dist/components/table/TableBulkActions.js +21 -0
  162. package/dist/components/table/TableHeader.d.ts +14 -0
  163. package/dist/components/table/TableHeader.js +23 -0
  164. package/dist/components/table/TablePagination.d.ts +13 -0
  165. package/dist/components/table/TablePagination.js +55 -0
  166. package/dist/components/table/TableRow.d.ts +21 -0
  167. package/dist/components/table/TableRow.js +32 -0
  168. package/dist/components/table/TableSearchBar.d.ts +11 -0
  169. package/dist/components/table/TableSearchBar.js +12 -0
  170. package/dist/components/table/TableTabs.d.ts +14 -0
  171. package/dist/components/table/TableTabs.js +8 -0
  172. package/dist/components/ui/Badge.d.ts +6 -0
  173. package/dist/components/ui/Badge.js +12 -0
  174. package/dist/components/ui/Button.d.ts +22 -0
  175. package/dist/components/ui/Button.js +22 -0
  176. package/dist/components/ui/Card.d.ts +7 -0
  177. package/dist/components/ui/Card.js +5 -0
  178. package/dist/components/ui/ConfirmDialog.d.ts +19 -0
  179. package/dist/components/ui/ConfirmDialog.js +45 -0
  180. package/dist/components/ui/EmptyState.d.ts +9 -0
  181. package/dist/components/ui/EmptyState.js +6 -0
  182. package/dist/components/ui/ErrorAlert.d.ts +7 -0
  183. package/dist/components/ui/ErrorAlert.js +9 -0
  184. package/dist/components/ui/Input.d.ts +11 -0
  185. package/dist/components/ui/Input.js +10 -0
  186. package/dist/components/ui/Label.d.ts +5 -0
  187. package/dist/components/ui/Label.js +5 -0
  188. package/dist/components/ui/PillButton.d.ts +14 -0
  189. package/dist/components/ui/PillButton.js +19 -0
  190. package/dist/components/ui/Select.d.ts +7 -0
  191. package/dist/components/ui/Select.js +7 -0
  192. package/dist/components/ui/Spinner.d.ts +8 -0
  193. package/dist/components/ui/Spinner.js +14 -0
  194. package/dist/components/ui/Toast.d.ts +21 -0
  195. package/dist/components/ui/Toast.js +47 -0
  196. package/dist/components/ui/index.d.ts +24 -0
  197. package/dist/components/ui/index.js +12 -0
  198. package/dist/components/utils/HintDisplay.d.ts +11 -0
  199. package/dist/components/utils/HintDisplay.js +12 -0
  200. package/dist/components/utils/Icon.d.ts +22 -0
  201. package/dist/components/utils/Icon.js +22 -0
  202. package/dist/components/utils/MediaPreviewModal.d.ts +14 -0
  203. package/dist/components/utils/MediaPreviewModal.js +32 -0
  204. package/dist/components/utils/ViewFieldWrapper.d.ts +11 -0
  205. package/dist/components/utils/ViewFieldWrapper.js +9 -0
  206. package/dist/components/utils/layoutHelpers.d.ts +19 -0
  207. package/dist/components/utils/layoutHelpers.js +257 -0
  208. package/dist/components/widgets/ChartWidget.d.ts +16 -0
  209. package/dist/components/widgets/ChartWidget.js +192 -0
  210. package/dist/components/widgets/StatsWidget.d.ts +16 -0
  211. package/dist/components/widgets/StatsWidget.js +39 -0
  212. package/dist/components/widgets/WidgetRenderer.d.ts +10 -0
  213. package/dist/components/widgets/WidgetRenderer.js +50 -0
  214. package/dist/components/widgets/WidgetShell.d.ts +9 -0
  215. package/dist/components/widgets/WidgetShell.js +7 -0
  216. package/dist/contexts/AuthChallengeRegistryContext.d.ts +15 -0
  217. package/dist/contexts/AuthChallengeRegistryContext.js +15 -0
  218. package/dist/contexts/BlockRegistryContext.d.ts +18 -0
  219. package/dist/contexts/BlockRegistryContext.js +8 -0
  220. package/dist/contexts/ColumnRegistryContext.d.ts +8 -0
  221. package/dist/contexts/ColumnRegistryContext.js +30 -0
  222. package/dist/contexts/FieldRegistryContext.d.ts +13 -0
  223. package/dist/contexts/FieldRegistryContext.js +46 -0
  224. package/dist/contexts/PanelMetadataContext.d.ts +26 -0
  225. package/dist/contexts/PanelMetadataContext.js +26 -0
  226. package/dist/contexts/PanelProviders.d.ts +27 -0
  227. package/dist/contexts/PanelProviders.js +24 -0
  228. package/dist/contexts/ResourceModalContext.d.ts +26 -0
  229. package/dist/contexts/ResourceModalContext.js +76 -0
  230. package/dist/contexts/SlotRegistryContext.d.ts +19 -0
  231. package/dist/contexts/SlotRegistryContext.js +24 -0
  232. package/dist/contexts/TableRefreshContext.d.ts +10 -0
  233. package/dist/contexts/TableRefreshContext.js +30 -0
  234. package/dist/contexts/WidgetRegistryContext.d.ts +17 -0
  235. package/dist/contexts/WidgetRegistryContext.js +14 -0
  236. package/dist/contexts/createRegistryContext.d.ts +19 -0
  237. package/dist/contexts/createRegistryContext.js +20 -0
  238. package/dist/hooks/useAfterStateUpdated.d.ts +6 -0
  239. package/dist/hooks/useAfterStateUpdated.js +62 -0
  240. package/dist/hooks/useValidation.d.ts +26 -0
  241. package/dist/hooks/useValidation.js +76 -0
  242. package/dist/i18n/I18nProvider.d.ts +27 -0
  243. package/dist/i18n/I18nProvider.js +101 -0
  244. package/dist/i18n/LocaleSwitcher.d.ts +10 -0
  245. package/dist/i18n/LocaleSwitcher.js +30 -0
  246. package/dist/i18n/activeLocale.d.ts +11 -0
  247. package/dist/i18n/activeLocale.js +34 -0
  248. package/dist/i18n/buildClientI18n.d.ts +28 -0
  249. package/dist/i18n/buildClientI18n.js +67 -0
  250. package/dist/i18n/index.d.ts +11 -0
  251. package/dist/i18n/index.js +9 -0
  252. package/dist/i18n/locales/core/en.d.ts +225 -0
  253. package/dist/i18n/locales/core/en.js +252 -0
  254. package/dist/i18n/locales/core/index.d.ts +2 -0
  255. package/dist/i18n/locales/core/index.js +4 -0
  256. package/dist/i18n/locales/core/sq.d.ts +253 -0
  257. package/dist/i18n/locales/core/sq.js +255 -0
  258. package/dist/i18n/useFormatter.d.ts +18 -0
  259. package/dist/i18n/useFormatter.js +37 -0
  260. package/dist/i18n/useLocale.d.ts +11 -0
  261. package/dist/i18n/useLocale.js +11 -0
  262. package/dist/i18n/useTranslation.d.ts +12 -0
  263. package/dist/i18n/useTranslation.js +12 -0
  264. package/dist/index.d.ts +106 -0
  265. package/dist/index.js +101 -0
  266. package/dist/pages/ResourceListPage.d.ts +8 -0
  267. package/dist/pages/ResourceListPage.js +139 -0
  268. package/dist/plugin.d.ts +79 -0
  269. package/dist/plugin.js +34 -0
  270. package/dist/runtime/conditions.d.ts +35 -0
  271. package/dist/runtime/conditions.js +97 -0
  272. package/dist/runtime/formTraversal.d.ts +25 -0
  273. package/dist/runtime/formTraversal.js +37 -0
  274. package/dist/runtime/serializedFunctions.d.ts +41 -0
  275. package/dist/runtime/serializedFunctions.js +264 -0
  276. package/dist/slots/Slot.d.ts +24 -0
  277. package/dist/slots/Slot.js +29 -0
  278. package/dist/slots/SlotCluster.d.ts +22 -0
  279. package/dist/slots/SlotCluster.js +49 -0
  280. package/dist/slots/index.d.ts +7 -0
  281. package/dist/slots/index.js +4 -0
  282. package/dist/slots/mergeSlots.d.ts +18 -0
  283. package/dist/slots/mergeSlots.js +35 -0
  284. package/dist/slots/types.d.ts +87 -0
  285. package/dist/slots/types.js +30 -0
  286. package/dist/styles.css +1 -0
  287. package/dist/table/TableContext.d.ts +36 -0
  288. package/dist/table/TableContext.js +13 -0
  289. package/dist/table/TableRenderer.d.ts +29 -0
  290. package/dist/table/TableRenderer.js +159 -0
  291. package/dist/table/components/FiltersPanel.d.ts +11 -0
  292. package/dist/table/components/FiltersPanel.js +52 -0
  293. package/dist/table/components/TableToolbar.d.ts +28 -0
  294. package/dist/table/components/TableToolbar.js +27 -0
  295. package/dist/table/components/TableToolbarButton.d.ts +6 -0
  296. package/dist/table/components/TableToolbarButton.js +9 -0
  297. package/dist/table/components/TableView.d.ts +12 -0
  298. package/dist/table/components/TableView.js +21 -0
  299. package/dist/table/defaultRowActions.d.ts +21 -0
  300. package/dist/table/defaultRowActions.js +37 -0
  301. package/dist/table/hooks/useColumnVisibility.d.ts +13 -0
  302. package/dist/table/hooks/useColumnVisibility.js +59 -0
  303. package/dist/table/hooks/useEditableRows.d.ts +22 -0
  304. package/dist/table/hooks/useEditableRows.js +63 -0
  305. package/dist/table/hooks/useTableActions.d.ts +54 -0
  306. package/dist/table/hooks/useTableActions.js +313 -0
  307. package/dist/table/hooks/useTableData.d.ts +28 -0
  308. package/dist/table/hooks/useTableData.js +63 -0
  309. package/dist/table/hooks/useTableLayout.d.ts +12 -0
  310. package/dist/table/hooks/useTableLayout.js +31 -0
  311. package/dist/table/hooks/useTableQuery.d.ts +29 -0
  312. package/dist/table/hooks/useTableQuery.js +135 -0
  313. package/dist/types/index.d.ts +224 -0
  314. package/dist/types/index.js +6 -0
  315. package/dist/utils/classNames.d.ts +7 -0
  316. package/dist/utils/classNames.js +9 -0
  317. package/dist/utils/columnMediaDimensions.d.ts +13 -0
  318. package/dist/utils/columnMediaDimensions.js +29 -0
  319. package/dist/utils/columnVisibilityStorage.d.ts +22 -0
  320. package/dist/utils/columnVisibilityStorage.js +56 -0
  321. package/dist/utils/fieldErrors.d.ts +13 -0
  322. package/dist/utils/fieldErrors.js +25 -0
  323. package/dist/utils/formatValue.d.ts +28 -0
  324. package/dist/utils/formatValue.js +109 -0
  325. package/dist/utils/layoutStorage.d.ts +23 -0
  326. package/dist/utils/layoutStorage.js +53 -0
  327. package/dist/utils/redirectHandler.d.ts +7 -0
  328. package/dist/utils/redirectHandler.js +25 -0
  329. package/dist/utils/tableFormatters.d.ts +14 -0
  330. package/dist/utils/tableFormatters.js +93 -0
  331. package/dist/utils/widgetVisibilityStorage.d.ts +11 -0
  332. package/dist/utils/widgetVisibilityStorage.js +39 -0
  333. package/package.json +101 -0
  334. package/src/FieldRenderer.test.tsx +44 -0
  335. package/src/FieldRenderer.tsx +104 -0
  336. package/src/FormRenderer.containers.test.tsx +121 -0
  337. package/src/FormRenderer.test.tsx +174 -0
  338. package/src/FormRenderer.tsx +140 -0
  339. package/src/TableRenderer.tsx +2 -0
  340. package/src/api/actionsApi.ts +76 -0
  341. package/src/api/authenticatedFetch.ts +40 -0
  342. package/src/api/exportApi.ts +66 -0
  343. package/src/api/http.test.ts +58 -0
  344. package/src/api/http.ts +68 -0
  345. package/src/api/resourceApi.ts +88 -0
  346. package/src/api/tableApi.test.ts +108 -0
  347. package/src/api/tableApi.ts +107 -0
  348. package/src/api/urls.ts +50 -0
  349. package/src/app.test.tsx +67 -0
  350. package/src/app.tsx +181 -0
  351. package/src/auth/AuthContext.tsx +188 -0
  352. package/src/auth/LoginPage.tsx +380 -0
  353. package/src/auth/ProtectedRoute.tsx +39 -0
  354. package/src/auth/authApiClient.ts +109 -0
  355. package/src/auth/authFlow.test.tsx +168 -0
  356. package/src/auth/types.ts +104 -0
  357. package/src/components/ActionFormModal.tsx +45 -0
  358. package/src/components/AdminPanel.tsx +368 -0
  359. package/src/components/Checkbox.tsx +59 -0
  360. package/src/components/CheckboxField.tsx +88 -0
  361. package/src/components/ColorPickerField.tsx +93 -0
  362. package/src/components/DateTimePickerField.tsx +112 -0
  363. package/src/components/FileUploadField.tsx +841 -0
  364. package/src/components/GlobalSearch.tsx +436 -0
  365. package/src/components/GroupField.tsx +85 -0
  366. package/src/components/HiddenField.tsx +14 -0
  367. package/src/components/ModalBreadcrumb.tsx +74 -0
  368. package/src/components/ModalDrawer.tsx +137 -0
  369. package/src/components/RadioField.tsx +80 -0
  370. package/src/components/RepeaterField.tsx +546 -0
  371. package/src/components/ResourceModalRenderer.tsx +144 -0
  372. package/src/components/RichEditorField.tsx +942 -0
  373. package/src/components/SectionField.tsx +242 -0
  374. package/src/components/SelectField.tsx +843 -0
  375. package/src/components/TabsField.test.tsx +151 -0
  376. package/src/components/TabsField.tsx +386 -0
  377. package/src/components/TagsInputField.tsx +411 -0
  378. package/src/components/TextInputField.tsx +91 -0
  379. package/src/components/TextareaField.tsx +110 -0
  380. package/src/components/ToggleField.tsx +126 -0
  381. package/src/components/ViewModal.tsx +353 -0
  382. package/src/components/blocks/BlockRenderer.tsx +56 -0
  383. package/src/components/blocks/FormBlockRenderer.tsx +160 -0
  384. package/src/components/blocks/TableBlockRenderer.tsx +33 -0
  385. package/src/components/blocks/TabsBlockRenderer.tsx +49 -0
  386. package/src/components/blocks/WidgetBlockRenderer.tsx +19 -0
  387. package/src/components/columns/CheckboxColumnComponent.tsx +38 -0
  388. package/src/components/columns/ColorColumnComponent.tsx +23 -0
  389. package/src/components/columns/CustomColumn.test.tsx +55 -0
  390. package/src/components/columns/DeeplinkWrapper.tsx +103 -0
  391. package/src/components/columns/IconColumnComponent.tsx +55 -0
  392. package/src/components/columns/ImageColumnComponent.tsx +220 -0
  393. package/src/components/columns/MediaColumnComponent.tsx +294 -0
  394. package/src/components/columns/SelectColumnComponent.tsx +49 -0
  395. package/src/components/columns/TagsColumnComponent.tsx +46 -0
  396. package/src/components/columns/TextColumnComponent.tsx +191 -0
  397. package/src/components/columns/TextInputColumnComponent.tsx +35 -0
  398. package/src/components/columns/ToggleColumnComponent.tsx +56 -0
  399. package/src/components/columns/VideoColumnComponent.tsx +236 -0
  400. package/src/components/columns/ViewColumnComponent.tsx +9 -0
  401. package/src/components/errors/ErrorBoundary.tsx +58 -0
  402. package/src/components/filters/CustomFilterComponent.tsx +130 -0
  403. package/src/components/filters/DateFilterComponent.tsx +272 -0
  404. package/src/components/filters/QueryBuilderFilterComponent.tsx +502 -0
  405. package/src/components/layout/Header.tsx +212 -0
  406. package/src/components/layout/PanelBrandMark.tsx +61 -0
  407. package/src/components/layout/Sidebar.tsx +283 -0
  408. package/src/components/modals/RelationCreateModal.tsx +107 -0
  409. package/src/components/modals/ResourceFormModal.test.tsx +119 -0
  410. package/src/components/modals/ResourceFormModal.tsx +128 -0
  411. package/src/components/modals/useResourceForm.ts +207 -0
  412. package/src/components/modals/view/RecordActions.tsx +69 -0
  413. package/src/components/modals/view/RecordDetails.tsx +60 -0
  414. package/src/components/modals/view/RelationPanel.tsx +76 -0
  415. package/src/components/modals/view/RelationTabs.tsx +145 -0
  416. package/src/components/modals/view/useRecordView.ts +134 -0
  417. package/src/components/pages/PageRenderer.tsx +173 -0
  418. package/src/components/table/ColumnTogglePopup.tsx +85 -0
  419. package/src/components/table/GridCard.tsx +155 -0
  420. package/src/components/table/GridView.tsx +138 -0
  421. package/src/components/table/LayoutToggle.tsx +24 -0
  422. package/src/components/table/TableActionsDropdown.tsx +114 -0
  423. package/src/components/table/TableBulkActions.tsx +65 -0
  424. package/src/components/table/TableHeader.tsx +96 -0
  425. package/src/components/table/TablePagination.tsx +169 -0
  426. package/src/components/table/TableRow.tsx +155 -0
  427. package/src/components/table/TableSearchBar.tsx +66 -0
  428. package/src/components/table/TableTabs.tsx +49 -0
  429. package/src/components/ui/Badge.tsx +30 -0
  430. package/src/components/ui/Button.test.tsx +78 -0
  431. package/src/components/ui/Button.tsx +102 -0
  432. package/src/components/ui/Card.tsx +23 -0
  433. package/src/components/ui/ConfirmDialog.tsx +112 -0
  434. package/src/components/ui/EmptyState.tsx +24 -0
  435. package/src/components/ui/ErrorAlert.tsx +37 -0
  436. package/src/components/ui/Input.tsx +48 -0
  437. package/src/components/ui/Label.tsx +15 -0
  438. package/src/components/ui/PillButton.tsx +72 -0
  439. package/src/components/ui/Select.tsx +33 -0
  440. package/src/components/ui/Spinner.tsx +39 -0
  441. package/src/components/ui/Toast.tsx +105 -0
  442. package/src/components/ui/index.ts +24 -0
  443. package/src/components/utils/HintDisplay.tsx +26 -0
  444. package/src/components/utils/Icon.tsx +36 -0
  445. package/src/components/utils/MediaPreviewModal.tsx +114 -0
  446. package/src/components/utils/ViewFieldWrapper.tsx +23 -0
  447. package/src/components/utils/layoutHelpers.ts +267 -0
  448. package/src/components/widgets/ChartWidget.tsx +247 -0
  449. package/src/components/widgets/StatsWidget.tsx +72 -0
  450. package/src/components/widgets/WidgetRenderer.tsx +108 -0
  451. package/src/components/widgets/WidgetShell.tsx +37 -0
  452. package/src/contexts/AuthChallengeRegistryContext.tsx +29 -0
  453. package/src/contexts/BlockRegistryContext.tsx +28 -0
  454. package/src/contexts/ColumnRegistryContext.tsx +38 -0
  455. package/src/contexts/FieldRegistryContext.tsx +56 -0
  456. package/src/contexts/PanelMetadataContext.tsx +60 -0
  457. package/src/contexts/PanelProviders.tsx +85 -0
  458. package/src/contexts/ResourceModalContext.tsx +137 -0
  459. package/src/contexts/SlotRegistryContext.tsx +35 -0
  460. package/src/contexts/TableRefreshContext.tsx +44 -0
  461. package/src/contexts/WidgetRegistryContext.tsx +34 -0
  462. package/src/contexts/createRegistryContext.tsx +29 -0
  463. package/src/hooks/useAfterStateUpdated.ts +70 -0
  464. package/src/hooks/useValidation.test.ts +59 -0
  465. package/src/hooks/useValidation.ts +95 -0
  466. package/src/i18n/I18nProvider.tsx +128 -0
  467. package/src/i18n/LocaleSwitcher.tsx +50 -0
  468. package/src/i18n/activeLocale.ts +39 -0
  469. package/src/i18n/buildClientI18n.ts +101 -0
  470. package/src/i18n/i18n.test.tsx +140 -0
  471. package/src/i18n/index.ts +12 -0
  472. package/src/i18n/locales/core/en.ts +274 -0
  473. package/src/i18n/locales/core/index.ts +5 -0
  474. package/src/i18n/locales/core/sq.ts +275 -0
  475. package/src/i18n/useFormatter.ts +42 -0
  476. package/src/i18n/useLocale.ts +16 -0
  477. package/src/i18n/useTranslation.ts +17 -0
  478. package/src/index.ts +244 -0
  479. package/src/pages/ResourceListPage.tsx +205 -0
  480. package/src/plugin.ts +110 -0
  481. package/src/runtime/conditions.test.ts +99 -0
  482. package/src/runtime/conditions.ts +148 -0
  483. package/src/runtime/formTraversal.ts +41 -0
  484. package/src/runtime/serializedFunctions.test.ts +59 -0
  485. package/src/runtime/serializedFunctions.ts +284 -0
  486. package/src/slots/Slot.test.tsx +89 -0
  487. package/src/slots/Slot.tsx +47 -0
  488. package/src/slots/SlotCluster.test.tsx +95 -0
  489. package/src/slots/SlotCluster.tsx +107 -0
  490. package/src/slots/index.ts +15 -0
  491. package/src/slots/mergeSlots.test.ts +71 -0
  492. package/src/slots/mergeSlots.ts +40 -0
  493. package/src/slots/slotNames.test.ts +21 -0
  494. package/src/slots/types.ts +119 -0
  495. package/src/styles.css +437 -0
  496. package/src/table/TableContext.tsx +41 -0
  497. package/src/table/TableRenderer.test.tsx +197 -0
  498. package/src/table/TableRenderer.tsx +390 -0
  499. package/src/table/components/FiltersPanel.tsx +193 -0
  500. package/src/table/components/TableToolbar.tsx +153 -0
  501. package/src/table/components/TableToolbarButton.tsx +14 -0
  502. package/src/table/components/TableView.tsx +106 -0
  503. package/src/table/defaultRowActions.ts +43 -0
  504. package/src/table/hooks/useColumnVisibility.test.ts +51 -0
  505. package/src/table/hooks/useColumnVisibility.ts +71 -0
  506. package/src/table/hooks/useEditableRows.test.ts +69 -0
  507. package/src/table/hooks/useEditableRows.ts +89 -0
  508. package/src/table/hooks/useTableActions.ts +393 -0
  509. package/src/table/hooks/useTableData.ts +89 -0
  510. package/src/table/hooks/useTableLayout.ts +45 -0
  511. package/src/table/hooks/useTableQuery.test.ts +116 -0
  512. package/src/table/hooks/useTableQuery.ts +172 -0
  513. package/src/test/mockFetch.ts +67 -0
  514. package/src/test/setup.ts +25 -0
  515. package/src/types/index.ts +228 -0
  516. package/src/utils/classNames.ts +10 -0
  517. package/src/utils/columnMediaDimensions.ts +45 -0
  518. package/src/utils/columnVisibilityStorage.ts +55 -0
  519. package/src/utils/fieldErrors.test.ts +35 -0
  520. package/src/utils/fieldErrors.ts +27 -0
  521. package/src/utils/formatValue.test.tsx +65 -0
  522. package/src/utils/formatValue.tsx +117 -0
  523. package/src/utils/layoutStorage.ts +52 -0
  524. package/src/utils/redirectHandler.ts +29 -0
  525. package/src/utils/tableFormatters.test.ts +54 -0
  526. package/src/utils/tableFormatters.ts +104 -0
  527. package/src/utils/widgetVisibilityStorage.ts +38 -0
  528. package/tailwind.config.js +9 -0
  529. package/vite.config.ts +17 -0
@@ -0,0 +1,159 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { ModalDrawer } from './ModalDrawer';
5
+ import { ActionFormModal } from './ActionFormModal';
6
+ import { RelationCreateModal } from './modals/RelationCreateModal';
7
+ import { useRecordView } from './modals/view/useRecordView';
8
+ import { RecordDetails } from './modals/view/RecordDetails';
9
+ import { RecordActions } from './modals/view/RecordActions';
10
+ import { Slot } from '../slots/Slot';
11
+ import { RelationPanel } from './modals/view/RelationPanel';
12
+ import { RelationTabs, GroupInnerTabs, groupRelations } from './modals/view/RelationTabs';
13
+ import { Spinner } from './ui/Spinner';
14
+ import { ErrorAlert } from './ui/ErrorAlert';
15
+ import { useConfirm } from './ui/ConfirmDialog';
16
+ import { useToast } from './ui/Toast';
17
+ import { bulkDelete } from '../api/resourceApi';
18
+ import { executeAction } from '../api/actionsApi';
19
+ import { handleRedirect } from '../utils/redirectHandler';
20
+ import { usePanelMetadata } from '../contexts/PanelMetadataContext';
21
+ import { useResourceModal } from '../contexts/ResourceModalContext';
22
+ import { translate } from '../i18n/activeLocale';
23
+ export function ViewModal({ isOpen, onClose, resourceSlug, resourceName, recordId, apiBaseUrl, formSchema, depth = 0, onCloseAll, }) {
24
+ const navigate = useNavigate();
25
+ const confirm = useConfirm();
26
+ const toast = useToast();
27
+ const { getResourceLabel } = usePanelMetadata();
28
+ const { setModalTitle, removeModalTitle, openModal, closeModal } = useResourceModal();
29
+ // Capabilities come from the form schema
30
+ const canEdit = formSchema.canEdit !== false;
31
+ const canDelete = formSchema.canDelete !== false;
32
+ const view = useRecordView(isOpen, apiBaseUrl, resourceSlug, recordId);
33
+ // Top-level tab: 'details', a group key, or an ungrouped relation name
34
+ const [activeTopTab, setActiveTopTab] = useState('details');
35
+ // Inner tab per group: groupKey -> relation.name
36
+ const [activeGroupRelation, setActiveGroupRelation] = useState({});
37
+ const [relationRefreshKeys, setRelationRefreshKeys] = useState({});
38
+ const [createRelation, setCreateRelation] = useState(null);
39
+ const [urlCopied, setUrlCopied] = useState(false);
40
+ const [actionFormModal, setActionFormModal] = useState(null);
41
+ // Modal title (breadcrumb)
42
+ const label = getResourceLabel(resourceSlug) || resourceName;
43
+ const modalKey = `${resourceSlug}-view-${recordId}`;
44
+ const modalTitle = view.recordTitle
45
+ ? translate('core:modal.view_record', { title: view.recordTitle })
46
+ : translate('core:modal.view_title', { label });
47
+ useEffect(() => {
48
+ setModalTitle(modalKey, modalTitle);
49
+ }, [modalKey, modalTitle, setModalTitle]);
50
+ useEffect(() => {
51
+ return () => {
52
+ removeModalTitle(modalKey);
53
+ };
54
+ }, [modalKey, removeModalTitle]);
55
+ // Reset tab state when closed
56
+ useEffect(() => {
57
+ if (!isOpen) {
58
+ setActiveTopTab('details');
59
+ setActiveGroupRelation({});
60
+ }
61
+ }, [isOpen]);
62
+ if (!isOpen)
63
+ return null;
64
+ const handleCopyUrl = () => {
65
+ navigator.clipboard.writeText(`${window.location.origin}/${resourceSlug}/${recordId}`).then(() => {
66
+ setUrlCopied(true);
67
+ setTimeout(() => setUrlCopied(false), 2000);
68
+ });
69
+ };
70
+ const handleDelete = async () => {
71
+ const confirmed = await confirm({
72
+ title: translate('core:confirm.delete_item_title'),
73
+ message: translate('core:confirm.delete_item_message'),
74
+ confirmLabel: translate('core:common.delete'),
75
+ danger: true,
76
+ });
77
+ if (!confirmed)
78
+ return;
79
+ try {
80
+ await bulkDelete(apiBaseUrl, resourceSlug, [recordId]);
81
+ toast.success(translate('core:toast.deleted'));
82
+ onClose();
83
+ }
84
+ catch (error) {
85
+ toast.error(error.message || translate('core:toast.delete_failed'));
86
+ }
87
+ };
88
+ const handleActionClick = async (action) => {
89
+ // Actions with a form open the action form modal
90
+ if (action.form && action.form.components) {
91
+ setActionFormModal({
92
+ actionName: action.name,
93
+ actionLabel: action.label,
94
+ formSchema: action.form,
95
+ requiresConfirmation: action.requiresConfirmation || false,
96
+ modalDescription: action.modalDescription,
97
+ });
98
+ openModal(resourceSlug, 'action', recordId, action.name, action.label);
99
+ return;
100
+ }
101
+ if (action.requiresConfirmation) {
102
+ const confirmed = await confirm({
103
+ title: action.label,
104
+ message: action.modalDescription ||
105
+ translate('core:confirm.action_generic', { action: action.label.toLowerCase() }),
106
+ });
107
+ if (!confirmed)
108
+ return;
109
+ }
110
+ try {
111
+ const result = await executeAction(`${apiBaseUrl}/${resourceSlug}`, action.name, recordId, {});
112
+ if (handleRedirect(result, navigate) || (result.data && handleRedirect(result.data, navigate))) {
113
+ // closeModal() pops from the stack without triggering the parent's navigation
114
+ closeModal();
115
+ return;
116
+ }
117
+ if (result.success) {
118
+ if (result.message) {
119
+ toast.success(result.message);
120
+ }
121
+ view.refreshRecord();
122
+ }
123
+ else {
124
+ toast.error(result.message || translate('core:form.action_failed'));
125
+ }
126
+ }
127
+ catch (error) {
128
+ toast.error(error.message || translate('core:error.action_failed'));
129
+ }
130
+ };
131
+ // Only actions with a backend handler (and not bulk-only) are shown
132
+ const filteredActions = (formSchema.actions?.filter((action) => !action.bulk && action.hasHandler) ||
133
+ []);
134
+ const hasActionBar = canEdit || canDelete || filteredActions.length > 0;
135
+ const grouped = groupRelations(view.relations);
136
+ const renderRelation = (relation) => (_jsx(RelationPanel, { relation: relation, schema: view.relationSchemas[relation.name], apiBaseUrl: apiBaseUrl, parentResourceSlug: resourceSlug, parentRecordId: recordId, refreshKey: relationRefreshKeys[relation.name] || 0, depth: depth, onCloseAll: onCloseAll, onAddRelation: setCreateRelation }));
137
+ return (_jsxs(_Fragment, { children: [_jsx(ModalDrawer, { isOpen: isOpen, onClose: onClose, title: modalTitle, width: "max-w-4xl", depth: depth, onCloseAll: onCloseAll, onCopyUrl: handleCopyUrl, urlCopied: urlCopied, children: _jsxs("div", { className: "-mx-4 -mt-4 flex h-full flex-col sm:-mx-6 sm:-mt-6", children: [view.loading && (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Spinner, { size: "lg", label: translate('core:common.loading_ellipsis') }) })), view.error && (_jsx("div", { className: "p-6", children: _jsx(ErrorAlert, { message: view.error }) })), !view.loading && !view.error && view.recordData && (_jsxs(_Fragment, { children: [_jsx(RecordActions, { actions: filteredActions, canEdit: canEdit, canDelete: canDelete, onAction: handleActionClick, onEdit: () => openModal(resourceSlug, 'edit', recordId), onDelete: handleDelete, resourceSlug: resourceSlug, record: view.recordData }), view.relations.length > 0 && (_jsx(RelationTabs, { grouped: grouped, activeTopTab: activeTopTab, onTopTabChange: setActiveTopTab, hasActionBar: hasActionBar })), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [activeTopTab === 'details' && (_jsxs(_Fragment, { children: [_jsx(RecordDetails, { formSchema: formSchema, recordData: view.recordData, apiBaseUrl: apiBaseUrl, resourceSlug: resourceSlug }), _jsx(Slot, { name: "detail.afterDetails", context: { resourceSlug, record: view.recordData }, as: "div", className: "px-6 pb-6 empty:hidden" })] })), grouped.ungrouped.map(relation => activeTopTab === relation.name && (_jsx("div", { className: "p-6", children: renderRelation(relation) }, relation.name))), grouped.groups.map(group => {
138
+ if (activeTopTab !== group.key)
139
+ return null;
140
+ const currentInner = activeGroupRelation[group.key] || group.relations[0]?.name;
141
+ const activeRelation = group.relations.find(r => r.name === currentInner) || group.relations[0];
142
+ if (!activeRelation)
143
+ return null;
144
+ return (_jsxs("div", { className: "p-6", children: [_jsx(GroupInnerTabs, { group: group, current: currentInner, onChange: name => setActiveGroupRelation(prev => ({ ...prev, [group.key]: name })) }), renderRelation(activeRelation)] }, group.key));
145
+ })] })] }))] }) }), createRelation && (_jsx(RelationCreateModal, { isOpen: !!createRelation, onClose: () => setCreateRelation(null), relation: createRelation, parentId: recordId, parentResourceSlug: resourceSlug, apiBaseUrl: apiBaseUrl, onSuccess: () => {
146
+ setRelationRefreshKeys(prev => ({
147
+ ...prev,
148
+ [createRelation.name]: (prev[createRelation.name] || 0) + 1,
149
+ }));
150
+ setCreateRelation(null);
151
+ }, depth: depth + 1, onCloseAll: onCloseAll })), actionFormModal && (_jsx(ActionFormModal, { isOpen: !!actionFormModal, onClose: () => {
152
+ setActionFormModal(null);
153
+ closeModal();
154
+ }, actionName: actionFormModal.actionName, actionLabel: actionFormModal.actionLabel, formSchema: actionFormModal.formSchema, recordIds: [recordId], isBulk: false, requiresConfirmation: actionFormModal.requiresConfirmation, modalDescription: actionFormModal.modalDescription, apiBaseUrl: apiBaseUrl || '', resourceSlug: resourceSlug, onSuccess: () => {
155
+ view.refreshRecord();
156
+ setActionFormModal(null);
157
+ closeModal();
158
+ }, depth: depth + 1, onCloseAll: onCloseAll }))] }));
159
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface BlockRendererProps {
3
+ block: any;
4
+ blockData?: Record<string, any>;
5
+ apiBaseUrl?: string;
6
+ }
7
+ export declare function BlockRenderer({ block, blockData, apiBaseUrl }: BlockRendererProps): React.JSX.Element;
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useBlockRegistry } from '../../contexts/BlockRegistryContext';
3
+ import { WidgetBlockRenderer } from './WidgetBlockRenderer';
4
+ import { FormBlockRenderer } from './FormBlockRenderer';
5
+ import { TableBlockRenderer } from './TableBlockRenderer';
6
+ import { TabsBlockRenderer } from './TabsBlockRenderer';
7
+ export function BlockRenderer({ block, blockData, apiBaseUrl }) {
8
+ const blocks = useBlockRegistry();
9
+ let content;
10
+ switch (block.type) {
11
+ case 'widget':
12
+ content = _jsx(WidgetBlockRenderer, { block: block, data: blockData?.[block.widget.name] });
13
+ break;
14
+ case 'form':
15
+ content = _jsx(FormBlockRenderer, { block: block, apiBaseUrl: apiBaseUrl });
16
+ break;
17
+ case 'table':
18
+ content = _jsx(TableBlockRenderer, { block: block, apiBaseUrl: apiBaseUrl });
19
+ break;
20
+ case 'tabs':
21
+ content = _jsx(TabsBlockRenderer, { block: block, blockData: blockData, apiBaseUrl: apiBaseUrl });
22
+ break;
23
+ default: {
24
+ const CustomBlockComponent = blocks[block.type];
25
+ if (CustomBlockComponent) {
26
+ content = _jsx(CustomBlockComponent, { block: block, blockData: blockData, apiBaseUrl: apiBaseUrl });
27
+ }
28
+ else {
29
+ console.warn(`Unknown block type: ${block.type}`);
30
+ return null;
31
+ }
32
+ break;
33
+ }
34
+ }
35
+ return (_jsxs("div", { className: "mb-6", children: [(block.title || block.subtitle) && (_jsxs("div", { className: "mb-1", children: [block.title && (_jsx("h2", { className: "text-xl text-gray-900 dark:text-gray-100 font-semibold mb-1", children: block.title })), block.subtitle && _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: block.subtitle })] })), content] }));
36
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface FormBlockRendererProps {
3
+ block: any;
4
+ apiBaseUrl?: string;
5
+ }
6
+ export declare function FormBlockRenderer({ block, apiBaseUrl }: FormBlockRendererProps): React.JSX.Element;
@@ -0,0 +1,110 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { FormRenderer } from '../../FormRenderer';
5
+ import { authenticatedFetch } from '../../api/authenticatedFetch';
6
+ import { handleRedirect } from '../../utils/redirectHandler';
7
+ import { translate } from '../../i18n/activeLocale';
8
+ export function FormBlockRenderer({ block, apiBaseUrl }) {
9
+ const navigate = useNavigate();
10
+ const [error, setError] = useState(null);
11
+ const [successMessage, setSuccessMessage] = useState(null);
12
+ const [initialData, setInitialData] = useState(block.initialData || {});
13
+ const [loading, setLoading] = useState(!!block.dataUrl);
14
+ // Fetch initial data from dataUrl if provided
15
+ useEffect(() => {
16
+ const fetchInitialData = async () => {
17
+ // If no dataUrl, use initialData directly (no fetch needed)
18
+ if (!block.dataUrl) {
19
+ setLoading(false);
20
+ return;
21
+ }
22
+ setLoading(true);
23
+ setError(null);
24
+ try {
25
+ if (!apiBaseUrl) {
26
+ throw new Error('API base URL is required');
27
+ }
28
+ const dataUrl = `${apiBaseUrl}/${block.dataUrl}`;
29
+ const response = await authenticatedFetch(dataUrl, {
30
+ method: 'GET',
31
+ headers: {
32
+ 'Content-Type': 'application/json',
33
+ },
34
+ }, apiBaseUrl);
35
+ if (!response.ok) {
36
+ if (response.status === 401) {
37
+ setError('Unauthorized - Please login again');
38
+ return;
39
+ }
40
+ const errorData = await response.json();
41
+ const errorMsg = errorData.error || errorData.message || translate('core:error.fetch_form_data');
42
+ setError(errorMsg);
43
+ return;
44
+ }
45
+ const responseData = await response.json();
46
+ // Use ONLY fetched data, don't merge with initialData
47
+ // This prevents metadata from being included in form state
48
+ setInitialData(responseData.data || responseData || {});
49
+ }
50
+ catch (err) {
51
+ setError(err.message || translate('core:error.fetch_form_data_generic'));
52
+ // On error, fall back to initialData if available
53
+ if (block.initialData) {
54
+ setInitialData(block.initialData);
55
+ }
56
+ }
57
+ finally {
58
+ setLoading(false);
59
+ }
60
+ };
61
+ fetchInitialData();
62
+ }, [block.dataUrl, block.initialData, apiBaseUrl]);
63
+ useEffect(() => {
64
+ // Reset success message after 3 seconds
65
+ if (successMessage) {
66
+ const timer = setTimeout(() => setSuccessMessage(null), 3000);
67
+ return () => clearTimeout(timer);
68
+ }
69
+ }, [successMessage]);
70
+ const handleSubmit = async (data) => {
71
+ setError(null);
72
+ setSuccessMessage(null);
73
+ try {
74
+ if (!apiBaseUrl) {
75
+ throw new Error('API base URL is required');
76
+ }
77
+ const submitUrl = block.submitUrl ? `${apiBaseUrl}/${block.submitUrl}` : `${apiBaseUrl}/submit`;
78
+ const response = await authenticatedFetch(submitUrl, {
79
+ method: 'POST',
80
+ headers: {
81
+ 'Content-Type': 'application/json',
82
+ },
83
+ body: JSON.stringify(data),
84
+ }, apiBaseUrl);
85
+ const responseData = await response.json();
86
+ if (!response.ok) {
87
+ if (response.status === 401) {
88
+ setError('Unauthorized - Please login again');
89
+ return;
90
+ }
91
+ // Extract error message from backend response
92
+ const errorMsg = responseData.error || responseData.message || translate('core:error.submit_form');
93
+ setError(errorMsg);
94
+ return;
95
+ }
96
+ // Check for redirect before showing success message
97
+ if (handleRedirect(responseData, navigate)) {
98
+ // Redirect was handled, exit early
99
+ return;
100
+ }
101
+ // Extract success message from backend response
102
+ const successMsg = responseData.message || translate('core:form.submitted');
103
+ setSuccessMessage(successMsg);
104
+ }
105
+ catch (err) {
106
+ setError(err.message || translate('core:error.generic'));
107
+ }
108
+ };
109
+ return (_jsxs(_Fragment, { children: [error && _jsx("div", { className: "mb-4 p-3 bg-red-50 border border-red-200 text-red-700 rounded", children: error }), successMessage && (_jsx("div", { className: "mb-4 p-3 bg-green-50 border border-green-200 text-green-700 rounded", children: successMessage })), loading && (_jsx("div", { className: "mb-4 p-3 bg-accent-soft border border-accent/30 text-accent rounded", children: "Loading form data..." })), !loading && (_jsx(FormRenderer, { schema: block.form, defaultValues: initialData, onSubmit: handleSubmit, apiBaseUrl: apiBaseUrl }))] }));
110
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface TableBlockRendererProps {
3
+ block: any;
4
+ apiBaseUrl?: string;
5
+ }
6
+ export declare function TableBlockRenderer({ block, apiBaseUrl }: TableBlockRendererProps): React.JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { TableRenderer } from '../../TableRenderer';
3
+ export function TableBlockRenderer({ block, apiBaseUrl }) {
4
+ const dataUrl = block.dataUrl
5
+ ? apiBaseUrl
6
+ ? `${apiBaseUrl}/${block.dataUrl}`
7
+ : block.dataUrl
8
+ : apiBaseUrl
9
+ ? `${apiBaseUrl}/custom/list`
10
+ : undefined;
11
+ return (_jsx(_Fragment, { children: dataUrl && (_jsx(TableRenderer, { isResource: false, schema: block.table, apiUrl: dataUrl, apiBaseUrl: apiBaseUrl, onCreateClick: undefined, canCreate: false })) }));
12
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export interface TabsBlockRendererProps {
3
+ block: any;
4
+ blockData?: Record<string, any>;
5
+ apiBaseUrl?: string;
6
+ }
7
+ export declare function TabsBlockRenderer({ block, blockData, apiBaseUrl }: TabsBlockRendererProps): React.JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { BlockRenderer } from './BlockRenderer';
4
+ import { Icon } from '../utils/Icon';
5
+ import { cn } from '../../utils/classNames';
6
+ export function TabsBlockRenderer({ block, blockData, apiBaseUrl }) {
7
+ const [activeTab, setActiveTab] = useState(block.defaultTab || 0);
8
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex border-b border-gray-200 dark:border-gray-700 mb-4", children: block.tabs.map((tab, index) => (_jsxs("button", { onClick: () => setActiveTab(index), className: cn('px-4 py-2 font-medium text-sm transition-colors', 'border-b-2 -mb-px', activeTab === index
9
+ ? 'border-accent text-accent'
10
+ : 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200'), children: [tab.icon && (_jsxs("span", { className: "inline-flex items-center gap-2", children: [_jsx(Icon, { name: tab.icon, className: "w-4 h-4" }), tab.label] })), !tab.icon && tab.label] }, index))) }), _jsx("div", { children: block.tabs[activeTab]?.blocks.map((nestedBlock, index) => (_jsx(BlockRenderer, { block: nestedBlock, blockData: blockData, apiBaseUrl: apiBaseUrl }, index))) })] }));
11
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export interface WidgetBlockRendererProps {
3
+ block: any;
4
+ data: any;
5
+ }
6
+ export declare function WidgetBlockRenderer({ block, data }: WidgetBlockRendererProps): React.JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useWidgetRegistry } from '../../contexts/WidgetRegistryContext';
3
+ export function WidgetBlockRenderer({ block, data }) {
4
+ const widgets = useWidgetRegistry();
5
+ const WidgetComponent = widgets[block.widget.type];
6
+ if (!WidgetComponent) {
7
+ console.warn(`Widget type "${block.widget.type}" not registered`);
8
+ return null;
9
+ }
10
+ return _jsx(WidgetComponent, { widget: block.widget, data: data });
11
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { ColumnProps } from './TextColumnComponent';
3
+ export interface EditableColumnProps extends ColumnProps {
4
+ onCellChange?: (value: any) => void;
5
+ }
6
+ export declare function CheckboxColumnComponent({ column, record, onCellChange }: EditableColumnProps): React.JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect } from 'react';
3
+ export function CheckboxColumnComponent({ column, record, onCellChange }) {
4
+ const [value, setValue] = useState(Boolean(record[column.name]));
5
+ const isDisabled = column.disabled;
6
+ // Update local value when record changes (e.g., after reset)
7
+ useEffect(() => {
8
+ setValue(Boolean(record[column.name]));
9
+ }, [record[column.name]]);
10
+ const handleChange = (e) => {
11
+ if (isDisabled)
12
+ return;
13
+ const newValue = e.target.checked;
14
+ setValue(newValue);
15
+ // Notify parent of change
16
+ if (onCellChange) {
17
+ onCellChange(newValue);
18
+ }
19
+ };
20
+ return (_jsx("input", { type: "checkbox", checked: value, onChange: handleChange, disabled: isDisabled, className: "w-4 h-4 text-accent bg-gray-100 border-gray-300 rounded focus:ring-ring dark:focus:ring-ring dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 disabled:opacity-50 disabled:cursor-not-allowed" }));
21
+ }
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ColumnProps } from './TextColumnComponent';
3
+ export declare function ColorColumnComponent({ column, record }: ColumnProps): React.JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { formatValue } from '../../utils/tableFormatters';
3
+ export function ColorColumnComponent({ column, record }) {
4
+ const rawValue = record[column.name];
5
+ // Apply formatter if present
6
+ const value = formatValue(rawValue, column, record);
7
+ if (!value) {
8
+ return _jsx("span", { className: "text-fg-secondary", children: "-" });
9
+ }
10
+ return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "w-6 h-6 rounded border border-gray-300 dark:border-gray-600", style: { backgroundColor: value } }), _jsx("span", { className: "text-sm text-fg-secondary font-mono", children: value })] }));
11
+ }
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { SerializedColumn } from '@maxal_studio/kratosjs';
3
+ interface DeeplinkWrapperProps {
4
+ column: SerializedColumn;
5
+ record: Record<string, any>;
6
+ value: any;
7
+ children: React.ReactNode;
8
+ className?: string;
9
+ }
10
+ /**
11
+ * Reusable component that wraps content with deeplink navigation functionality
12
+ * Uses an anchor tag for proper HTML content support and semantic correctness
13
+ */
14
+ export declare function DeeplinkWrapper({ column, record, value, children, className }: DeeplinkWrapperProps): React.JSX.Element;
15
+ export {};
@@ -0,0 +1,85 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useNavigate, useLocation } from 'react-router-dom';
3
+ import { executeSerializedFunction } from '../../runtime/serializedFunctions';
4
+ import { useResourceModal } from '../../contexts/ResourceModalContext';
5
+ /**
6
+ * Reusable component that wraps content with deeplink navigation functionality
7
+ * Uses an anchor tag for proper HTML content support and semantic correctness
8
+ */
9
+ export function DeeplinkWrapper({ column, record, value, children, className = '' }) {
10
+ const navigate = useNavigate();
11
+ const location = useLocation();
12
+ const { openModal } = useResourceModal();
13
+ // Determine current resource from URL
14
+ const getCurrentResource = () => {
15
+ const pathParts = location.pathname.split('/').filter(Boolean);
16
+ // First part after root is typically the resource slug
17
+ return pathParts[0] || null;
18
+ };
19
+ // Check if deeplink exists
20
+ if (!column.deeplink) {
21
+ return _jsx(_Fragment, { children: children });
22
+ }
23
+ const handleClick = (e) => {
24
+ e.preventDefault();
25
+ e.stopPropagation();
26
+ const deeplink = column.deeplink;
27
+ if (!deeplink)
28
+ return;
29
+ try {
30
+ // Get the record ID
31
+ let recordId;
32
+ if (deeplink.id) {
33
+ // Static ID string
34
+ recordId = deeplink.id;
35
+ }
36
+ else if (deeplink.idFn) {
37
+ // Execute the serialized function to get the ID
38
+ recordId = executeSerializedFunction(deeplink.idFn, value, record);
39
+ }
40
+ // Handle resource deeplinks
41
+ if (deeplink.resource) {
42
+ // Check if we're currently on the target resource page
43
+ const currentPath = location.pathname;
44
+ const isOnTargetResource = currentPath.startsWith(`/${deeplink.resource}`);
45
+ if (recordId) {
46
+ const mode = deeplink.edit ? 'edit' : 'view';
47
+ const currentResource = getCurrentResource();
48
+ const isSameResource = currentResource === deeplink.resource;
49
+ if (isSameResource) {
50
+ // Same resource: navigate to update URL (for bookmarking)
51
+ // The URL listener in ResourceListPage will open the modal via context
52
+ const path = deeplink.edit
53
+ ? `/${deeplink.resource}/${recordId}/edit`
54
+ : `/${deeplink.resource}/${recordId}`;
55
+ navigate(path);
56
+ }
57
+ else {
58
+ // Cross-resource: push the target URL into browser history so the
59
+ // address bar updates, but do NOT call navigate() — that would unmount
60
+ // the current page. Store the current URL as originUrl so AdminPanel
61
+ // can restore it with replaceState when the modal closes.
62
+ const originUrl = location.pathname + location.search;
63
+ const targetPath = deeplink.edit
64
+ ? `/${deeplink.resource}/${recordId}/edit`
65
+ : `/${deeplink.resource}/${recordId}`;
66
+ window.history.pushState(null, '', targetPath);
67
+ openModal(deeplink.resource, mode, recordId, undefined, undefined, originUrl);
68
+ }
69
+ }
70
+ else {
71
+ // No ID provided, navigate to resource list page
72
+ navigate(`/${deeplink.resource}`);
73
+ }
74
+ }
75
+ else if (deeplink.page) {
76
+ // Page navigation
77
+ navigate(`/page/${deeplink.page}`);
78
+ }
79
+ }
80
+ catch (error) {
81
+ console.error('Error handling deeplink:', error);
82
+ }
83
+ };
84
+ return (_jsx("a", { href: "#", onClick: handleClick, className: `cursor-pointer text-accent hover:underline ${className}`.trim(), children: children }));
85
+ }
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ColumnProps } from './TextColumnComponent';
3
+ export declare function IconColumnComponent({ column, record }: ColumnProps): React.JSX.Element;
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { formatValue } from '../../utils/tableFormatters';
3
+ import { cn } from '../../utils/classNames';
4
+ import { Icon } from '../utils/Icon';
5
+ import { executeSerializedFunction } from '../../runtime/serializedFunctions';
6
+ export function IconColumnComponent({ column, record }) {
7
+ const rawValue = record[column.name];
8
+ // Apply formatStateUsing if present
9
+ const value = formatValue(rawValue, column, record);
10
+ // Determine icon name
11
+ let iconName = null;
12
+ if (column.iconFn) {
13
+ // Execute serialized function
14
+ const result = executeSerializedFunction(column.iconFn, value, record);
15
+ iconName = result !== undefined ? result : null;
16
+ }
17
+ else if (column.icon) {
18
+ if (typeof column.icon === 'string') {
19
+ // Static icon
20
+ iconName = column.icon;
21
+ }
22
+ else if (typeof column.icon === 'object') {
23
+ // Object mapping
24
+ iconName = column.icon[value] || null;
25
+ }
26
+ }
27
+ // Determine color class
28
+ let colorClass = 'text-fg';
29
+ if (column.iconColorFn) {
30
+ // Execute serialized function
31
+ const result = executeSerializedFunction(column.iconColorFn, value, record);
32
+ colorClass = result !== undefined ? result : 'text-fg';
33
+ }
34
+ else if (column.iconColor) {
35
+ if (typeof column.iconColor === 'string') {
36
+ // Static color
37
+ colorClass = column.iconColor;
38
+ }
39
+ else if (typeof column.iconColor === 'object') {
40
+ // Object mapping
41
+ colorClass = column.iconColor[value] || 'text-fg';
42
+ }
43
+ }
44
+ // If no icon is determined, show placeholder
45
+ if (!iconName) {
46
+ return _jsx("span", { className: "text-fg-secondary", children: "-" });
47
+ }
48
+ // Get size from column (default to 20px)
49
+ const size = column.size || 20;
50
+ // Render Lucide icon
51
+ return _jsx(Icon, { name: iconName, size: size, className: cn(colorClass) });
52
+ }
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ColumnProps } from './TextColumnComponent';
3
+ export declare function ImageColumnComponent({ column, record }: ColumnProps): React.JSX.Element;