@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
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @maxal_studio/kratosjs-react
2
+
3
+ React components for KratosJs. Render dynamic forms and tables from JSON schemas with React Hook Form and Tailwind CSS.
4
+
5
+ ## Documentation
6
+
7
+ 📚 **[View Documentation](./docs/README.md)**
8
+
9
+ ### Key Topics
10
+
11
+ - [Getting Started](./docs/getting-started.md)
12
+
13
+ ### Related Documentation
14
+
15
+ - [Forms Documentation](../docs/forms/overview.md) - Form fields and components
16
+ - [Custom Fields](../docs/forms/custom-fields.md) - Creating custom form fields
17
+ - [Tables Documentation](../docs/tables/overview.md) - Table columns and features
18
+ - [Custom Columns](../docs/tables/custom-columns.md) - Creating custom table columns
19
+ - [Custom Widgets](../docs/resources/custom-widgets.md) - Creating custom widgets
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @maxal_studio/kratosjs-react react-hook-form
25
+ ```
26
+
27
+ **Peer Dependencies:**
28
+
29
+ - `react` ^18.0.0
30
+ - `react-dom` ^18.0.0
31
+ - `react-hook-form` ^7.0.0
32
+
33
+ **Styling:**
34
+
35
+ Import the pre-built styles in your app:
36
+
37
+ ```js
38
+ // In your main.tsx or App.tsx
39
+ import '@maxal_studio/kratosjs-react/styles.css';
40
+ ```
41
+
42
+ ## License
43
+
44
+ ISC
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { FieldRendererProps } from './types';
3
+ /**
4
+ * FieldRenderer component
5
+ * Dynamically renders the correct field component based on type
6
+ */
7
+ export declare function FieldRenderer({ field, apiBaseUrl, resource, operation, mode, value, }: FieldRendererProps & {
8
+ apiBaseUrl?: string;
9
+ resource?: string;
10
+ operation?: 'create' | 'edit' | 'view';
11
+ mode?: 'edit' | 'view';
12
+ value?: any;
13
+ }): React.JSX.Element;
@@ -0,0 +1,62 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useWatch, useFormContext } from 'react-hook-form';
3
+ import { useFieldRegistry } from './contexts/FieldRegistryContext';
4
+ import { evaluateCondition } from './runtime/conditions';
5
+ import { useAfterStateUpdated } from './hooks/useAfterStateUpdated';
6
+ import { getColumnClasses } from './components/utils/layoutHelpers';
7
+ import { translate } from './i18n/activeLocale';
8
+ /**
9
+ * FieldRenderer component
10
+ * Dynamically renders the correct field component based on type
11
+ */
12
+ export function FieldRenderer({ field, apiBaseUrl, resource, operation, mode = 'edit', value, }) {
13
+ const registry = useFieldRegistry();
14
+ const FieldComponent = registry[field.type];
15
+ // In view mode, we don't need form context
16
+ let formState = {};
17
+ if (mode === 'edit') {
18
+ const { control } = useFormContext();
19
+ // Watch form state for conditional visibility/disabled evaluation
20
+ formState = useWatch({ control }) || {};
21
+ // Execute afterStateUpdated callback when field value changes (if provided)
22
+ useAfterStateUpdated(field.name, field.afterStateUpdatedFn);
23
+ }
24
+ else {
25
+ // In view mode, create a simple form state from the value prop for conditional evaluation
26
+ // This allows conditional visibility to work based on field values
27
+ if (field.name && value !== undefined) {
28
+ formState = { [field.name]: value };
29
+ }
30
+ }
31
+ // Unknown field type
32
+ if (!FieldComponent) {
33
+ console.warn(`Unknown field type: ${field.type}`);
34
+ return (_jsx("div", { className: "mb-4 p-4 bg-yellow-50 border border-yellow-200 rounded-lg", children: _jsxs("p", { className: "text-sm text-yellow-800", children: [_jsxs("strong", { children: [translate('core:common.warning'), ":"] }), ' ', translate('core:state.unknown_field', { type: field.type, name: field.name })] }) }));
35
+ }
36
+ // Evaluate conditional hidden state — hiddenWhen is the structured-AST form
37
+ // (no code execution), hiddenFn the serialized-function form.
38
+ const isHidden = evaluateCondition(field.hiddenWhen ?? field.hiddenFn ?? field.hidden, formState, operation);
39
+ // Evaluate conditional disabled state
40
+ const isDisabled = evaluateCondition(field.disabledWhen ?? field.disabledFn ?? field.disabled, formState, operation);
41
+ // Hidden field
42
+ if (isHidden) {
43
+ return null;
44
+ }
45
+ // Update field props with evaluated disabled state, API base URL, resource, mode, operation, and value
46
+ const fieldWithEvaluatedProps = {
47
+ ...field,
48
+ disabled: isDisabled,
49
+ apiBaseUrl,
50
+ resource,
51
+ mode,
52
+ operation,
53
+ value: value !== undefined ? value : mode === 'view' ? undefined : undefined,
54
+ };
55
+ // Get column layout classes using shared helper
56
+ const columnClasses = getColumnClasses(fieldWithEvaluatedProps.columnSpan, fieldWithEvaluatedProps.columnStart);
57
+ // Render the field component
58
+ if (columnClasses) {
59
+ return (_jsx("div", { className: columnClasses, children: _jsx(FieldComponent, { ...fieldWithEvaluatedProps }) }));
60
+ }
61
+ return _jsx(FieldComponent, { ...fieldWithEvaluatedProps });
62
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { FormRendererProps } from './types';
3
+ /**
4
+ * FormRenderer component
5
+ * Main component that accepts JSON schema and renders the form
6
+ */
7
+ export declare function FormRenderer({ schema, onSubmit, defaultValues, className, apiBaseUrl, resource, operation, children, }: FormRendererProps): React.JSX.Element;
@@ -0,0 +1,78 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from 'react';
3
+ import { useForm, FormProvider } from 'react-hook-form';
4
+ import { FieldRenderer } from './FieldRenderer';
5
+ import { cn } from './utils/classNames';
6
+ import { getGridClasses } from './components/utils/layoutHelpers';
7
+ import { Button } from './components/ui/Button';
8
+ import { getChildComponents, isArrayScope, isLayout } from './runtime/formTraversal';
9
+ import { useTranslation } from './i18n/useTranslation';
10
+ import { Slot } from './slots/Slot';
11
+ /**
12
+ * Extract default values from a schema using the declarative children contract.
13
+ * Layout containers are transparent (recurse into children); array-scope
14
+ * containers (repeaters) seed their own array value from the item template; leaf
15
+ * fields contribute their `default`.
16
+ */
17
+ function extractDefaultValues(components) {
18
+ const defaults = {};
19
+ components.forEach(component => {
20
+ // Array-scope container (Repeater): seed the array value, never leak item fields.
21
+ if (isArrayScope(component)) {
22
+ if (!component.name)
23
+ return;
24
+ const template = getChildComponents(component);
25
+ if (component.default !== undefined && Array.isArray(component.default)) {
26
+ defaults[component.name] = component.default;
27
+ return;
28
+ }
29
+ const count = typeof component.defaultItems === 'number' && component.defaultItems > 0
30
+ ? component.defaultItems
31
+ : typeof component.minItems === 'number' && component.minItems > 0
32
+ ? component.minItems
33
+ : 0;
34
+ if (count > 0 && template.length > 0) {
35
+ const itemDefaults = extractDefaultValues(template);
36
+ defaults[component.name] = Array.from({ length: count }, () => ({ ...itemDefaults }));
37
+ }
38
+ return;
39
+ }
40
+ // Layout container: transparent, recurse into children.
41
+ if (isLayout(component)) {
42
+ Object.assign(defaults, extractDefaultValues(getChildComponents(component)));
43
+ return;
44
+ }
45
+ // Leaf field with a default value.
46
+ if (component.name && component.default !== undefined) {
47
+ defaults[component.name] = component.default;
48
+ }
49
+ });
50
+ return defaults;
51
+ }
52
+ /**
53
+ * FormRenderer component
54
+ * Main component that accepts JSON schema and renders the form
55
+ */
56
+ export function FormRenderer({ schema, onSubmit, defaultValues = {}, className, apiBaseUrl, resource, operation, children, }) {
57
+ const { t } = useTranslation();
58
+ // Extract default values from schema and merge with user-provided defaults
59
+ const mergedDefaults = useMemo(() => {
60
+ const schemaDefaults = extractDefaultValues(schema.components);
61
+ return { ...schemaDefaults, ...defaultValues };
62
+ }, [schema.components, defaultValues]);
63
+ const methods = useForm({
64
+ defaultValues: mergedDefaults,
65
+ mode: 'onChange', // Validate and re-validate on change
66
+ });
67
+ const handleSubmit = async (data) => {
68
+ try {
69
+ await onSubmit(data);
70
+ }
71
+ catch (error) {
72
+ console.error('Form submission error:', error);
73
+ }
74
+ };
75
+ // Calculate grid classes based on the columns prop (static class maps — purge-safe)
76
+ const formGridClasses = !schema.columns || schema.columns === 1 ? 'space-y-6' : `${getGridClasses(schema.columns)} gap-y-4`;
77
+ return (_jsxs(FormProvider, { ...methods, children: [children, _jsxs("form", { onSubmit: methods.handleSubmit(handleSubmit), className: cn(className), noValidate: true, children: [_jsx(Slot, { name: "form.header", context: { resourceSlug: resource, record: defaultValues, schema }, as: "div", className: "mb-4 space-y-3 empty:hidden" }), _jsx("div", { className: formGridClasses, children: schema.components.map((field, index) => (_jsx(FieldRenderer, { field: field, apiBaseUrl: apiBaseUrl, resource: resource, operation: operation, mode: "edit" }, field.name || index))) }), _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-3 pt-6", children: [_jsx(Slot, { name: "form.footer", context: { resourceSlug: resource, record: defaultValues, schema }, as: "div", className: "mr-auto flex flex-wrap items-center gap-2 empty:hidden" }), _jsx(Button, { variant: "secondary", onClick: () => methods.reset(), children: t('core:common.reset') }), _jsx(Button, { type: "submit", loading: methods.formState.isSubmitting, children: methods.formState.isSubmitting ? t('core:common.submitting') : t('core:common.submit') })] })] })] }));
78
+ }
@@ -0,0 +1,2 @@
1
+ export { TableRenderer } from './table/TableRenderer';
2
+ export type { TableRendererProps } from './table/TableRenderer';
@@ -0,0 +1 @@
1
+ export { TableRenderer } from './table/TableRenderer';
@@ -0,0 +1,23 @@
1
+ export interface ActionResult {
2
+ success: boolean;
3
+ message?: string;
4
+ data?: any;
5
+ redirect?: string;
6
+ [key: string]: any;
7
+ }
8
+ /**
9
+ * Execute a single row action
10
+ * @param apiUrl - The base API URL for the resource (e.g., http://localhost:3001/api/users)
11
+ * @param actionName - The name of the action to execute
12
+ * @param recordId - The record ID (backend will populate the full record)
13
+ * @param formData - Optional form data from the action form
14
+ */
15
+ export declare function executeAction(apiUrl: string, actionName: string, recordId: string, formData?: any): Promise<ActionResult>;
16
+ /**
17
+ * Execute a bulk action on multiple rows
18
+ * @param apiUrl - The base API URL for the resource (e.g., http://localhost:3001/api/users)
19
+ * @param actionName - The name of the action to execute
20
+ * @param recordIds - Array of record IDs (backend will populate the full records)
21
+ * @param formData - Optional form data from the action form
22
+ */
23
+ export declare function executeBulkAction(apiUrl: string, actionName: string, recordIds: string[], formData?: any): Promise<ActionResult>;
@@ -0,0 +1,46 @@
1
+ import { ApiError, apiPost } from './http';
2
+ import { deriveApiBaseUrl } from './urls';
3
+ import { translate } from '../i18n/activeLocale';
4
+ async function runAction(apiUrl, actionName, recordIds, formData, isBulk) {
5
+ try {
6
+ const result = await apiPost(`${apiUrl}/actions`, {
7
+ action: actionName,
8
+ data: { recordIds, formData: formData || {} },
9
+ ...(isBulk ? { isBulk: true } : {}),
10
+ }, deriveApiBaseUrl(apiUrl));
11
+ return {
12
+ ...result,
13
+ success: result.success !== false,
14
+ message: result.message,
15
+ data: result.data,
16
+ redirect: result.redirect,
17
+ };
18
+ }
19
+ catch (error) {
20
+ const fallback = isBulk ? translate('core:error.action_failed_bulk') : translate('core:error.action_failed');
21
+ return {
22
+ success: false,
23
+ message: error instanceof ApiError ? error.message : error?.message || fallback,
24
+ };
25
+ }
26
+ }
27
+ /**
28
+ * Execute a single row action
29
+ * @param apiUrl - The base API URL for the resource (e.g., http://localhost:3001/api/users)
30
+ * @param actionName - The name of the action to execute
31
+ * @param recordId - The record ID (backend will populate the full record)
32
+ * @param formData - Optional form data from the action form
33
+ */
34
+ export function executeAction(apiUrl, actionName, recordId, formData) {
35
+ return runAction(apiUrl, actionName, [recordId], formData, false);
36
+ }
37
+ /**
38
+ * Execute a bulk action on multiple rows
39
+ * @param apiUrl - The base API URL for the resource (e.g., http://localhost:3001/api/users)
40
+ * @param actionName - The name of the action to execute
41
+ * @param recordIds - Array of record IDs (backend will populate the full records)
42
+ * @param formData - Optional form data from the action form
43
+ */
44
+ export function executeBulkAction(apiUrl, actionName, recordIds, formData) {
45
+ return runAction(apiUrl, actionName, recordIds, formData, true);
46
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Fetch wrapper that automatically retries with a silent token refresh on 401.
3
+ * Auth tokens are carried by HTTP-only cookies — no Authorization header needed.
4
+ *
5
+ * Sends `X-KratosJs-Locale` so the server localizes labels/schemas/action
6
+ * messages to the admin's current UI locale.
7
+ */
8
+ export declare function authenticatedFetch(url: string, options: RequestInit, apiBaseUrl: string): Promise<Response>;
@@ -0,0 +1,31 @@
1
+ import { AuthApiClient } from '../auth/authApiClient';
2
+ import { getActiveLocale } from '../i18n/activeLocale';
3
+ /**
4
+ * Fetch wrapper that automatically retries with a silent token refresh on 401.
5
+ * Auth tokens are carried by HTTP-only cookies — no Authorization header needed.
6
+ *
7
+ * Sends `X-KratosJs-Locale` so the server localizes labels/schemas/action
8
+ * messages to the admin's current UI locale.
9
+ */
10
+ export async function authenticatedFetch(url, options = {}, apiBaseUrl) {
11
+ const headers = new Headers({
12
+ 'Content-Type': 'application/json',
13
+ 'X-KratosJs-Locale': getActiveLocale(),
14
+ ...options.headers,
15
+ });
16
+ let response = await fetch(url, { ...options, headers, credentials: 'include' });
17
+ if (response.status === 401) {
18
+ const authClient = new AuthApiClient(apiBaseUrl);
19
+ const tokens = await authClient.refreshToken();
20
+ if (tokens) {
21
+ response = await fetch(url, { ...options, headers, credentials: 'include' });
22
+ }
23
+ else {
24
+ return response;
25
+ }
26
+ }
27
+ if (response.ok && response.headers.get('X-KratosJs-Refresh-Badges')) {
28
+ window.dispatchEvent(new CustomEvent('kratosjs-refresh-badges'));
29
+ }
30
+ return response;
31
+ }
@@ -0,0 +1,18 @@
1
+ export interface ExportOptions {
2
+ /** Export format, e.g. 'csv'. */
3
+ format: string;
4
+ /** Originating action name (used for server-side per-action authorization). */
5
+ action?: string;
6
+ /** Current table query (search/filters/sort) — exports all matching rows. */
7
+ query?: Record<string, any>;
8
+ /** Specific record ids — exports only these (bulk "export selected"). */
9
+ recordIds?: any[];
10
+ }
11
+ /**
12
+ * POST to a resource's `/export` endpoint and trigger a browser download of the
13
+ * returned file. Used by header/bulk actions marked with `exportsTo(format)`.
14
+ *
15
+ * @param resourceUrl - The resource endpoint (e.g. `${apiBaseUrl}/users`)
16
+ * @param apiBaseUrl - Panel API base (for token refresh)
17
+ */
18
+ export declare function downloadExport(resourceUrl: string, apiBaseUrl: string, options: ExportOptions): Promise<void>;
@@ -0,0 +1,50 @@
1
+ import { authenticatedFetch } from './authenticatedFetch';
2
+ /**
3
+ * POST to a resource's `/export` endpoint and trigger a browser download of the
4
+ * returned file. Used by header/bulk actions marked with `exportsTo(format)`.
5
+ *
6
+ * @param resourceUrl - The resource endpoint (e.g. `${apiBaseUrl}/users`)
7
+ * @param apiBaseUrl - Panel API base (for token refresh)
8
+ */
9
+ export async function downloadExport(resourceUrl, apiBaseUrl, options) {
10
+ const { format, action, query, recordIds } = options;
11
+ const url = `${resourceUrl.replace(/\/$/, '')}/export`;
12
+ const body = { format, ...(query || {}) };
13
+ if (action) {
14
+ body.action = action;
15
+ }
16
+ if (recordIds && recordIds.length > 0) {
17
+ body.recordIds = recordIds;
18
+ }
19
+ const response = await authenticatedFetch(url, { method: 'POST', body: JSON.stringify(body) }, apiBaseUrl);
20
+ if (!response.ok) {
21
+ let message = `Export failed (${response.status})`;
22
+ try {
23
+ const errorBody = await response.json();
24
+ message = errorBody.message || message;
25
+ }
26
+ catch {
27
+ // response had no JSON body
28
+ }
29
+ throw new Error(message);
30
+ }
31
+ const blob = await response.blob();
32
+ const filename = parseContentDispositionFilename(response.headers.get('Content-Disposition')) || `export.${format}`;
33
+ triggerBrowserDownload(blob, filename);
34
+ }
35
+ function parseContentDispositionFilename(header) {
36
+ if (!header)
37
+ return undefined;
38
+ const match = /filename\*?=(?:UTF-8'')?["']?([^"';]+)["']?/i.exec(header);
39
+ return match ? decodeURIComponent(match[1]) : undefined;
40
+ }
41
+ function triggerBrowserDownload(blob, filename) {
42
+ const objectUrl = URL.createObjectURL(blob);
43
+ const anchor = document.createElement('a');
44
+ anchor.href = objectUrl;
45
+ anchor.download = filename;
46
+ document.body.appendChild(anchor);
47
+ anchor.click();
48
+ anchor.remove();
49
+ URL.revokeObjectURL(objectUrl);
50
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Typed error thrown by apiFetch for any non-2xx response.
3
+ * Carries the HTTP status and whatever the server put in the body so
4
+ * callers can map field-level validation errors or show the message.
5
+ */
6
+ export declare class ApiError extends Error {
7
+ readonly status: number;
8
+ readonly details?: unknown;
9
+ constructor(message: string, status: number, details?: unknown);
10
+ get isUnauthorized(): boolean;
11
+ }
12
+ export interface ApiFetchOptions extends RequestInit {
13
+ /** Base URL of the panel API, used for token refresh on 401 */
14
+ apiBaseUrl: string;
15
+ }
16
+ /**
17
+ * JSON fetch with auth + token refresh + uniform error handling.
18
+ * Throws ApiError on any non-ok response, preserving the server message.
19
+ */
20
+ export declare function apiFetch<T = unknown>(url: string, options: ApiFetchOptions): Promise<T>;
21
+ /** Convenience JSON POST */
22
+ export declare function apiPost<T = unknown>(url: string, payload: unknown, apiBaseUrl: string): Promise<T>;
23
+ /** Convenience JSON GET */
24
+ export declare function apiGet<T = unknown>(url: string, apiBaseUrl: string): Promise<T>;
@@ -0,0 +1,52 @@
1
+ import { authenticatedFetch } from './authenticatedFetch';
2
+ /**
3
+ * Typed error thrown by apiFetch for any non-2xx response.
4
+ * Carries the HTTP status and whatever the server put in the body so
5
+ * callers can map field-level validation errors or show the message.
6
+ */
7
+ export class ApiError extends Error {
8
+ constructor(message, status, details) {
9
+ super(message);
10
+ this.name = 'ApiError';
11
+ this.status = status;
12
+ this.details = details;
13
+ }
14
+ get isUnauthorized() {
15
+ return this.status === 401;
16
+ }
17
+ }
18
+ /**
19
+ * JSON fetch with auth + token refresh + uniform error handling.
20
+ * Throws ApiError on any non-ok response, preserving the server message.
21
+ */
22
+ export async function apiFetch(url, options) {
23
+ const { apiBaseUrl, ...init } = options;
24
+ const response = await authenticatedFetch(url, init, apiBaseUrl);
25
+ let body = null;
26
+ const text = await response.text();
27
+ if (text) {
28
+ try {
29
+ body = JSON.parse(text);
30
+ }
31
+ catch {
32
+ body = text;
33
+ }
34
+ }
35
+ if (!response.ok) {
36
+ const message = response.status === 401
37
+ ? 'Unauthorized - Please login again'
38
+ : (body && typeof body === 'object' && (body.message || body.error)) ||
39
+ response.statusText ||
40
+ `Request failed with status ${response.status}`;
41
+ throw new ApiError(message, response.status, body);
42
+ }
43
+ return body;
44
+ }
45
+ /** Convenience JSON POST */
46
+ export function apiPost(url, payload, apiBaseUrl) {
47
+ return apiFetch(url, { method: 'POST', body: JSON.stringify(payload), apiBaseUrl });
48
+ }
49
+ /** Convenience JSON GET */
50
+ export function apiGet(url, apiBaseUrl) {
51
+ return apiFetch(url, { apiBaseUrl });
52
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Typed endpoints for the panel's resource API.
3
+ * All functions take the panel apiBaseUrl (e.g. http://host/kratosjs/api) and a resource slug.
4
+ */
5
+ export interface RecordEnvelope<T = any> {
6
+ data: T;
7
+ metadata?: {
8
+ recordTitle?: string;
9
+ refreshBadges?: boolean;
10
+ [key: string]: any;
11
+ };
12
+ }
13
+ /** GET /:slug/:id */
14
+ export declare function getRecord(apiBaseUrl: string, slug: string, id: string | number): Promise<RecordEnvelope>;
15
+ /** POST /:slug */
16
+ export declare function createRecord(apiBaseUrl: string, slug: string, payload: any): Promise<RecordEnvelope>;
17
+ /** POST /:slug/update/:id */
18
+ export declare function updateRecord(apiBaseUrl: string, slug: string, id: string | number, payload: any): Promise<RecordEnvelope>;
19
+ /** POST /:slug/bulk-delete */
20
+ export declare function bulkDelete(apiBaseUrl: string, slug: string, ids: any[]): Promise<{
21
+ deleted?: any[];
22
+ metadata?: {
23
+ refreshBadges?: boolean;
24
+ };
25
+ [key: string]: any;
26
+ }>;
27
+ /** GET /:slug/schema/form — returns the serialized form schema */
28
+ export declare function getFormSchema(apiBaseUrl: string, slug: string): Promise<any>;
29
+ /**
30
+ * GET /:slug/schema/table — returns the serialized table schema with
31
+ * the resource capability flags merged in (as TableRenderer expects).
32
+ */
33
+ export declare function getTableSchema(apiBaseUrl: string, slug: string): Promise<any>;
34
+ /** GET /:slug/relations — relation metadata for the view modal */
35
+ export declare function getRelations(apiBaseUrl: string, slug: string): Promise<any[]>;
36
+ /** POST /:parentSlug/:parentId/relations/:relationName */
37
+ export declare function createRelationRecord(apiBaseUrl: string, parentSlug: string, parentId: string | number, relationName: string, payload: any): Promise<RecordEnvelope>;
@@ -0,0 +1,52 @@
1
+ import { apiGet, apiPost } from './http';
2
+ /** Normalize bare-record responses into the `{ data, metadata }` envelope. */
3
+ function toEnvelope(result) {
4
+ if (result && typeof result === 'object' && 'data' in result) {
5
+ return result;
6
+ }
7
+ return { data: result };
8
+ }
9
+ /** GET /:slug/:id */
10
+ export async function getRecord(apiBaseUrl, slug, id) {
11
+ return toEnvelope(await apiGet(`${apiBaseUrl}/${slug}/${id}`, apiBaseUrl));
12
+ }
13
+ /** POST /:slug */
14
+ export async function createRecord(apiBaseUrl, slug, payload) {
15
+ return toEnvelope(await apiPost(`${apiBaseUrl}/${slug}`, payload, apiBaseUrl));
16
+ }
17
+ /** POST /:slug/update/:id */
18
+ export async function updateRecord(apiBaseUrl, slug, id, payload) {
19
+ return toEnvelope(await apiPost(`${apiBaseUrl}/${slug}/update/${id}`, payload, apiBaseUrl));
20
+ }
21
+ /** POST /:slug/bulk-delete */
22
+ export function bulkDelete(apiBaseUrl, slug, ids) {
23
+ return apiPost(`${apiBaseUrl}/${slug}/bulk-delete`, { ids }, apiBaseUrl);
24
+ }
25
+ /** GET /:slug/schema/form — returns the serialized form schema */
26
+ export async function getFormSchema(apiBaseUrl, slug) {
27
+ const result = await apiGet(`${apiBaseUrl}/${slug}/schema/form`, apiBaseUrl);
28
+ return result?.schema || result;
29
+ }
30
+ /**
31
+ * GET /:slug/schema/table — returns the serialized table schema with
32
+ * the resource capability flags merged in (as TableRenderer expects).
33
+ */
34
+ export async function getTableSchema(apiBaseUrl, slug) {
35
+ const result = await apiGet(`${apiBaseUrl}/${slug}/schema/table`, apiBaseUrl);
36
+ return {
37
+ ...(result?.schema || result),
38
+ canCreate: result?.canCreate,
39
+ canEdit: result?.canEdit,
40
+ canDelete: result?.canDelete,
41
+ canView: result?.canView,
42
+ };
43
+ }
44
+ /** GET /:slug/relations — relation metadata for the view modal */
45
+ export async function getRelations(apiBaseUrl, slug) {
46
+ const result = await apiGet(`${apiBaseUrl}/${slug}/relations`, apiBaseUrl);
47
+ return result?.relations || [];
48
+ }
49
+ /** POST /:parentSlug/:parentId/relations/:relationName */
50
+ export async function createRelationRecord(apiBaseUrl, parentSlug, parentId, relationName, payload) {
51
+ return toEnvelope(await apiPost(`${apiBaseUrl}/${parentSlug}/${parentId}/relations/${relationName}`, payload, apiBaseUrl));
52
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Query parameters for table API requests
3
+ */
4
+ export interface QueryParams {
5
+ page?: number;
6
+ perPage?: number;
7
+ search?: string;
8
+ sort?: string;
9
+ sortDirection?: 'asc' | 'desc';
10
+ filters?: Record<string, any>;
11
+ queryBuilders?: Record<string, any[]>;
12
+ }
13
+ /**
14
+ * Standard pagination metadata
15
+ */
16
+ export interface PaginationMeta {
17
+ /** Current page number (1-indexed) */
18
+ page: number;
19
+ /** Number of items per page */
20
+ limit: number;
21
+ /** Total number of items across all pages */
22
+ total: number;
23
+ /** Total number of pages */
24
+ pages: number;
25
+ /** Whether there's a next page */
26
+ hasNext: boolean;
27
+ /** Whether there's a previous page */
28
+ hasPrev: boolean;
29
+ }
30
+ /**
31
+ * Result structure for table API responses
32
+ */
33
+ export interface QueryResult {
34
+ data: any[];
35
+ pagination: PaginationMeta;
36
+ widgets?: Record<string, any>;
37
+ }
38
+ /**
39
+ * API client for communicating with the table backend
40
+ */
41
+ export declare class TableApiClient {
42
+ private baseUrl;
43
+ private apiBaseUrl;
44
+ private fetchPath;
45
+ /**
46
+ * @param apiBaseUrl - Base URL for the panel API (used for token refresh)
47
+ * @param baseUrl - Base URL of the resource endpoint (e.g. 'http://localhost:3001/api/users')
48
+ * @param fetchPath - Path appended for list queries ('/list' for resources, '' for custom endpoints)
49
+ */
50
+ constructor(apiBaseUrl: string, baseUrl: string, fetchPath?: string);
51
+ /**
52
+ * Fetch table data with filtering, sorting, and pagination
53
+ */
54
+ fetchData(params: QueryParams): Promise<QueryResult>;
55
+ /**
56
+ * Update a single record. Unwraps the `{ data, metadata }` envelope.
57
+ */
58
+ updateRecord(id: any, data: any): Promise<any>;
59
+ /**
60
+ * Delete records (bulk or single).
61
+ * Returns the full response body (including metadata e.g. refreshBadges) so callers can react to it.
62
+ */
63
+ deleteRecords(ids: any[]): Promise<{
64
+ deleted?: any[];
65
+ metadata?: {
66
+ refreshBadges?: boolean;
67
+ };
68
+ [key: string]: any;
69
+ }>;
70
+ /**
71
+ * Bulk delete records (alias for deleteRecords)
72
+ */
73
+ bulkDelete(ids: any[]): Promise<{
74
+ deleted?: any[];
75
+ metadata?: {
76
+ refreshBadges?: boolean;
77
+ };
78
+ [key: string]: any;
79
+ }>;
80
+ getBaseUrl(): string;
81
+ getFetchPath(): string;
82
+ getApiBaseUrl(): string;
83
+ }