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.
- package/Readme.md +12 -0
- package/assets/RelationDialogStack-CnHFOYyR.css +1 -0
- package/assets/RelationDialogStack-DI2bZxQX.js +20 -0
- package/assets/add-DCQ7ZW4B.js +1 -0
- package/assets/add-group-DCVPryBo.js +1 -0
- package/assets/add-group-form-DKRXC2n-.js +1 -0
- package/assets/add-user-B7OOiYxv.js +1 -0
- package/assets/add-user-form-UXAToWQd.js +1 -0
- package/assets/app-AKbNCggP.css +1 -0
- package/assets/app-layout-6EwNBvnR.js +1 -0
- package/assets/app-shell-D8wtkECO.js +1 -0
- package/assets/app-sidebar-DfGjL-2K.js +1 -0
- package/assets/app-sidebar-header-BZbIBQjq.js +1 -0
- package/assets/app.js +59 -7990
- package/assets/breadcrumbs-CODaqVkB.js +1 -0
- package/assets/catalog-DVvFGa2X.js +6 -0
- package/assets/dashboard-BadoiH_a.js +3 -0
- package/assets/date-picker-DSOkNiNo.js +1 -0
- package/assets/del-modal-Cd4M7af8.js +1 -0
- package/assets/dynamic-controls-BsrJhPDY.js +1 -0
- package/assets/geo-json-CzR5JBXL.js +1 -0
- package/assets/handsontable-BI98OF5R.js +336 -0
- package/assets/history-D1iLA6rs.js +1 -0
- package/assets/home-DbWj-W_k.js +2 -0
- package/assets/icon-C2JNaLxH.js +1 -0
- package/assets/init-user-D2HSyXup.js +1 -0
- package/assets/input-error-CH2caTtO.js +1 -0
- package/assets/jsoneditor-DVNQmA6G.js +3869 -0
- package/assets/list-CVoljVUw.js +4 -0
- package/assets/login-DFSLEO17.js +1 -0
- package/assets/manifest.json +246 -273
- package/assets/material-icon-Bx9pGQiQ.js +1 -0
- package/assets/media-manager-WcKe1EvD.js +6 -0
- package/assets/module-DJsC37CM.js +1 -0
- package/assets/monaco-Bl4zdWCn.js +11 -0
- package/assets/nav-footer-BiSQkPt4.js +1 -0
- package/assets/nav-main-rTH0PfDw.js +1 -0
- package/assets/nav-user-Bj6cWs0a.js +1 -0
- package/assets/notification-DKrNfaAB.js +20 -0
- package/assets/pagination-render-AKJvTIRA.js +1 -0
- package/assets/register-BTP4uxsK.js +1 -0
- package/assets/ru-eW0WKkga.js +1 -0
- package/assets/theme-switcher-Dm8EOGzx.js +1 -0
- package/assets/toast-editor-DOg_gvSp.js +668 -0
- package/assets/user-filters-list-C9R9J6Om.js +1 -0
- package/assets/user-info-BgSbT02v.js +1 -0
- package/assets/user-menu-content-TQTXHIv6.js +1 -0
- package/assets/{vanilla-picker-l5rcX3cq.js → vanilla-picker-B3LgXoKV.js} +1 -7
- package/assets/welcome-BwDlAOGh.js +1 -0
- package/controllers/add.d.ts +1 -1
- package/controllers/add.js +20 -26
- package/controllers/addGroup.d.ts +1 -1
- package/controllers/addGroup.js +7 -15
- package/controllers/addUser.d.ts +1 -1
- package/controllers/addUser.js +10 -16
- package/controllers/catalog/Catalog.d.ts +1 -1
- package/controllers/catalog/Catalog.js +1 -10
- package/controllers/catalog/FrontendCatalogAdapter.d.ts +3 -3
- package/controllers/catalog/FrontendCatalogAdapter.js +0 -6
- package/controllers/catalog/FrontentCatalogAdapter.d.ts +3 -3
- package/controllers/catalog/FrontentCatalogAdapter.js +0 -4
- package/controllers/ckeditorUpload.js +2 -18
- package/controllers/dashboard.d.ts +1 -1
- package/controllers/dashboard.js +2 -5
- package/controllers/edit.js +24 -37
- package/controllers/editGroup.d.ts +1 -1
- package/controllers/editGroup.js +10 -21
- package/controllers/editUser.d.ts +1 -1
- package/controllers/editUser.js +11 -23
- package/controllers/exportData.d.ts +6 -0
- package/controllers/exportData.js +315 -0
- package/controllers/feed.d.ts +6 -0
- package/controllers/feed.js +73 -0
- package/controllers/feedback/feedbackController.d.ts +1 -1
- package/controllers/feedback/feedbackController.js +5 -7
- package/controllers/filter-fields/columns.d.ts +11 -0
- package/controllers/filter-fields/columns.js +106 -0
- package/controllers/filter-fields/filterFields.d.ts +10 -0
- package/controllers/filter-fields/filterFields.js +141 -0
- package/controllers/filter-fields/getAllUserFilters.d.ts +6 -0
- package/controllers/filter-fields/getAllUserFilters.js +115 -0
- package/controllers/filter-fields/groups.d.ts +5 -0
- package/controllers/filter-fields/groups.js +26 -0
- package/controllers/filter-fields/savedFilters.d.ts +25 -0
- package/controllers/filter-fields/savedFilters.js +317 -0
- package/controllers/getAllWidgets.d.ts +1 -1
- package/controllers/getAllWidgets.js +1 -9
- package/controllers/history-actions/HistoryController.js +6 -31
- package/controllers/initUser.js +6 -5
- package/controllers/inlineUpdate.d.ts +7 -0
- package/controllers/inlineUpdate.js +148 -0
- package/controllers/list.d.ts +1 -1
- package/controllers/list.js +383 -70
- package/controllers/listUserFilters.d.ts +5 -0
- package/controllers/listUserFilters.js +26 -0
- package/controllers/login.js +2 -2
- package/controllers/media-manager/mediaManagerApi.js +0 -9
- package/controllers/navigation/edit.js +3 -9
- package/controllers/notifications/NotificationController.d.ts +1 -1
- package/controllers/notifications/NotificationController.js +12 -36
- package/controllers/register.js +10 -9
- package/controllers/remove.js +10 -19
- package/controllers/timezones.d.ts +1 -1
- package/controllers/timezones.js +0 -6
- package/controllers/userApiKey.d.ts +7 -0
- package/controllers/userApiKey.js +36 -0
- package/controllers/view.js +14 -26
- package/controllers/welcome.d.ts +1 -1
- package/controllers/welcome.js +0 -4
- package/controllers/widgets/Action.d.ts +1 -1
- package/controllers/widgets/Action.js +1 -9
- package/controllers/widgets/Custom.d.ts +1 -1
- package/controllers/widgets/Custom.js +1 -9
- package/controllers/widgets/Info.d.ts +1 -1
- package/controllers/widgets/Info.js +1 -9
- package/controllers/widgets/filterInfo.d.ts +1 -0
- package/controllers/widgets/filterInfo.js +44 -0
- package/controllers/widgets/switch.d.ts +1 -1
- package/controllers/widgets/switch.js +1 -9
- package/controllers/widgetsDB.d.ts +1 -1
- package/controllers/widgetsDB.js +2 -8
- package/helpers/accessRightsHelper.d.ts +1 -1
- package/helpers/accessRightsHelper.js +5 -4
- package/helpers/apiKeyHelper.d.ts +5 -0
- package/helpers/apiKeyHelper.js +8 -0
- package/helpers/configHelper.js +12 -15
- package/helpers/controllerHelper.d.ts +14 -21
- package/helpers/controllerHelper.js +50 -83
- package/helpers/fieldsHelper.js +3 -3
- package/helpers/filterDatetimeHelper.d.ts +5 -0
- package/helpers/filterDatetimeHelper.js +84 -0
- package/helpers/inertiaActionsHelper.d.ts +2 -2
- package/helpers/inertiaActionsHelper.js +5 -4
- package/helpers/inertiaAddHelper.d.ts +3 -414
- package/helpers/inertiaAddHelper.js +39 -15
- package/helpers/inertiaGroupHelper.d.ts +2 -2
- package/helpers/inertiaGroupHelper.js +3 -3
- package/helpers/inertiaListHelper.d.ts +7 -3
- package/helpers/inertiaListHelper.js +26 -12
- package/helpers/inertiaMenuHelper.d.ts +1 -0
- package/helpers/inertiaMenuHelper.js +15 -3
- package/helpers/inertiaUserHelper.d.ts +3 -2
- package/helpers/inertiaUserHelper.js +7 -3
- package/helpers/menuHelper.d.ts +5 -2
- package/helpers/menuHelper.js +64 -12
- package/helpers/viteHelper.js +1 -2
- package/index.d.ts +6 -2
- package/index.js +6 -2
- package/interfaces/adminpanelConfig.d.ts +126 -39
- package/interfaces/internalModelAccess.d.ts +37 -0
- package/interfaces/internalModelAccess.js +1 -0
- package/interfaces/listQueryBuilder.d.ts +22 -0
- package/interfaces/listQueryBuilder.js +1 -0
- package/interfaces/queryCriteria.d.ts +54 -0
- package/interfaces/queryCriteria.js +1 -0
- package/interfaces/types.d.ts +1 -13
- package/lib/Adminizer.d.ts +4 -2
- package/lib/Adminizer.js +29 -10
- package/lib/DataAccessor.d.ts +8 -5
- package/lib/DataAccessor.js +89 -42
- package/lib/I18n.d.ts +5 -1
- package/lib/I18n.js +45 -19
- package/lib/MiddlewareManager.d.ts +8 -0
- package/lib/MiddlewareManager.js +53 -0
- package/lib/ai-assistant/OpenAiModelService.d.ts +3 -3
- package/lib/ai-assistant/OpenAiModelService.js +23 -24
- package/lib/catalog/Navigation.d.ts +1 -0
- package/lib/catalog/Navigation.js +12 -11
- package/lib/controls/jsoneditor/JsonEditor.d.ts +1 -2
- package/lib/controls/markdown/ToastUiEditor.d.ts +1 -2
- package/lib/feedback/FeedbackHandler.js +2 -2
- package/lib/filters/ConditionValidator.d.ts +107 -0
- package/lib/filters/ConditionValidator.js +483 -0
- package/lib/filters/CustomFilterHandler.d.ts +122 -0
- package/lib/filters/CustomFilterHandler.js +131 -0
- package/lib/filters/FilterCustomFieldHandler.d.ts +2 -0
- package/lib/filters/FilterCustomFieldHandler.js +2 -0
- package/lib/filters/FilterService.d.ts +82 -0
- package/lib/filters/FilterService.js +323 -0
- package/lib/filters/index.d.ts +6 -0
- package/lib/filters/index.js +4 -0
- package/lib/history-actions/AbstractHistoryAdapter.d.ts +5 -4
- package/lib/history-actions/AbstractHistoryAdapter.js +45 -30
- package/lib/history-actions/DefaultHistoryAdapter.d.ts +2 -0
- package/lib/history-actions/DefaultHistoryAdapter.js +12 -6
- package/lib/history-actions/HistoryHandler.js +1 -1
- package/lib/list-query-builder/ListQueryBuilder.d.ts +117 -0
- package/lib/list-query-builder/ListQueryBuilder.js +707 -0
- package/lib/media-manager/AbstractMediaManager.d.ts +9 -8
- package/lib/media-manager/DefaultMediaManager.d.ts +2 -0
- package/lib/media-manager/DefaultMediaManager.js +27 -15
- package/lib/media-manager/Items.d.ts +4 -1
- package/lib/media-manager/Items.js +62 -59
- package/lib/media-manager/MediaManagerHandler.js +1 -1
- package/lib/media-manager/helpers/MediaManagerHelper.d.ts +5 -1
- package/lib/media-manager/helpers/MediaManagerHelper.js +38 -4
- package/lib/model/AbstractModel.d.ts +33 -25
- package/lib/model/AbstractModel.js +54 -2
- package/lib/model/InternalModelAccessFactory.d.ts +18 -0
- package/lib/model/InternalModelAccessFactory.js +82 -0
- package/lib/model/ModelHandler.d.ts +6 -0
- package/lib/model/ModelHandler.js +14 -0
- package/lib/model/adapter/sequelize.d.ts +32 -10
- package/lib/model/adapter/sequelize.js +409 -62
- package/lib/model/adapter/typeorm.d.ts +62 -0
- package/lib/model/adapter/typeorm.js +777 -0
- package/lib/model/internalModelAccessToken.d.ts +1 -0
- package/lib/model/internalModelAccessToken.js +1 -0
- package/lib/model/internalModelRepository.d.ts +3 -0
- package/lib/model/internalModelRepository.js +4 -0
- package/lib/notifications/AbstractNotificationService.d.ts +3 -0
- package/lib/notifications/AbstractNotificationService.js +42 -36
- package/lib/notifications/GeneralNotificationService.js +37 -40
- package/lib/notifications/SystemNotificationService.js +33 -36
- package/lib/requestProcessor.js +0 -3
- package/lib/ui-i18n/getUiTranslations.d.ts +1 -0
- package/lib/ui-i18n/getUiTranslations.js +3 -0
- package/lib/ui-i18n/uiTranslationKeys.d.ts +6 -0
- package/lib/ui-i18n/uiTranslationKeys.js +268 -0
- package/lib/widgets/widgetHandler.d.ts +7 -2
- package/lib/widgets/widgetHandler.js +98 -18
- package/models/FilterAP.d.ts +116 -0
- package/models/FilterAP.js +68 -0
- package/models/FilterColumnAP.d.ts +32 -0
- package/models/FilterColumnAP.js +21 -0
- package/models/GroupAP.d.ts +1 -1
- package/models/HistoryActionsAP.d.ts +3 -3
- package/models/MediaManagerMetaAP.d.ts +1 -1
- package/models/NavigationAP.d.ts +1 -1
- package/models/UserAP.d.ts +6 -1
- package/models/UserAP.js +4 -0
- package/package.json +39 -32
- package/policies/authPolicies.d.ts +12 -0
- package/policies/authPolicies.js +104 -0
- package/policies/permissionResolvers.d.ts +12 -0
- package/policies/permissionResolvers.js +52 -0
- package/services/FeedService.d.ts +70 -0
- package/services/FeedService.js +334 -0
- package/system/Router.d.ts +1 -0
- package/system/Router.js +136 -59
- package/system/bindAccessRights.js +11 -30
- package/system/bindAuthorization.js +18 -18
- package/system/bindCors.js +16 -1
- package/system/bindCustomFilterHandlers.d.ts +2 -0
- package/system/bindCustomFilterHandlers.js +4 -0
- package/system/bindInertia.js +18 -61
- package/system/bindReqFunctions.js +10 -2
- package/system/bindTranslations.js +7 -3
- package/system/buildInternalModelAccess.d.ts +4 -0
- package/system/buildInternalModelAccess.js +59 -0
- package/system/defaults.js +18 -14
- package/system/routePolicies.d.ts +2 -0
- package/system/routePolicies.js +29 -0
- package/translations/en.json +151 -39
- package/translations/ru.json +211 -64
- package/ui/components/handsontable.js +13 -27
- package/ui/components/ui/dialog-stack.js +1 -3
- package/ui/components/ui/popover.js +1 -1
- package/ui/components/ui/sidebar.js +1 -1
- package/assets/RelationDialogStack-D9UVEF9s.js +0 -407
- package/assets/RelationDialogStack-DV8OITPR.css +0 -4
- package/assets/add-BlvzWQKF.js +0 -1
- package/assets/add-group-1Uoq9NWe.js +0 -1
- package/assets/add-group-form-B01gwDGu.js +0 -1
- package/assets/add-user-BQCAsaRy.js +0 -1
- package/assets/add-user-form-Cgwc9JkI.js +0 -1
- package/assets/app-DaOMy1nl.css +0 -72
- package/assets/app-layout-CAm60qoE.js +0 -1
- package/assets/app-shell-QWCtn9ye.js +0 -1
- package/assets/app-sidebar-CfaYbnSy.js +0 -1
- package/assets/app-sidebar-header-BsPFDhZ8.js +0 -1
- package/assets/breadcrumbs-CZZirDj8.js +0 -1
- package/assets/catalog-k5myk7fk.js +0 -6
- package/assets/dashboard-BkL9ybBw.js +0 -3
- package/assets/date-picker-B5AZ_7Q9.js +0 -1
- package/assets/del-modal-BoyXZloG.js +0 -1
- package/assets/dynamic-controls-k61T9W2P.js +0 -1
- package/assets/form-1WGY0YgG.js +0 -1
- package/assets/form-DJapG3qF.js +0 -1
- package/assets/geo-json-DsMUHo0l.js +0 -4
- package/assets/handsontable-PxYdjN8c.js +0 -298
- package/assets/history-CluyR-yJ.js +0 -1
- package/assets/home-Dug9zBzM.js +0 -2
- package/assets/icon-DfDLMG5f.js +0 -1
- package/assets/init-user-CF80MEnT.js +0 -1
- package/assets/input-error-DuuqFgZa.js +0 -1
- package/assets/jsoneditor-De1FvcYu.js +0 -3882
- package/assets/list-CuexshNt.js +0 -1
- package/assets/list-table-BsEWjTKY.js +0 -22
- package/assets/login-eDemYzN-.js +0 -1
- package/assets/material-icon-DMT8KdmE.js +0 -1
- package/assets/media-manager-DfYa_mT_.js +0 -14
- package/assets/module-Cd4Tm6uq.js +0 -1
- package/assets/monaco-BhBYtg3d.js +0 -11
- package/assets/nav-footer-D3olYxtz.js +0 -1
- package/assets/nav-main-BctqyzeV.js +0 -1
- package/assets/nav-user-Bn1Lt-BZ.js +0 -1
- package/assets/notification-D64qvni-.js +0 -27
- package/assets/pagination-render-DxD78ahJ.js +0 -1
- package/assets/register-349PwYbe.js +0 -1
- package/assets/theme-switcher-DfExsHW2.js +0 -1
- package/assets/toast-editor-ESK5iWPx.js +0 -845
- package/assets/user-info-DtBK5Kh8.js +0 -1
- package/assets/user-menu-content-0XYOCMaA.js +0 -1
- package/assets/welcome-PDp-gUei.js +0 -1
- package/controllers/form.d.ts +0 -1
- package/controllers/form.js +0 -86
- package/helpers/formHelper.d.ts +0 -6
- package/helpers/formHelper.js +0 -38
- package/helpers/inertiaFromHelper.d.ts +0 -11
- package/helpers/inertiaFromHelper.js +0 -98
- package/helpers/runtimeMode.d.ts +0 -1
- package/helpers/runtimeMode.js +0 -3
- package/lib/PolicyManager.d.ts +0 -8
- package/lib/PolicyManager.js +0 -53
- package/lib/datatable/NodeTable.d.ts +0 -49
- package/lib/datatable/NodeTable.js +0 -207
- package/lib/model/adapter/waterline.d.ts +0 -32
- package/lib/model/adapter/waterline.js +0 -180
- package/migrations/index.d.ts +0 -3
- package/migrations/index.js +0 -4
- package/migrations/knex/20250106000001_adminizer_init.d.ts +0 -8
- package/migrations/knex/20250106000001_adminizer_init.js +0 -164
- package/migrations/umzug/0001.d.ts +0 -7
- package/migrations/umzug/0001.js +0 -121
- package/migrations/umzugExports.d.ts +0 -2
- package/migrations/umzugExports.js +0 -9
- package/system/bindForms.d.ts +0 -2
- package/system/bindForms.js +0 -20
- /package/{policies → middlewares}/addMessages.d.ts +0 -0
- /package/{policies → middlewares}/addMessages.js +0 -0
- /package/{policies → middlewares}/checkAuth.d.ts +0 -0
- /package/{policies → middlewares}/checkAuth.js +0 -0
- /package/{policies → middlewares}/setLocale.d.ts +0 -0
- /package/{policies → middlewares}/setLocale.js +0 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import inertiaActionsHelper from "./inertiaActionsHelper.js";
|
|
2
|
-
export function inertiaListHelper(
|
|
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
|
-
|
|
15
|
-
name:
|
|
16
|
-
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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,
|
|
40
|
-
if (req.adminizer.menuHelper.hasInlineActions(
|
|
41
|
-
for (const inlineAction of req.adminizer.menuHelper.getInlineActions(
|
|
42
|
-
|
|
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
|
}
|
|
@@ -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
|
|
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,
|
|
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 {
|
|
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(
|
|
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(
|
|
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:
|
|
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 ? `${
|
|
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
|
}
|
package/helpers/menuHelper.d.ts
CHANGED
|
@@ -13,12 +13,15 @@ export type MenuItem = {
|
|
|
13
13
|
actions: HrefConfig[] | null;
|
|
14
14
|
icon: string | null;
|
|
15
15
|
accessRightsToken: string | null;
|
|
16
|
-
|
|
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
|
|
64
|
+
* Get list of ModelResource menus that was not bound to groups
|
|
62
65
|
*
|
|
63
66
|
* @returns {Array}
|
|
64
67
|
*/
|
package/helpers/menuHelper.js
CHANGED
|
@@ -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
|
|
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(
|
|
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:
|
|
111
|
-
title:
|
|
112
|
-
type:
|
|
113
|
-
id:
|
|
114
|
-
actions:
|
|
115
|
-
icon:
|
|
116
|
-
accessRightsToken:
|
|
117
|
-
section:
|
|
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
|
|
195
|
+
actions: val.tools ? val.tools.map((tool) => _this.enrichHrefAccessToken(tool)) : null,
|
|
144
196
|
id: val.title ? val.title.replace(" ", "_") : key,
|
|
145
|
-
|
|
197
|
+
modelResourceName: key,
|
|
146
198
|
accessRightsToken: `read-${key}-model`,
|
|
147
199
|
section: val.navbar?.section || 'Platform',
|
|
148
200
|
});
|
package/helpers/viteHelper.js
CHANGED
|
@@ -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 =
|
|
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/
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
137
|
-
defaultLocale: string;
|
|
138
|
-
} | false;
|
|
139
|
-
/**
|
|
140
|
-
* Forms
|
|
141
|
-
* */
|
|
142
|
-
forms?: {
|
|
143
|
+
directory?: string;
|
|
143
144
|
/**
|
|
144
|
-
*
|
|
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
|
-
|
|
147
|
+
missingTranslationDirectory?: string;
|
|
159
148
|
/**
|
|
160
|
-
*
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
381
|
+
* Model resource actions displayed in left navbar for specific model resource
|
|
325
382
|
* */
|
|
326
383
|
tools?: HrefConfig[];
|
|
327
384
|
/**
|
|
328
|
-
*
|
|
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 {};
|