adminizer 4.6.0 → 4.7.0-build.222

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 (335) hide show
  1. package/Readme.md +12 -0
  2. package/assets/RelationDialogStack-CnHFOYyR.css +1 -0
  3. package/assets/RelationDialogStack-DI2bZxQX.js +20 -0
  4. package/assets/add-DCQ7ZW4B.js +1 -0
  5. package/assets/add-group-DCVPryBo.js +1 -0
  6. package/assets/add-group-form-DKRXC2n-.js +1 -0
  7. package/assets/add-user-B7OOiYxv.js +1 -0
  8. package/assets/add-user-form-UXAToWQd.js +1 -0
  9. package/assets/app-AKbNCggP.css +1 -0
  10. package/assets/app-layout-6EwNBvnR.js +1 -0
  11. package/assets/app-shell-D8wtkECO.js +1 -0
  12. package/assets/app-sidebar-DfGjL-2K.js +1 -0
  13. package/assets/app-sidebar-header-BZbIBQjq.js +1 -0
  14. package/assets/app.js +59 -7990
  15. package/assets/breadcrumbs-CODaqVkB.js +1 -0
  16. package/assets/catalog-DVvFGa2X.js +6 -0
  17. package/assets/dashboard-BadoiH_a.js +3 -0
  18. package/assets/date-picker-DSOkNiNo.js +1 -0
  19. package/assets/del-modal-Cd4M7af8.js +1 -0
  20. package/assets/dynamic-controls-BsrJhPDY.js +1 -0
  21. package/assets/geo-json-CzR5JBXL.js +1 -0
  22. package/assets/handsontable-BI98OF5R.js +336 -0
  23. package/assets/history-D1iLA6rs.js +1 -0
  24. package/assets/home-DbWj-W_k.js +2 -0
  25. package/assets/icon-C2JNaLxH.js +1 -0
  26. package/assets/init-user-D2HSyXup.js +1 -0
  27. package/assets/input-error-CH2caTtO.js +1 -0
  28. package/assets/jsoneditor-DVNQmA6G.js +3869 -0
  29. package/assets/list-CVoljVUw.js +4 -0
  30. package/assets/login-DFSLEO17.js +1 -0
  31. package/assets/manifest.json +246 -273
  32. package/assets/material-icon-Bx9pGQiQ.js +1 -0
  33. package/assets/media-manager-WcKe1EvD.js +6 -0
  34. package/assets/module-DJsC37CM.js +1 -0
  35. package/assets/monaco-Bl4zdWCn.js +11 -0
  36. package/assets/nav-footer-BiSQkPt4.js +1 -0
  37. package/assets/nav-main-rTH0PfDw.js +1 -0
  38. package/assets/nav-user-Bj6cWs0a.js +1 -0
  39. package/assets/notification-DKrNfaAB.js +20 -0
  40. package/assets/pagination-render-AKJvTIRA.js +1 -0
  41. package/assets/register-BTP4uxsK.js +1 -0
  42. package/assets/ru-eW0WKkga.js +1 -0
  43. package/assets/theme-switcher-Dm8EOGzx.js +1 -0
  44. package/assets/toast-editor-DOg_gvSp.js +668 -0
  45. package/assets/user-filters-list-C9R9J6Om.js +1 -0
  46. package/assets/user-info-BgSbT02v.js +1 -0
  47. package/assets/user-menu-content-TQTXHIv6.js +1 -0
  48. package/assets/{vanilla-picker-l5rcX3cq.js → vanilla-picker-B3LgXoKV.js} +1 -7
  49. package/assets/welcome-BwDlAOGh.js +1 -0
  50. package/controllers/add.d.ts +1 -1
  51. package/controllers/add.js +20 -26
  52. package/controllers/addGroup.d.ts +1 -1
  53. package/controllers/addGroup.js +7 -15
  54. package/controllers/addUser.d.ts +1 -1
  55. package/controllers/addUser.js +10 -16
  56. package/controllers/catalog/Catalog.d.ts +1 -1
  57. package/controllers/catalog/Catalog.js +1 -10
  58. package/controllers/catalog/FrontendCatalogAdapter.d.ts +3 -3
  59. package/controllers/catalog/FrontendCatalogAdapter.js +0 -6
  60. package/controllers/catalog/FrontentCatalogAdapter.d.ts +3 -3
  61. package/controllers/catalog/FrontentCatalogAdapter.js +0 -4
  62. package/controllers/ckeditorUpload.js +2 -18
  63. package/controllers/dashboard.d.ts +1 -1
  64. package/controllers/dashboard.js +2 -5
  65. package/controllers/edit.js +24 -37
  66. package/controllers/editGroup.d.ts +1 -1
  67. package/controllers/editGroup.js +10 -21
  68. package/controllers/editUser.d.ts +1 -1
  69. package/controllers/editUser.js +11 -23
  70. package/controllers/exportData.d.ts +6 -0
  71. package/controllers/exportData.js +315 -0
  72. package/controllers/feed.d.ts +6 -0
  73. package/controllers/feed.js +73 -0
  74. package/controllers/feedback/feedbackController.d.ts +1 -1
  75. package/controllers/feedback/feedbackController.js +5 -7
  76. package/controllers/filter-fields/columns.d.ts +11 -0
  77. package/controllers/filter-fields/columns.js +106 -0
  78. package/controllers/filter-fields/filterFields.d.ts +10 -0
  79. package/controllers/filter-fields/filterFields.js +141 -0
  80. package/controllers/filter-fields/getAllUserFilters.d.ts +6 -0
  81. package/controllers/filter-fields/getAllUserFilters.js +115 -0
  82. package/controllers/filter-fields/groups.d.ts +5 -0
  83. package/controllers/filter-fields/groups.js +26 -0
  84. package/controllers/filter-fields/savedFilters.d.ts +25 -0
  85. package/controllers/filter-fields/savedFilters.js +317 -0
  86. package/controllers/getAllWidgets.d.ts +1 -1
  87. package/controllers/getAllWidgets.js +1 -9
  88. package/controllers/history-actions/HistoryController.js +6 -31
  89. package/controllers/initUser.js +6 -5
  90. package/controllers/inlineUpdate.d.ts +7 -0
  91. package/controllers/inlineUpdate.js +148 -0
  92. package/controllers/list.d.ts +1 -1
  93. package/controllers/list.js +383 -70
  94. package/controllers/listUserFilters.d.ts +5 -0
  95. package/controllers/listUserFilters.js +26 -0
  96. package/controllers/login.js +2 -2
  97. package/controllers/media-manager/mediaManagerApi.js +0 -9
  98. package/controllers/navigation/edit.js +3 -9
  99. package/controllers/notifications/NotificationController.d.ts +1 -1
  100. package/controllers/notifications/NotificationController.js +12 -36
  101. package/controllers/register.js +10 -9
  102. package/controllers/remove.js +10 -19
  103. package/controllers/timezones.d.ts +1 -1
  104. package/controllers/timezones.js +0 -6
  105. package/controllers/userApiKey.d.ts +7 -0
  106. package/controllers/userApiKey.js +36 -0
  107. package/controllers/view.js +14 -26
  108. package/controllers/welcome.d.ts +1 -1
  109. package/controllers/welcome.js +0 -4
  110. package/controllers/widgets/Action.d.ts +1 -1
  111. package/controllers/widgets/Action.js +1 -9
  112. package/controllers/widgets/Custom.d.ts +1 -1
  113. package/controllers/widgets/Custom.js +1 -9
  114. package/controllers/widgets/Info.d.ts +1 -1
  115. package/controllers/widgets/Info.js +1 -9
  116. package/controllers/widgets/filterInfo.d.ts +1 -0
  117. package/controllers/widgets/filterInfo.js +44 -0
  118. package/controllers/widgets/switch.d.ts +1 -1
  119. package/controllers/widgets/switch.js +1 -9
  120. package/controllers/widgetsDB.d.ts +1 -1
  121. package/controllers/widgetsDB.js +2 -8
  122. package/helpers/accessRightsHelper.d.ts +1 -1
  123. package/helpers/accessRightsHelper.js +5 -4
  124. package/helpers/apiKeyHelper.d.ts +5 -0
  125. package/helpers/apiKeyHelper.js +8 -0
  126. package/helpers/configHelper.js +12 -15
  127. package/helpers/controllerHelper.d.ts +14 -21
  128. package/helpers/controllerHelper.js +50 -83
  129. package/helpers/fieldsHelper.js +3 -3
  130. package/helpers/filterDatetimeHelper.d.ts +5 -0
  131. package/helpers/filterDatetimeHelper.js +84 -0
  132. package/helpers/inertiaActionsHelper.d.ts +2 -2
  133. package/helpers/inertiaActionsHelper.js +5 -4
  134. package/helpers/inertiaAddHelper.d.ts +3 -414
  135. package/helpers/inertiaAddHelper.js +39 -15
  136. package/helpers/inertiaGroupHelper.d.ts +2 -2
  137. package/helpers/inertiaGroupHelper.js +3 -3
  138. package/helpers/inertiaListHelper.d.ts +7 -3
  139. package/helpers/inertiaListHelper.js +26 -12
  140. package/helpers/inertiaMenuHelper.d.ts +1 -0
  141. package/helpers/inertiaMenuHelper.js +15 -3
  142. package/helpers/inertiaUserHelper.d.ts +3 -2
  143. package/helpers/inertiaUserHelper.js +7 -3
  144. package/helpers/menuHelper.d.ts +5 -2
  145. package/helpers/menuHelper.js +64 -12
  146. package/helpers/viteHelper.js +1 -2
  147. package/index.d.ts +6 -2
  148. package/index.js +6 -2
  149. package/interfaces/adminpanelConfig.d.ts +126 -39
  150. package/interfaces/internalModelAccess.d.ts +37 -0
  151. package/interfaces/internalModelAccess.js +1 -0
  152. package/interfaces/listQueryBuilder.d.ts +22 -0
  153. package/interfaces/listQueryBuilder.js +1 -0
  154. package/interfaces/queryCriteria.d.ts +54 -0
  155. package/interfaces/queryCriteria.js +1 -0
  156. package/interfaces/types.d.ts +1 -13
  157. package/lib/Adminizer.d.ts +4 -2
  158. package/lib/Adminizer.js +29 -10
  159. package/lib/DataAccessor.d.ts +8 -5
  160. package/lib/DataAccessor.js +89 -42
  161. package/lib/I18n.d.ts +5 -1
  162. package/lib/I18n.js +45 -19
  163. package/lib/MiddlewareManager.d.ts +8 -0
  164. package/lib/MiddlewareManager.js +53 -0
  165. package/lib/ai-assistant/OpenAiModelService.d.ts +3 -3
  166. package/lib/ai-assistant/OpenAiModelService.js +23 -24
  167. package/lib/catalog/Navigation.d.ts +1 -0
  168. package/lib/catalog/Navigation.js +12 -11
  169. package/lib/controls/jsoneditor/JsonEditor.d.ts +1 -2
  170. package/lib/controls/markdown/ToastUiEditor.d.ts +1 -2
  171. package/lib/feedback/FeedbackHandler.js +2 -2
  172. package/lib/filters/ConditionValidator.d.ts +107 -0
  173. package/lib/filters/ConditionValidator.js +483 -0
  174. package/lib/filters/CustomFilterHandler.d.ts +122 -0
  175. package/lib/filters/CustomFilterHandler.js +131 -0
  176. package/lib/filters/FilterCustomFieldHandler.d.ts +2 -0
  177. package/lib/filters/FilterCustomFieldHandler.js +2 -0
  178. package/lib/filters/FilterService.d.ts +82 -0
  179. package/lib/filters/FilterService.js +323 -0
  180. package/lib/filters/index.d.ts +6 -0
  181. package/lib/filters/index.js +4 -0
  182. package/lib/history-actions/AbstractHistoryAdapter.d.ts +5 -4
  183. package/lib/history-actions/AbstractHistoryAdapter.js +45 -30
  184. package/lib/history-actions/DefaultHistoryAdapter.d.ts +2 -0
  185. package/lib/history-actions/DefaultHistoryAdapter.js +12 -6
  186. package/lib/history-actions/HistoryHandler.js +1 -1
  187. package/lib/list-query-builder/ListQueryBuilder.d.ts +117 -0
  188. package/lib/list-query-builder/ListQueryBuilder.js +707 -0
  189. package/lib/media-manager/AbstractMediaManager.d.ts +9 -8
  190. package/lib/media-manager/DefaultMediaManager.d.ts +2 -0
  191. package/lib/media-manager/DefaultMediaManager.js +27 -15
  192. package/lib/media-manager/Items.d.ts +4 -1
  193. package/lib/media-manager/Items.js +62 -59
  194. package/lib/media-manager/MediaManagerHandler.js +1 -1
  195. package/lib/media-manager/helpers/MediaManagerHelper.d.ts +5 -1
  196. package/lib/media-manager/helpers/MediaManagerHelper.js +38 -4
  197. package/lib/model/AbstractModel.d.ts +33 -25
  198. package/lib/model/AbstractModel.js +54 -2
  199. package/lib/model/InternalModelAccessFactory.d.ts +18 -0
  200. package/lib/model/InternalModelAccessFactory.js +82 -0
  201. package/lib/model/ModelHandler.d.ts +6 -0
  202. package/lib/model/ModelHandler.js +14 -0
  203. package/lib/model/adapter/sequelize.d.ts +32 -10
  204. package/lib/model/adapter/sequelize.js +409 -62
  205. package/lib/model/adapter/typeorm.d.ts +62 -0
  206. package/lib/model/adapter/typeorm.js +777 -0
  207. package/lib/model/internalModelAccessToken.d.ts +1 -0
  208. package/lib/model/internalModelAccessToken.js +1 -0
  209. package/lib/model/internalModelRepository.d.ts +3 -0
  210. package/lib/model/internalModelRepository.js +4 -0
  211. package/lib/notifications/AbstractNotificationService.d.ts +3 -0
  212. package/lib/notifications/AbstractNotificationService.js +42 -36
  213. package/lib/notifications/GeneralNotificationService.js +37 -40
  214. package/lib/notifications/SystemNotificationService.js +33 -36
  215. package/lib/requestProcessor.js +0 -3
  216. package/lib/ui-i18n/getUiTranslations.d.ts +1 -0
  217. package/lib/ui-i18n/getUiTranslations.js +3 -0
  218. package/lib/ui-i18n/uiTranslationKeys.d.ts +6 -0
  219. package/lib/ui-i18n/uiTranslationKeys.js +268 -0
  220. package/lib/widgets/widgetHandler.d.ts +7 -2
  221. package/lib/widgets/widgetHandler.js +98 -18
  222. package/models/FilterAP.d.ts +116 -0
  223. package/models/FilterAP.js +68 -0
  224. package/models/FilterColumnAP.d.ts +32 -0
  225. package/models/FilterColumnAP.js +21 -0
  226. package/models/GroupAP.d.ts +1 -1
  227. package/models/HistoryActionsAP.d.ts +3 -3
  228. package/models/MediaManagerMetaAP.d.ts +1 -1
  229. package/models/NavigationAP.d.ts +1 -1
  230. package/models/UserAP.d.ts +6 -1
  231. package/models/UserAP.js +4 -0
  232. package/package.json +39 -32
  233. package/policies/authPolicies.d.ts +12 -0
  234. package/policies/authPolicies.js +104 -0
  235. package/policies/permissionResolvers.d.ts +12 -0
  236. package/policies/permissionResolvers.js +52 -0
  237. package/services/FeedService.d.ts +70 -0
  238. package/services/FeedService.js +334 -0
  239. package/system/Router.d.ts +1 -0
  240. package/system/Router.js +136 -59
  241. package/system/bindAccessRights.js +11 -30
  242. package/system/bindAuthorization.js +18 -18
  243. package/system/bindCors.js +16 -1
  244. package/system/bindCustomFilterHandlers.d.ts +2 -0
  245. package/system/bindCustomFilterHandlers.js +4 -0
  246. package/system/bindInertia.js +18 -61
  247. package/system/bindReqFunctions.js +10 -2
  248. package/system/bindTranslations.js +7 -3
  249. package/system/buildInternalModelAccess.d.ts +4 -0
  250. package/system/buildInternalModelAccess.js +59 -0
  251. package/system/defaults.js +18 -14
  252. package/system/routePolicies.d.ts +2 -0
  253. package/system/routePolicies.js +29 -0
  254. package/translations/en.json +151 -39
  255. package/translations/ru.json +211 -64
  256. package/ui/components/handsontable.js +13 -27
  257. package/ui/components/ui/dialog-stack.js +1 -3
  258. package/ui/components/ui/popover.js +1 -1
  259. package/ui/components/ui/sidebar.js +1 -1
  260. package/assets/RelationDialogStack-D9UVEF9s.js +0 -407
  261. package/assets/RelationDialogStack-DV8OITPR.css +0 -4
  262. package/assets/add-BlvzWQKF.js +0 -1
  263. package/assets/add-group-1Uoq9NWe.js +0 -1
  264. package/assets/add-group-form-B01gwDGu.js +0 -1
  265. package/assets/add-user-BQCAsaRy.js +0 -1
  266. package/assets/add-user-form-Cgwc9JkI.js +0 -1
  267. package/assets/app-DaOMy1nl.css +0 -72
  268. package/assets/app-layout-CAm60qoE.js +0 -1
  269. package/assets/app-shell-QWCtn9ye.js +0 -1
  270. package/assets/app-sidebar-CfaYbnSy.js +0 -1
  271. package/assets/app-sidebar-header-BsPFDhZ8.js +0 -1
  272. package/assets/breadcrumbs-CZZirDj8.js +0 -1
  273. package/assets/catalog-k5myk7fk.js +0 -6
  274. package/assets/dashboard-BkL9ybBw.js +0 -3
  275. package/assets/date-picker-B5AZ_7Q9.js +0 -1
  276. package/assets/del-modal-BoyXZloG.js +0 -1
  277. package/assets/dynamic-controls-k61T9W2P.js +0 -1
  278. package/assets/form-1WGY0YgG.js +0 -1
  279. package/assets/form-DJapG3qF.js +0 -1
  280. package/assets/geo-json-DsMUHo0l.js +0 -4
  281. package/assets/handsontable-PxYdjN8c.js +0 -298
  282. package/assets/history-CluyR-yJ.js +0 -1
  283. package/assets/home-Dug9zBzM.js +0 -2
  284. package/assets/icon-DfDLMG5f.js +0 -1
  285. package/assets/init-user-CF80MEnT.js +0 -1
  286. package/assets/input-error-DuuqFgZa.js +0 -1
  287. package/assets/jsoneditor-De1FvcYu.js +0 -3882
  288. package/assets/list-CuexshNt.js +0 -1
  289. package/assets/list-table-BsEWjTKY.js +0 -22
  290. package/assets/login-eDemYzN-.js +0 -1
  291. package/assets/material-icon-DMT8KdmE.js +0 -1
  292. package/assets/media-manager-DfYa_mT_.js +0 -14
  293. package/assets/module-Cd4Tm6uq.js +0 -1
  294. package/assets/monaco-BhBYtg3d.js +0 -11
  295. package/assets/nav-footer-D3olYxtz.js +0 -1
  296. package/assets/nav-main-BctqyzeV.js +0 -1
  297. package/assets/nav-user-Bn1Lt-BZ.js +0 -1
  298. package/assets/notification-D64qvni-.js +0 -27
  299. package/assets/pagination-render-DxD78ahJ.js +0 -1
  300. package/assets/register-349PwYbe.js +0 -1
  301. package/assets/theme-switcher-DfExsHW2.js +0 -1
  302. package/assets/toast-editor-ESK5iWPx.js +0 -845
  303. package/assets/user-info-DtBK5Kh8.js +0 -1
  304. package/assets/user-menu-content-0XYOCMaA.js +0 -1
  305. package/assets/welcome-PDp-gUei.js +0 -1
  306. package/controllers/form.d.ts +0 -1
  307. package/controllers/form.js +0 -86
  308. package/helpers/formHelper.d.ts +0 -6
  309. package/helpers/formHelper.js +0 -38
  310. package/helpers/inertiaFromHelper.d.ts +0 -11
  311. package/helpers/inertiaFromHelper.js +0 -98
  312. package/helpers/runtimeMode.d.ts +0 -1
  313. package/helpers/runtimeMode.js +0 -3
  314. package/lib/PolicyManager.d.ts +0 -8
  315. package/lib/PolicyManager.js +0 -53
  316. package/lib/datatable/NodeTable.d.ts +0 -49
  317. package/lib/datatable/NodeTable.js +0 -207
  318. package/lib/model/adapter/waterline.d.ts +0 -32
  319. package/lib/model/adapter/waterline.js +0 -180
  320. package/migrations/index.d.ts +0 -3
  321. package/migrations/index.js +0 -4
  322. package/migrations/knex/20250106000001_adminizer_init.d.ts +0 -8
  323. package/migrations/knex/20250106000001_adminizer_init.js +0 -164
  324. package/migrations/umzug/0001.d.ts +0 -7
  325. package/migrations/umzug/0001.js +0 -121
  326. package/migrations/umzugExports.d.ts +0 -2
  327. package/migrations/umzugExports.js +0 -9
  328. package/system/bindForms.d.ts +0 -2
  329. package/system/bindForms.js +0 -20
  330. /package/{policies → middlewares}/addMessages.d.ts +0 -0
  331. /package/{policies → middlewares}/addMessages.js +0 -0
  332. /package/{policies → middlewares}/checkAuth.d.ts +0 -0
  333. /package/{policies → middlewares}/checkAuth.js +0 -0
  334. /package/{policies → middlewares}/setLocale.d.ts +0 -0
  335. /package/{policies → middlewares}/setLocale.js +0 -0
@@ -1,6 +1,11 @@
1
1
  import inertiaActionsHelper from "./inertiaActionsHelper.js";
2
- export function inertiaListHelper(entity, req, fields) {
2
+ export function inertiaListHelper(modelResource, req, fields, activeFilterName) {
3
3
  const actionType = 'list';
4
+ // Check if filters are enabled for this model
5
+ // Preferred: model-level `models.<Model>.filters`; fallback: legacy top-level `modelFilters.<Model>`
6
+ const modelFiltersConfig = modelResource.config?.filters ?? req.adminizer.config.modelFilters?.[modelResource.name];
7
+ const filtersEnabledGlobally = req.adminizer.config.filters?.enabled !== false;
8
+ const filtersEnabled = filtersEnabledGlobally && modelFiltersConfig?.enabled === true;
4
9
  let props = {
5
10
  thActionsTitle: req.i18n.__('Actions'),
6
11
  actions: [],
@@ -11,9 +16,9 @@ export function inertiaListHelper(entity, req, fields) {
11
16
  viewsTitle: '',
12
17
  deleteTitle: ''
13
18
  },
14
- entity: {
15
- name: entity.name,
16
- uri: entity.uri
19
+ modelResource: {
20
+ name: modelResource.name,
21
+ uri: modelResource.uri
17
22
  },
18
23
  delModal: {
19
24
  yes: req.i18n.__('Yes'),
@@ -23,23 +28,26 @@ export function inertiaListHelper(entity, req, fields) {
23
28
  notFoundContent: req.i18n.__('No records found !'),
24
29
  searchBtn: req.i18n.__('Search'),
25
30
  resetBtn: req.i18n.__('Reset'),
31
+ defaultPageSize: req.adminizer.config.list?.defaultPageSize ?? 50,
32
+ pageSizeOptions: [5, 20, 50],
26
33
  };
27
- if (entity.config.add && req.adminizer.accessRightsHelper.hasPermission(`create-${entity.name}-model`, req.user)) {
34
+ if (modelResource.config.add && req.adminizer.accessRightsHelper.hasPermission(`create-${modelResource.name}-model`, req.user, `CRUD create on model "${modelResource.name}"`)) {
28
35
  props.crudActions.createTitle = req.i18n.__('create');
29
36
  }
30
- if (entity.config.edit && req.adminizer.accessRightsHelper.hasPermission(`update-${entity.name}-model`, req.user)) {
37
+ if (modelResource.config.edit && req.adminizer.accessRightsHelper.hasPermission(`update-${modelResource.name}-model`, req.user, `CRUD update on model "${modelResource.name}"`)) {
31
38
  props.crudActions.editTitle = req.i18n.__('Edit');
32
39
  }
33
- if (entity.config.view && req.adminizer.accessRightsHelper.hasPermission(`read-${entity.name}-model`, req.user)) {
40
+ if (modelResource.config.view && req.adminizer.accessRightsHelper.hasPermission(`read-${modelResource.name}-model`, req.user, `CRUD read on model "${modelResource.name}"`)) {
34
41
  props.crudActions.viewsTitle = req.i18n.__('View');
35
42
  }
36
- if (entity.config.remove && req.adminizer.accessRightsHelper.hasPermission(`delete-${entity.name}-model`, req.user)) {
43
+ if (modelResource.config.remove && req.adminizer.accessRightsHelper.hasPermission(`delete-${modelResource.name}-model`, req.user, `CRUD delete on model "${modelResource.name}"`)) {
37
44
  props.crudActions.deleteTitle = req.i18n.__('Delete');
38
45
  }
39
- props.actions = inertiaActionsHelper(actionType, entity, req);
40
- if (req.adminizer.menuHelper.hasInlineActions(entity.config, 'list')) {
41
- for (const inlineAction of req.adminizer.menuHelper.getInlineActions(entity.config, 'list')) {
42
- if (req.adminizer.accessRightsHelper.hasPermission(inlineAction.accessRightsToken, req.user)) {
46
+ props.actions = inertiaActionsHelper(actionType, modelResource, req);
47
+ if (req.adminizer.menuHelper.hasInlineActions(modelResource.config, 'list')) {
48
+ for (const inlineAction of req.adminizer.menuHelper.getInlineActions(modelResource.config, 'list')) {
49
+ const context = `inline action "${inlineAction.title}" (${inlineAction.id}) on model "${modelResource.name}"`;
50
+ if (req.adminizer.accessRightsHelper.hasPermission(inlineAction.accessRightsToken, req.user, context)) {
43
51
  props.inlineActions.push({
44
52
  icon: inlineAction.icon,
45
53
  id: inlineAction.id,
@@ -50,5 +58,11 @@ export function inertiaListHelper(entity, req, fields) {
50
58
  }
51
59
  }
52
60
  }
61
+ // Add filtersEnabled flag
62
+ props.filtersEnabled = filtersEnabled;
63
+ // Add active filter name if filter is applied
64
+ if (activeFilterName) {
65
+ props.activeFilterName = activeFilterName;
66
+ }
53
67
  return props;
54
68
  }
@@ -4,6 +4,7 @@ export declare class InertiaMenuHelper {
4
4
  private adminizer;
5
5
  constructor(adminizer: Adminizer);
6
6
  getMenuItems(req: ReqType): MenuItem[];
7
+ private filterAccessibleItems;
7
8
  private translateMenuItem;
8
9
  private translateHrefItem;
9
10
  getBrandTitle(): string;
@@ -6,19 +6,31 @@ export class InertiaMenuHelper {
6
6
  getMenuItems(req) {
7
7
  const menu = [];
8
8
  for (const menuItem of this.adminizer.menuHelper.getMenuItems(req.user)) {
9
- const menuItemTokens = menuItem.actions ? menuItem.actions.map(item => {
9
+ const filteredActions = this.filterAccessibleItems(menuItem.actions ?? [], req);
10
+ const menuItemTokens = filteredActions.map(item => {
10
11
  return item.accessRightsToken;
11
12
  }).filter(item => {
12
13
  return item;
13
- }) : [];
14
+ });
14
15
  if (menuItem.accessRightsToken)
15
16
  menuItemTokens.push(menuItem.accessRightsToken);
16
17
  if (this.adminizer.accessRightsHelper.enoughPermissions(menuItemTokens, req.user)) {
17
- menu.push(this.translateMenuItem(req, menuItem));
18
+ menu.push(this.translateMenuItem(req, {
19
+ ...menuItem,
20
+ actions: filteredActions
21
+ }));
18
22
  }
19
23
  }
20
24
  return menu;
21
25
  }
26
+ filterAccessibleItems(items, req) {
27
+ return items
28
+ .filter((item) => !item.accessRightsToken || this.adminizer.accessRightsHelper.hasPermission(item.accessRightsToken, req.user))
29
+ .map((item) => ({
30
+ ...item,
31
+ subItems: item.subItems ? this.filterAccessibleItems(item.subItems, req) : item.subItems
32
+ }));
33
+ }
22
34
  translateMenuItem(req, menuItem) {
23
35
  return {
24
36
  ...menuItem,
@@ -1,6 +1,6 @@
1
1
  import { GroupAP } from "../models/GroupAP";
2
2
  import { UserAP } from "../models/UserAP";
3
- import { Entity, PropsField } from "../interfaces/types";
3
+ import { ModelResource, PropsField } from "../interfaces/types";
4
4
  interface listProps extends Record<string | number | symbol, unknown> {
5
5
  edit: boolean;
6
6
  view: boolean;
@@ -22,6 +22,7 @@ interface listProps extends Record<string | number | symbol, unknown> {
22
22
  label: string;
23
23
  postLink: string;
24
24
  };
25
+ apiKey?: string;
25
26
  }
26
- export declare function inertiaUserHelper(entity: Entity, req: ReqType, groups: GroupAP[], user?: UserAP, view?: boolean): listProps;
27
+ export declare function inertiaUserHelper(modelResource: ModelResource, req: ReqType, groups: GroupAP[], user?: UserAP, view?: boolean): listProps;
27
28
  export {};
@@ -1,10 +1,10 @@
1
- export function inertiaUserHelper(entity, req, groups, user, view = false) {
1
+ export function inertiaUserHelper(modelResource, req, groups, user, view = false) {
2
2
  let props = {
3
3
  edit: !!user,
4
4
  view: view,
5
5
  btnBack: {
6
6
  title: req.i18n.__('Back'),
7
- link: entity.uri
7
+ link: modelResource.uri
8
8
  },
9
9
  userPretend: {
10
10
  label: req.i18n.__('Pretend to be a user'),
@@ -14,7 +14,7 @@ export function inertiaUserHelper(entity, req, groups, user, view = false) {
14
14
  btnSave: {
15
15
  title: req.i18n.__('Save')
16
16
  },
17
- postLink: user ? `${entity.uri}/edit/${user.id}` : `${entity.uri}/add`,
17
+ postLink: user ? `${modelResource.uri}/edit/${user.id}` : `${modelResource.uri}/add`,
18
18
  head: req.i18n.__('User settings'),
19
19
  groupHead: req.i18n.__('User groups'),
20
20
  fields: [
@@ -111,5 +111,9 @@ export function inertiaUserHelper(entity, req, groups, user, view = false) {
111
111
  });
112
112
  }
113
113
  }
114
+ // Include apiKey for edit mode
115
+ if (user?.apiKey) {
116
+ props.apiKey = user.apiKey;
117
+ }
114
118
  return props;
115
119
  }
@@ -13,12 +13,15 @@ export type MenuItem = {
13
13
  actions: HrefConfig[] | null;
14
14
  icon: string | null;
15
15
  accessRightsToken: string | null;
16
- entityName?: string;
16
+ modelResourceName?: string;
17
17
  section?: string;
18
18
  };
19
19
  export declare class MenuHelper {
20
20
  private config;
21
21
  constructor(config: AdminpanelConfig);
22
+ private normalizePath;
23
+ private inferCatalogAccessToken;
24
+ private enrichHrefAccessToken;
22
25
  /**
23
26
  * Get menu brand title
24
27
  *
@@ -58,7 +61,7 @@ export declare class MenuHelper {
58
61
  */
59
62
  getInlineActions(modelConfig: ModelConfig, action: ActionType): HrefConfig[];
60
63
  /**
61
- * Get list of entity menus that was not bound to groups
64
+ * Get list of ModelResource menus that was not bound to groups
62
65
  *
63
66
  * @returns {Array}
64
67
  */
@@ -4,6 +4,48 @@ export class MenuHelper {
4
4
  constructor(config) {
5
5
  this.config = config;
6
6
  }
7
+ normalizePath(path) {
8
+ return path.replace(/[?#].*$/, "").replace(/\/+$/, "");
9
+ }
10
+ inferCatalogAccessToken(link) {
11
+ if (!link || typeof link !== "string") {
12
+ return undefined;
13
+ }
14
+ // Skip external links.
15
+ if (/^[a-z][a-z0-9+.-]*:/i.test(link) || link.startsWith("//")) {
16
+ return undefined;
17
+ }
18
+ const routePrefix = (this.config.routePrefix || "").replace(/\/+$/, "");
19
+ let normalized = this.normalizePath(link);
20
+ if (routePrefix && normalized.startsWith(`${routePrefix}/`)) {
21
+ normalized = normalized.slice(routePrefix.length);
22
+ }
23
+ else if (routePrefix && normalized === routePrefix) {
24
+ normalized = "";
25
+ }
26
+ if (!normalized.startsWith("/")) {
27
+ normalized = `/${normalized}`;
28
+ }
29
+ const match = normalized.match(/^\/catalog\/([^/]+)/i);
30
+ if (!match?.[1]) {
31
+ return undefined;
32
+ }
33
+ try {
34
+ return `catalog-${decodeURIComponent(match[1]).toLowerCase()}`;
35
+ }
36
+ catch {
37
+ return `catalog-${match[1].toLowerCase()}`;
38
+ }
39
+ }
40
+ enrichHrefAccessToken(item) {
41
+ const subItems = item.subItems?.map((subItem) => this.enrichHrefAccessToken(subItem));
42
+ const accessRightsToken = item.accessRightsToken || this.inferCatalogAccessToken(item.link);
43
+ return {
44
+ ...item,
45
+ accessRightsToken,
46
+ subItems
47
+ };
48
+ }
7
49
  /**
8
50
  * Get menu brand title
9
51
  *
@@ -95,26 +137,36 @@ export class MenuHelper {
95
137
  return [];
96
138
  }
97
139
  /**
98
- * Get list of entity menus that was not bound to groups
140
+ * Get list of ModelResource menus that was not bound to groups
99
141
  *
100
142
  * @returns {Array}
101
143
  */
102
144
  getMenuItems(user) {
103
145
  let menus = [];
146
+ const filtersDisabledGlobally = this.config.filters?.enabled === false;
104
147
  const staticLinks = this.config.navbar?.additionalLinks ?? [];
105
- staticLinks.forEach(function (additionalLink) {
148
+ staticLinks.forEach((additionalLink) => {
149
+ const additionalLinkPath = typeof additionalLink.link === "string"
150
+ ? additionalLink.link.replace(/\/+$/, "")
151
+ : "";
152
+ const isUserFiltersLink = additionalLink.id === "user-filters"
153
+ || additionalLinkPath.endsWith("/user-filters");
154
+ if (filtersDisabledGlobally && isUserFiltersLink) {
155
+ return;
156
+ }
106
157
  if (!additionalLink.link || !additionalLink.title || additionalLink.disabled) {
107
158
  return;
108
159
  }
160
+ const resolvedLink = this.enrichHrefAccessToken(additionalLink);
109
161
  menus.push({
110
- link: additionalLink.link,
111
- title: additionalLink.title,
112
- type: additionalLink.type,
113
- id: additionalLink.id || additionalLink.title.replace(" ", "_"),
114
- actions: additionalLink.subItems || null,
115
- icon: additionalLink.icon || null,
116
- accessRightsToken: additionalLink.accessRightsToken || null,
117
- section: additionalLink.section || 'Platform',
162
+ link: resolvedLink.link,
163
+ title: resolvedLink.title,
164
+ type: resolvedLink.type,
165
+ id: resolvedLink.id || resolvedLink.title.replace(" ", "_"),
166
+ actions: resolvedLink.subItems || null,
167
+ icon: resolvedLink.icon || null,
168
+ accessRightsToken: resolvedLink.accessRightsToken || null,
169
+ section: resolvedLink.section || 'Platform',
118
170
  });
119
171
  });
120
172
  if (this.config.models) {
@@ -140,9 +192,9 @@ export class MenuHelper {
140
192
  link: _this.config.routePrefix + '/model/' + key,
141
193
  title: val.title || key,
142
194
  icon: val.icon || null,
143
- actions: val.tools || null,
195
+ actions: val.tools ? val.tools.map((tool) => _this.enrichHrefAccessToken(tool)) : null,
144
196
  id: val.title ? val.title.replace(" ", "_") : key,
145
- entityName: key,
197
+ modelResourceName: key,
146
198
  accessRightsToken: `read-${key}-model`,
147
199
  section: val.navbar?.section || 'Platform',
148
200
  });
@@ -1,9 +1,8 @@
1
1
  import path from "path";
2
2
  import fs from "fs";
3
3
  import chalk from "chalk";
4
- import { isAdminizerViteDevMode } from "./runtimeMode.js";
5
4
  export function viteRender(routePrefix, assetName) {
6
- const isViteDev = isAdminizerViteDevMode();
5
+ const isViteDev = process.env.ADMINIZER_ENV === "dev";
7
6
  if (isViteDev) {
8
7
  return `/${assetName}`;
9
8
  }
package/index.d.ts CHANGED
@@ -14,10 +14,14 @@ export * from "./lib/media-manager/MediaManagerHandler";
14
14
  export * from "./controllers/media-manager/mediaManagerAdapter";
15
15
  export * from "./interfaces/adminpanelConfig";
16
16
  export * from "./interfaces/types";
17
+ export * from "./interfaces/queryCriteria";
18
+ export * from "./interfaces/listQueryBuilder";
19
+ export * from "./interfaces/internalModelAccess";
17
20
  export * from "./interfaces/MaaterialIcons";
18
21
  export * from "./lib/model/AbstractModel";
19
- export * from "./lib/model/adapter/waterline";
22
+ export * from "./lib/model/InternalModelAccessFactory";
20
23
  export * from "./lib/model/adapter/sequelize";
24
+ export * from "./lib/model/adapter/typeorm";
21
25
  export * from "./lib/media-manager/AbstractMediaManager";
22
26
  export * from "./lib/controls/AbstractControls";
23
27
  export * from "./lib/controls/ControlsHandler";
@@ -29,7 +33,6 @@ export * from "./models/MediaManagerAP";
29
33
  export * from "./models/MediaManagerAssociationsAP";
30
34
  export * from "./models/MediaManagerMetaAP";
31
35
  export * from "./models/NavigationAP";
32
- export * from "./migrations/index";
33
36
  export * from "./system/bindNavigation";
34
37
  export * from "./lib/helper/jwt";
35
38
  export * from "./lib/notifications/AbstractNotificationService";
@@ -37,5 +40,6 @@ export * from "./lib/POWCaptcha";
37
40
  export * from "./lib/ai-assistant/AbstractAiModelService";
38
41
  export * from "./lib/DataAccessor";
39
42
  export * from "./lib/history-actions/AbstractHistoryAdapter";
43
+ export * from "./lib/filters/CustomFilterHandler";
40
44
  export * from "./lib/feedback/AbstractFeedbackHandler";
41
45
  export * from "./lib/feedback/FeedbackHandler";
package/index.js CHANGED
@@ -14,10 +14,14 @@ export * from "./lib/media-manager/MediaManagerHandler.js";
14
14
  export * from "./controllers/media-manager/mediaManagerAdapter.js";
15
15
  export * from "./interfaces/adminpanelConfig.js";
16
16
  export * from "./interfaces/types.js";
17
+ export * from "./interfaces/queryCriteria.js";
18
+ export * from "./interfaces/listQueryBuilder.js";
19
+ export * from "./interfaces/internalModelAccess.js";
17
20
  export * from "./interfaces/MaaterialIcons.js";
18
21
  export * from "./lib/model/AbstractModel.js";
19
- export * from "./lib/model/adapter/waterline.js";
22
+ export * from "./lib/model/InternalModelAccessFactory.js";
20
23
  export * from "./lib/model/adapter/sequelize.js";
24
+ export * from "./lib/model/adapter/typeorm.js";
21
25
  export * from "./lib/media-manager/AbstractMediaManager.js";
22
26
  export * from "./lib/controls/AbstractControls.js";
23
27
  export * from "./lib/controls/ControlsHandler.js";
@@ -29,7 +33,6 @@ export * from "./models/MediaManagerAP.js";
29
33
  export * from "./models/MediaManagerAssociationsAP.js";
30
34
  export * from "./models/MediaManagerMetaAP.js";
31
35
  export * from "./models/NavigationAP.js";
32
- export * from "./migrations/index.js";
33
36
  export * from "./system/bindNavigation.js";
34
37
  export * from "./lib/helper/jwt.js";
35
38
  export * from "./lib/notifications/AbstractNotificationService.js";
@@ -37,5 +40,6 @@ export * from "./lib/POWCaptcha.js";
37
40
  export * from "./lib/ai-assistant/AbstractAiModelService.js";
38
41
  export * from "./lib/DataAccessor.js";
39
42
  export * from "./lib/history-actions/AbstractHistoryAdapter.js";
43
+ export * from "./lib/filters/CustomFilterHandler.js";
40
44
  export * from "./lib/feedback/AbstractFeedbackHandler.js";
41
45
  export * from "./lib/feedback/FeedbackHandler.js";
@@ -3,6 +3,7 @@ import { EditorOptions } from "@toast-ui/editor/types/editor";
3
3
  import { GridSettings as HandsontableSettings } from "handsontable/settings";
4
4
  import { GroupAP } from "../models/GroupAP";
5
5
  import { UserAP } from "../models/UserAP";
6
+ import { InternalModelAccessMap } from "./internalModelAccess";
6
7
  /**
7
8
  * Controller function type - async function that handles requests and returns a response
8
9
  */
@@ -13,9 +14,8 @@ export type FieldsTypes = "string" | "password" | "date" | "datetime" | "time" |
13
14
  * it will be needed only for polygon data
14
15
  */
15
16
  "geo-polygon";
16
- type SetFunction = (slug: string, key: string, data: any) => Promise<void>;
17
- type GetFunction = (slug: string, key: string) => Promise<any>;
18
17
  export type ActionType = "list" | "edit" | "add" | "remove" | "view";
18
+ export type ListPageSize = 5 | 20 | 50;
19
19
  interface DashboardConfig {
20
20
  autoloadWidgetsPath: string;
21
21
  /**
@@ -26,6 +26,13 @@ interface DashboardConfig {
26
26
  }
27
27
  export interface AdminpanelConfig {
28
28
  routePrefix: string;
29
+ list?: {
30
+ /**
31
+ * Default records count per list page.
32
+ * @default 50
33
+ */
34
+ defaultPageSize?: ListPageSize;
35
+ };
29
36
  /**
30
37
  * Custom favicon URL for admin pages.
31
38
  * - absolute URL is used as-is (`https://...`, `//...`, `data:...`)
@@ -103,7 +110,7 @@ export interface AdminpanelConfig {
103
110
  /**
104
111
  * Policies that will be executed before going to every page
105
112
  * */
106
- policies?: MiddlewareType[];
113
+ middlewares?: MiddlewareType[];
107
114
  styles?: string[];
108
115
  scripts?: {
109
116
  header?: string[];
@@ -133,34 +140,17 @@ export interface AdminpanelConfig {
133
140
  /**
134
141
  * Relative path from project root to translations folder
135
142
  * */
136
- path?: string;
137
- defaultLocale: string;
138
- } | false;
139
- /**
140
- * Forms
141
- * */
142
- forms?: {
143
+ directory?: string;
143
144
  /**
144
- * You can add forms directly to adminpanel configuration or put them in files with
145
- * `.json` extension which should be named as form slug. Put your forms in your
146
- * directory and write down path to it in `path` field.
147
- */
148
- path?: string;
149
- /**
150
- * same for model (need entity config types)
151
- * */
152
- data: {
153
- [key: string]: FieldsForms;
154
- };
155
- /**
156
- * Custom getter
145
+ * Relative path from project root to directory where missing translation keys are written in dev mode
157
146
  * */
158
- get?: GetFunction;
147
+ missingTranslationDirectory?: string;
159
148
  /**
160
- * Custom setter
161
- * */
162
- set?: SetFunction;
163
- };
149
+ * @deprecated use `directory`
150
+ */
151
+ path?: string;
152
+ defaultLocale: string;
153
+ } | false;
164
154
  /**
165
155
  * Prime administrator login credentials
166
156
  * */
@@ -217,6 +207,11 @@ export interface AdminpanelConfig {
217
207
  system?: {
218
208
  /** Default ORM adapter for system models */
219
209
  defaultORM: string;
210
+ /**
211
+ * Extra internal model access scopes for modules and project code.
212
+ * Built-in scopes are registered by Adminizer.
213
+ */
214
+ internalModelAccess?: InternalModelAccessMap;
220
215
  };
221
216
  bind?: {
222
217
  public: boolean;
@@ -244,6 +239,64 @@ export interface AdminpanelConfig {
244
239
  adapter?: string;
245
240
  excludeModels?: string[];
246
241
  };
242
+ /**
243
+ * Filter system configuration
244
+ */
245
+ filters?: {
246
+ /**
247
+ * Global enable/disable of the filter system
248
+ * @default true
249
+ */
250
+ enabled?: boolean;
251
+ };
252
+ /**
253
+ * Filter settings for specific models
254
+ * @deprecated Use model-level `models.<Model>.filters` instead
255
+ */
256
+ modelFilters?: {
257
+ [modelName: string]: ModelFiltersConfig;
258
+ };
259
+ }
260
+ /**
261
+ * Filter configuration for a specific model
262
+ */
263
+ export interface ModelFiltersConfig {
264
+ /**
265
+ * Enable filters for this model
266
+ * Works only when global filters.enabled is not false
267
+ * @default undefined (use global setting)
268
+ */
269
+ enabled?: boolean;
270
+ /**
271
+ * Use legacy search instead of filters
272
+ * @default false
273
+ */
274
+ useLegacySearch?: boolean;
275
+ /**
276
+ * Fields to exclude from auto-generated filters
277
+ * @example ['password', 'apiKey', 'token']
278
+ */
279
+ excludeFields?: string[];
280
+ /**
281
+ * Fields to include in auto-generated filters (whitelist mode)
282
+ * If specified, only these fields will have filters generated
283
+ * Takes priority over excludeFields
284
+ */
285
+ includeFields?: string[];
286
+ /**
287
+ * Fields to exclude from filter fields API
288
+ * Use this to hide specific fields from the filter UI
289
+ * @example ['password', 'apiKey', 'token', 'createdAt']
290
+ */
291
+ excludeFromFilters?: string[];
292
+ /**
293
+ * Custom field type overrides for filters
294
+ * Use this to change how a field appears in the filter UI
295
+ * @example { my_field: 'select' }
296
+ */
297
+ fieldTypes?: {
298
+ [fieldName: string]: string;
299
+ };
247
300
  }
248
301
  export interface ModelConfig {
249
302
  adapter?: string;
@@ -275,9 +328,13 @@ export interface ModelConfig {
275
328
  section?: string;
276
329
  };
277
330
  /**
278
- * Entity fields configuration
331
+ * Model resource fields configuration
279
332
  * */
280
333
  fields?: FieldsModels;
334
+ /**
335
+ * Filter settings for this model
336
+ */
337
+ filters?: ModelFiltersConfig;
281
338
  /**
282
339
  * List display configuration
283
340
  * */
@@ -321,11 +378,11 @@ export interface ModelConfig {
321
378
  * */
322
379
  view?: boolean;
323
380
  /**
324
- * Entity actions displayed in left navbar for specific entity
381
+ * Model resource actions displayed in left navbar for specific model resource
325
382
  * */
326
383
  tools?: HrefConfig[];
327
384
  /**
328
- * Entity icon
385
+ * Model resource icon
329
386
  * */
330
387
  icon?: MaterialIcon;
331
388
  /**
@@ -348,20 +405,12 @@ export interface ModelConfig {
348
405
  type UserWithGroups = UserAP & {
349
406
  groups: GroupAP[];
350
407
  };
351
- export interface FieldsForms {
352
- [key: string]: FormFieldConfig;
353
- }
354
408
  export type ModelFieldConfig = (BaseFieldConfig | TuiEditorFieldConfig) & {
355
409
  groupsAccessRights?: string[];
356
410
  };
357
411
  export interface FieldsModels {
358
412
  [key: string]: ModelFieldConfig;
359
413
  }
360
- interface FormFieldConfig extends BaseFieldConfig {
361
- value?: any;
362
- required?: boolean;
363
- description?: string;
364
- }
365
414
  export interface BaseFieldConfig {
366
415
  title?: string;
367
416
  type?: FieldsTypes;
@@ -396,6 +445,44 @@ export interface BaseFieldConfig {
396
445
  required?: boolean;
397
446
  /** show or hode element, default `true` */
398
447
  visible?: boolean;
448
+ /**
449
+ * Allow inline editing of this field in list view
450
+ * Inline editing is enabled by default for supported field types.
451
+ * Set to false to explicitly disable inline editing for this field.
452
+ */
453
+ inlineEditable?: boolean;
454
+ /**
455
+ * Validation rules for inline editing
456
+ * Applied when field is updated via inline edit
457
+ */
458
+ inlineValidation?: {
459
+ /** Minimum length for string fields */
460
+ minLength?: number;
461
+ /** Maximum length for string fields */
462
+ maxLength?: number;
463
+ /** Minimum value for number fields */
464
+ min?: number;
465
+ /** Maximum value for number fields */
466
+ max?: number;
467
+ /** Regex pattern for validation */
468
+ pattern?: string;
469
+ /** Custom validation function */
470
+ validate?: (value: any) => boolean | string;
471
+ };
472
+ /**
473
+ * Attach a custom filter handler to this field.
474
+ * Handler must be registered in Adminizer instance via `customFilterHandler`.
475
+ */
476
+ customFilter?: {
477
+ /**
478
+ * Handler ID in format "ModelName.fieldName"
479
+ */
480
+ handlerId: string;
481
+ /**
482
+ * @deprecated Condition label is taken from handler class `name`
483
+ */
484
+ label?: string;
485
+ };
399
486
  }
400
487
  export interface TuiEditorFieldConfig extends BaseFieldConfig {
401
488
  type: 'tui' | 'tuieditor' | 'toast-ui';
@@ -0,0 +1,37 @@
1
+ import { IsAny, QueryCriteria } from "./queryCriteria";
2
+ export type InternalModelAccessScope = string;
3
+ export type InternalModelAccessMap = Record<InternalModelAccessScope, string[]>;
4
+ export type InternalModelRelationId = string | number;
5
+ export type InternalModelWriteFieldValue<TValue> = NonNullable<TValue> extends Array<infer Item> ? Item extends {
6
+ id?: unknown;
7
+ } ? TValue | InternalModelRelationId[] : TValue : NonNullable<TValue> extends {
8
+ id?: unknown;
9
+ } ? TValue | InternalModelRelationId : TValue;
10
+ type RequiredFieldKeys<T> = {
11
+ [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
12
+ }[keyof T];
13
+ type OptionalFieldKeys<T> = {
14
+ [K in keyof T]-?: {} extends Pick<T, K> ? K : never;
15
+ }[keyof T];
16
+ export type InternalModelCreateData<T = any> = IsAny<T> extends true ? Record<string, any> : {
17
+ [K in RequiredFieldKeys<T>]: InternalModelWriteFieldValue<T[K]>;
18
+ } & {
19
+ [K in OptionalFieldKeys<T>]?: InternalModelWriteFieldValue<T[K]>;
20
+ };
21
+ export type InternalModelUpdateData<T = any> = IsAny<T> extends true ? Record<string, any> : {
22
+ [Field in keyof T]?: InternalModelWriteFieldValue<T[Field]>;
23
+ };
24
+ /** @deprecated Use `InternalModelCreateData` for create or `InternalModelUpdateData` for update. */
25
+ export type InternalModelWriteData<T = any> = InternalModelUpdateData<T>;
26
+ export interface InternalModelRepository<T = any> {
27
+ readonly name: string;
28
+ find(criteria?: QueryCriteria<T>): Promise<T[]>;
29
+ findOne(criteria?: QueryCriteria<T>): Promise<T | null>;
30
+ count(criteria?: QueryCriteria<T>): Promise<number>;
31
+ create(data: InternalModelCreateData<T>): Promise<T>;
32
+ update(criteria: QueryCriteria<T>, data: InternalModelUpdateData<T>): Promise<T[]>;
33
+ updateOne(criteria: QueryCriteria<T>, data: InternalModelUpdateData<T>): Promise<T | null>;
34
+ destroy(criteria: QueryCriteria<T>): Promise<T[]>;
35
+ destroyOne(criteria: QueryCriteria<T>): Promise<T | null>;
36
+ }
37
+ export {};
@@ -0,0 +1 @@
1
+ export {};