adminizer 4.6.0 → 4.7.0-build.221
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-4213XScp.js +1 -0
- package/assets/add-group--F1XxfJ1.js +1 -0
- package/assets/add-group-form-DKRXC2n-.js +1 -0
- package/assets/add-user-b9HfMq7z.js +1 -0
- package/assets/add-user-form-UXAToWQd.js +1 -0
- package/assets/app-Clx8f5hd.css +1 -0
- package/assets/app-layout-C02ja4OI.js +1 -0
- package/assets/app-shell-D8wtkECO.js +1 -0
- package/assets/app-sidebar-BR5_zwxj.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-6ZZjWdFs.js +6 -0
- package/assets/dashboard-CftAdKiH.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-DLHSU7Ak.js +1 -0
- package/assets/home-NcQ7nnU0.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-CFU0-TgN.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-CT7PC6pc.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-Bi-PX87D.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-YUfR4XMI.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-vLwTu1R6.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
package/system/bindInertia.js
CHANGED
|
@@ -3,13 +3,20 @@ import inertia from "../lib/inertia/inertiaAdapter.js";
|
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { InertiaMenuHelper } from "../helpers/inertiaMenuHelper.js";
|
|
6
|
-
import {
|
|
6
|
+
import { getUiTranslations } from "../lib/ui-i18n/getUiTranslations.js";
|
|
7
|
+
import { COMMON_UI_TRANSLATION_KEYS } from "../lib/ui-i18n/uiTranslationKeys.js";
|
|
7
8
|
export function bindInertia(adminizer) {
|
|
8
9
|
const escapeHtmlAttribute = (value) => value
|
|
9
10
|
.replace(/&/g, "&")
|
|
10
11
|
.replace(/"/g, """)
|
|
11
12
|
.replace(/</g, "<")
|
|
12
13
|
.replace(/>/g, ">");
|
|
14
|
+
const serializePageForScript = (value) => JSON.stringify(value)
|
|
15
|
+
.replace(/</g, "\\u003c")
|
|
16
|
+
.replace(/>/g, "\\u003e")
|
|
17
|
+
.replace(/&/g, "\\u0026")
|
|
18
|
+
.replace(/\u2028/g, "\\u2028")
|
|
19
|
+
.replace(/\u2029/g, "\\u2029");
|
|
13
20
|
const resolveFaviconHref = () => {
|
|
14
21
|
const customFavicon = adminizer.config.favicon?.trim();
|
|
15
22
|
if (!customFavicon) {
|
|
@@ -24,7 +31,7 @@ export function bindInertia(adminizer) {
|
|
|
24
31
|
return `${adminizer.config.routePrefix}/${customFavicon.replace(/^\/+/, "")}`;
|
|
25
32
|
};
|
|
26
33
|
const viteRender = () => {
|
|
27
|
-
if (
|
|
34
|
+
if (process.env.ADMINIZER_ENV === 'dev') {
|
|
28
35
|
return `
|
|
29
36
|
<script type="module">
|
|
30
37
|
import RefreshRuntime from "/@react-refresh"
|
|
@@ -89,6 +96,7 @@ export function bindInertia(adminizer) {
|
|
|
89
96
|
};
|
|
90
97
|
const getHtml = (page, _viewData) => {
|
|
91
98
|
const faviconHref = escapeHtmlAttribute(resolveFaviconHref());
|
|
99
|
+
const serializedPage = serializePageForScript(page);
|
|
92
100
|
return `
|
|
93
101
|
<!DOCTYPE html><html lang="${_viewData.lang}">
|
|
94
102
|
<head>
|
|
@@ -98,12 +106,8 @@ export function bindInertia(adminizer) {
|
|
|
98
106
|
${viteRender()}
|
|
99
107
|
</head>
|
|
100
108
|
<body>
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
.replace(/</g, "<")
|
|
104
|
-
.replace(/>/g, ">")
|
|
105
|
-
.replace(/"/g, """)
|
|
106
|
-
.replace(/'/g, "'")}'></div>
|
|
109
|
+
<script data-page="app" type="application/json">${serializedPage}</script>
|
|
110
|
+
<div id="app"></div>
|
|
107
111
|
</body>
|
|
108
112
|
</html>
|
|
109
113
|
`;
|
|
@@ -128,8 +132,10 @@ export function bindInertia(adminizer) {
|
|
|
128
132
|
const defaultLocale = typeof req.adminizer.config.translation !== "boolean"
|
|
129
133
|
? req.adminizer.config.translation.defaultLocale
|
|
130
134
|
: "en";
|
|
135
|
+
const locale = req.user?.locale || defaultLocale;
|
|
136
|
+
const commonMessages = getUiTranslations(req, COMMON_UI_TRANSLATION_KEYS);
|
|
131
137
|
req.Inertia.setViewData({
|
|
132
|
-
lang:
|
|
138
|
+
lang: locale,
|
|
133
139
|
});
|
|
134
140
|
const menuHelper = new InertiaMenuHelper(adminizer);
|
|
135
141
|
req.Inertia.shareProps({
|
|
@@ -137,58 +143,9 @@ export function bindInertia(adminizer) {
|
|
|
137
143
|
user: req.session.userPretended ?? req.user
|
|
138
144
|
},
|
|
139
145
|
routePrefix: req.adminizer.config.routePrefix,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
Preview: req.i18n.__("Preview"),
|
|
144
|
-
Add: req.i18n.__("Add"),
|
|
145
|
-
Search: req.i18n.__("Search"),
|
|
146
|
-
Yes: req.i18n.__("Yes"),
|
|
147
|
-
No: req.i18n.__("No"),
|
|
148
|
-
On: req.i18n.__("On"),
|
|
149
|
-
Off: req.i18n.__("Off"),
|
|
150
|
-
Hide: req.i18n.__("Hide"),
|
|
151
|
-
Show: req.i18n.__("Show"),
|
|
152
|
-
"No notifications found": req.i18n.__("No notifications found"),
|
|
153
|
-
"No widgets found": req.i18n.__("No widgets found"),
|
|
154
|
-
"Changes not found": req.i18n.__("Changes not found"),
|
|
155
|
-
Old: req.i18n.__("Old"),
|
|
156
|
-
New: req.i18n.__("New"),
|
|
157
|
-
Added: req.i18n.__("Added"),
|
|
158
|
-
Removed: req.i18n.__("Removed"),
|
|
159
|
-
Updated: req.i18n.__("Updated"),
|
|
160
|
-
"changed type": req.i18n.__("changed type"),
|
|
161
|
-
"Error: Invalid field data": req.i18n.__("Error: Invalid field data"),
|
|
162
|
-
"Error: Fields data is invalid": req.i18n.__("Error: Fields data is invalid"),
|
|
163
|
-
"No fields to display": req.i18n.__("No fields to display"),
|
|
164
|
-
"Error: Some fields are missing required properties (name, type, label)": req.i18n.__("Error: Some fields are missing required properties (name, type, label)"),
|
|
165
|
-
Edit: req.i18n.__("Edit"),
|
|
166
|
-
create: req.i18n.__("create"),
|
|
167
|
-
Clean: req.i18n.__("Clean"),
|
|
168
|
-
"Are you sure?": req.i18n.__("Are you sure?"),
|
|
169
|
-
"Select Item type": req.i18n.__("Select Item type"),
|
|
170
|
-
"Select Ids": req.i18n.__("Select Ids"),
|
|
171
|
-
"Open in a new window": req.i18n.__("Open in a new window"),
|
|
172
|
-
Visible: req.i18n.__("Visible"),
|
|
173
|
-
"Performing an action...": req.i18n.__("Performing an action..."),
|
|
174
|
-
"Action completed": req.i18n.__("Action completed"),
|
|
175
|
-
Save: req.i18n.__("Save"),
|
|
176
|
-
First: req.i18n.__("First"),
|
|
177
|
-
Last: req.i18n.__("Last"),
|
|
178
|
-
Previous: req.i18n.__("Previous"),
|
|
179
|
-
Next: req.i18n.__("Next"),
|
|
180
|
-
"Send feedback": req.i18n.__("Send feedback"),
|
|
181
|
-
"Feedback": req.i18n.__("Feedback"),
|
|
182
|
-
"Title": req.i18n.__("Title"),
|
|
183
|
-
"Description": req.i18n.__("Description"),
|
|
184
|
-
"Attach files": req.i18n.__("Attach files"),
|
|
185
|
-
"Send": req.i18n.__("Send"),
|
|
186
|
-
"Sending...": req.i18n.__("Sending..."),
|
|
187
|
-
"Feedback sent successfully": req.i18n.__("Feedback sent successfully"),
|
|
188
|
-
"Title is required": req.i18n.__("Title is required"),
|
|
189
|
-
"File size exceeds the 5 MB limit": req.i18n.__("File size exceeds the 5 MB limit"),
|
|
190
|
-
"Remove file": req.i18n.__("Remove file"),
|
|
191
|
-
"Max 5 MB per file": req.i18n.__("Max 5 MB per file"),
|
|
146
|
+
i18n: {
|
|
147
|
+
locale,
|
|
148
|
+
common: commonMessages,
|
|
192
149
|
},
|
|
193
150
|
menu: req.user ? menuHelper.getMenuItems(req) : null,
|
|
194
151
|
title: menuHelper.getBrandTitle(),
|
|
@@ -13,9 +13,16 @@ export default function bindReqFunctions(adminizer) {
|
|
|
13
13
|
* */
|
|
14
14
|
const hasExternalI18n = typeof req.i18n?.__ === "function";
|
|
15
15
|
if (!hasExternalI18n) {
|
|
16
|
+
const translationDirectory = adminizer.config.translation !== false
|
|
17
|
+
? adminizer.config.translation.directory ?? adminizer.config.translation.path
|
|
18
|
+
: null;
|
|
19
|
+
const missingTranslationDirectory = adminizer.config.translation !== false
|
|
20
|
+
? adminizer.config.translation.missingTranslationDirectory
|
|
21
|
+
: null;
|
|
16
22
|
req.i18n = new I18n({
|
|
17
23
|
locales: adminizer.config.translation !== false ? adminizer.config.translation.locales : [],
|
|
18
|
-
directory:
|
|
24
|
+
directory: translationDirectory ?? null,
|
|
25
|
+
missingDirectory: missingTranslationDirectory ?? null
|
|
19
26
|
});
|
|
20
27
|
}
|
|
21
28
|
if (res.locals) {
|
|
@@ -39,7 +46,8 @@ export default function bindReqFunctions(adminizer) {
|
|
|
39
46
|
if (token) {
|
|
40
47
|
const user = verifyUser(token, req.adminizer.jwtSecret);
|
|
41
48
|
if (user) {
|
|
42
|
-
|
|
49
|
+
// Load user with groups (Sequelize adapter auto-populates associations in _findOne)
|
|
50
|
+
req.user = await req.adminizer.modelHandler.internal("auth").get("UserAP").findOne({ where: { id: user.id } });
|
|
43
51
|
}
|
|
44
52
|
}
|
|
45
53
|
if (req.session.userPretended) {
|
|
@@ -10,11 +10,15 @@ export default function bindTranslations(adminizer) {
|
|
|
10
10
|
}
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const translationsDirectory = adminizer.config.translation.directory ?? adminizer.config.translation.path;
|
|
14
|
+
if (!translationsDirectory) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (fs.existsSync(translationsDirectory)) {
|
|
18
|
+
let translationsDir = fs.readdirSync(translationsDirectory);
|
|
15
19
|
if (translationsDir.length) {
|
|
16
20
|
// load project translations
|
|
17
|
-
TranslationHelper.loadTranslations(adminizer, `${process.cwd()}/${
|
|
21
|
+
TranslationHelper.loadTranslations(adminizer, `${process.cwd()}/${translationsDirectory}`);
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AdminpanelConfig } from "../interfaces/adminpanelConfig";
|
|
2
|
+
import { InternalModelAccessMap } from "../interfaces/internalModelAccess";
|
|
3
|
+
import { ModelHandler } from "../lib/model/ModelHandler";
|
|
4
|
+
export declare function buildInternalModelAccess(config: AdminpanelConfig, modelHandler: ModelHandler): InternalModelAccessMap | undefined;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export function buildInternalModelAccess(config, modelHandler) {
|
|
2
|
+
const accessMap = config.system?.internalModelAccess;
|
|
3
|
+
const dynamicAccessMap = {};
|
|
4
|
+
addInternalAccessModels(dynamicAccessMap, "navigation", getNavigationInternalModels(config));
|
|
5
|
+
addInternalAccessModels(dynamicAccessMap, "data-accessor", getDataAccessorInternalModels(config, modelHandler));
|
|
6
|
+
addInternalAccessModels(dynamicAccessMap, "history", getHistoryInternalModels(config, modelHandler));
|
|
7
|
+
if (!Object.keys(dynamicAccessMap).length) {
|
|
8
|
+
return accessMap;
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
...(accessMap ?? {}),
|
|
12
|
+
...Object.fromEntries(Object.entries(dynamicAccessMap).map(([scope, models]) => [
|
|
13
|
+
scope,
|
|
14
|
+
[...(accessMap?.[scope] ?? []), ...models]
|
|
15
|
+
]))
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function addInternalAccessModels(accessMap, scope, models) {
|
|
19
|
+
if (!models.length) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
accessMap[scope] = Array.from(new Set(models));
|
|
23
|
+
}
|
|
24
|
+
function getNavigationInternalModels(config) {
|
|
25
|
+
if (!config.navigation) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
const models = [
|
|
29
|
+
config.navigation.model ?? "NavigationAP",
|
|
30
|
+
...config.navigation.items
|
|
31
|
+
.map(item => item.model)
|
|
32
|
+
.filter((model) => Boolean(model))
|
|
33
|
+
];
|
|
34
|
+
return Array.from(new Set(models));
|
|
35
|
+
}
|
|
36
|
+
function getDataAccessorInternalModels(config, modelHandler) {
|
|
37
|
+
const models = [];
|
|
38
|
+
for (const [modelName, modelConfig] of Object.entries(config.models ?? {})) {
|
|
39
|
+
if (!modelConfig || typeof modelConfig !== "object" || Array.isArray(modelConfig)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const userAccessRelation = modelConfig.userAccessRelation;
|
|
43
|
+
if (!userAccessRelation || typeof userAccessRelation !== "object" || Array.isArray(userAccessRelation)) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const model = modelHandler.model.get(modelName);
|
|
47
|
+
const intermediateModelName = model?.attributes?.[userAccessRelation.field]?.model;
|
|
48
|
+
if (intermediateModelName) {
|
|
49
|
+
models.push(intermediateModelName);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Array.from(new Set(models));
|
|
53
|
+
}
|
|
54
|
+
function getHistoryInternalModels(config, modelHandler) {
|
|
55
|
+
if (!config.history?.enabled) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
return Array.from(new Set(modelHandler.model.keys()));
|
|
59
|
+
}
|
package/system/defaults.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
import { FileStorageHelper } from "../helpers/fileStorageHelper.js";
|
|
3
2
|
import timezones from "../lib/timezones.js";
|
|
4
3
|
import addUser from "../controllers/addUser.js";
|
|
5
4
|
import editUser from "../controllers/editUser.js";
|
|
@@ -11,6 +10,9 @@ import editGroup from "../controllers/editGroup.js";
|
|
|
11
10
|
let adminpanelConfig = {
|
|
12
11
|
/** Default route prefix */
|
|
13
12
|
routePrefix: '/adminizer',
|
|
13
|
+
list: {
|
|
14
|
+
defaultPageSize: 50
|
|
15
|
+
},
|
|
14
16
|
/**
|
|
15
17
|
* Name of model identifier field
|
|
16
18
|
*/
|
|
@@ -18,13 +20,22 @@ let adminpanelConfig = {
|
|
|
18
20
|
/**
|
|
19
21
|
* Policies
|
|
20
22
|
*/
|
|
21
|
-
|
|
23
|
+
middlewares: [],
|
|
22
24
|
/**
|
|
23
25
|
* Base navbar configuration
|
|
24
26
|
*/
|
|
25
27
|
navbar: {
|
|
26
28
|
// List of additional actions
|
|
27
|
-
additionalLinks: [
|
|
29
|
+
additionalLinks: [
|
|
30
|
+
{
|
|
31
|
+
link: '/adminizer/user-filters',
|
|
32
|
+
title: 'User Filters',
|
|
33
|
+
id: 'user-filters',
|
|
34
|
+
icon: 'filter_list',
|
|
35
|
+
section: 'System',
|
|
36
|
+
type: 'self'
|
|
37
|
+
}
|
|
38
|
+
]
|
|
28
39
|
},
|
|
29
40
|
brand: {
|
|
30
41
|
link: null
|
|
@@ -102,19 +113,9 @@ let adminpanelConfig = {
|
|
|
102
113
|
},
|
|
103
114
|
translation: {
|
|
104
115
|
locales: ['en', 'ru'],
|
|
105
|
-
|
|
116
|
+
directory: `config/locales/adminpanel`,
|
|
106
117
|
defaultLocale: 'en'
|
|
107
118
|
},
|
|
108
|
-
forms: {
|
|
109
|
-
path: `api/adminpanel-forms`,
|
|
110
|
-
data: {},
|
|
111
|
-
get: async function (slug, key) {
|
|
112
|
-
return FileStorageHelper.get(slug, key);
|
|
113
|
-
},
|
|
114
|
-
set: async function (slug, key, value) {
|
|
115
|
-
FileStorageHelper.set(slug, key, value);
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
119
|
/**
|
|
119
120
|
* List of sections in head
|
|
120
121
|
*/
|
|
@@ -166,6 +167,9 @@ let adminpanelConfig = {
|
|
|
166
167
|
},
|
|
167
168
|
mediamanager: {
|
|
168
169
|
fileStoragePath: '.tmp/public',
|
|
170
|
+
},
|
|
171
|
+
filters: {
|
|
172
|
+
enabled: false
|
|
169
173
|
}
|
|
170
174
|
};
|
|
171
175
|
export function setDefaultConfig(config) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function composePolicies(action, guards) {
|
|
2
|
+
return async (req, res, next) => {
|
|
3
|
+
try {
|
|
4
|
+
for (const guard of guards) {
|
|
5
|
+
let shouldContinue = false;
|
|
6
|
+
const guardNext = ((error) => {
|
|
7
|
+
if (error) {
|
|
8
|
+
throw error;
|
|
9
|
+
}
|
|
10
|
+
shouldContinue = true;
|
|
11
|
+
});
|
|
12
|
+
await Promise.resolve(guard(req, res, guardNext));
|
|
13
|
+
if (!shouldContinue || res.headersSent) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return action(req, res, next);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return next(error);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function bindWithMiddlewares(adminizer, middlewares, action, policies = []) {
|
|
25
|
+
if (!policies.length) {
|
|
26
|
+
return adminizer.middlewareManager.bindMiddlewares(middlewares, action);
|
|
27
|
+
}
|
|
28
|
+
return adminizer.middlewareManager.bindMiddlewares(middlewares, composePolicies(action, policies));
|
|
29
|
+
}
|
package/translations/en.json
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"Create a new administrator": "Create a new administrator",
|
|
14
14
|
"Create an Account": "Create an Account",
|
|
15
15
|
"Custom": "Custom",
|
|
16
|
+
"Custom filtering": "Custom filtering",
|
|
16
17
|
"Delete": "Delete",
|
|
17
18
|
"E-mail": "E-mail",
|
|
18
19
|
"Edit": "Edit",
|
|
@@ -153,45 +154,156 @@
|
|
|
153
154
|
"Current": "Current",
|
|
154
155
|
"There is no history": "There is no history",
|
|
155
156
|
"The end of the list has been reached": "The end of the list has been reached",
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"
|
|
157
|
+
"Filters": "Filters",
|
|
158
|
+
"Saved filters": "Saved filters",
|
|
159
|
+
"Active filter": "Active filter",
|
|
160
|
+
"Add filter": "Add filter",
|
|
161
|
+
"Reset filter": "Reset filter",
|
|
162
|
+
"Equal": "equal",
|
|
163
|
+
"Not equal": "not equal",
|
|
164
|
+
"Contains": "contains",
|
|
165
|
+
"Starts with": "starts with",
|
|
166
|
+
"Ends with": "ends with",
|
|
167
|
+
"Is empty": "is empty",
|
|
168
|
+
"Is not empty": "is not empty",
|
|
169
|
+
"Greater than": "greater than",
|
|
170
|
+
"Greater or equal": "greater or equal",
|
|
171
|
+
"Less than": "less than",
|
|
172
|
+
"Less or equal": "less or equal",
|
|
173
|
+
"Between": "between",
|
|
174
|
+
"Today": "today",
|
|
175
|
+
"Month": "month",
|
|
176
|
+
"Year": "year",
|
|
177
|
+
"Month range": "month range",
|
|
178
|
+
"Year range": "year range",
|
|
179
|
+
"After": "after",
|
|
180
|
+
"After or equal": "after or equal",
|
|
181
|
+
"Before": "before",
|
|
182
|
+
"Before or equal": "before or equal",
|
|
183
|
+
"In list": "in list",
|
|
184
|
+
"Not in list": "not in list",
|
|
185
|
+
"Is null": "is null",
|
|
186
|
+
"Is not null": "is not null",
|
|
187
|
+
"From": "From",
|
|
188
|
+
"To": "To",
|
|
189
|
+
"From...": "From...",
|
|
190
|
+
"To...": "To...",
|
|
191
|
+
"Date...": "Date...",
|
|
192
|
+
"Value...": "Value...",
|
|
193
|
+
"Select...": "Select...",
|
|
194
|
+
"selected": "selected",
|
|
195
|
+
"Search...": "Search...",
|
|
196
|
+
"No results": "No results",
|
|
197
|
+
"Enter filter name": "Enter filter name",
|
|
198
|
+
"Temporary filter": "Temporary filter",
|
|
199
|
+
"Error: model not found": "Error: model not found",
|
|
200
|
+
"Error loading columns": "Error loading columns",
|
|
201
|
+
"Network error": "Network error",
|
|
202
|
+
"Columns settings": "Columns settings",
|
|
203
|
+
"Available columns": "Available columns",
|
|
204
|
+
"Visible columns": "Visible columns",
|
|
205
|
+
"Add all": "Add all",
|
|
206
|
+
"Hide all": "Hide all",
|
|
207
|
+
"No available columns": "No available columns",
|
|
208
|
+
"Move columns here": "Move columns here",
|
|
209
|
+
"Save changes": "Save changes",
|
|
210
|
+
"Apply": "Apply",
|
|
211
|
+
"Cancel": "Cancel",
|
|
212
|
+
"conditions": "conditions",
|
|
213
|
+
"modified": "modified",
|
|
214
|
+
"Private filter": "Private filter",
|
|
215
|
+
"For groups": "Filter for groups",
|
|
216
|
+
"Public filter": "Public filter",
|
|
217
|
+
"Only for you": "Only for you",
|
|
218
|
+
"For selected groups": "For selected groups",
|
|
219
|
+
"For all users": "For all users",
|
|
220
|
+
"Visible only to you": "Visible only to you",
|
|
221
|
+
"Visible only to your group": "Visible only to your group",
|
|
222
|
+
"API access (feed)": "API access (feed)",
|
|
159
223
|
"Hide": "Hide",
|
|
160
224
|
"Show": "Show",
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
"
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
"
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
183
|
-
"
|
|
184
|
-
"
|
|
185
|
-
"
|
|
186
|
-
"
|
|
187
|
-
"
|
|
188
|
-
"
|
|
189
|
-
"
|
|
190
|
-
"
|
|
191
|
-
"
|
|
192
|
-
"
|
|
193
|
-
"
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
"
|
|
225
|
+
"Regenerate": "Regenerate",
|
|
226
|
+
"copied to clipboard": "copied to clipboard",
|
|
227
|
+
"Failed to copy": "Failed to copy",
|
|
228
|
+
"Loading filters...": "Loading filters...",
|
|
229
|
+
"No saved filters": "No saved filters",
|
|
230
|
+
"Save current filter for quick access": "Save current filter for quick access",
|
|
231
|
+
"Someone else's private filter (owner:": "Someone else's private filter (owner:",
|
|
232
|
+
"unknown)": "unknown)",
|
|
233
|
+
"Owner": "Owner",
|
|
234
|
+
"Apply filter": "Apply filter",
|
|
235
|
+
"Delete filter": "Delete filter",
|
|
236
|
+
"No permission to delete filter": "No permission to delete filter",
|
|
237
|
+
"Edit filter": "Edit filter",
|
|
238
|
+
"New filter": "New filter",
|
|
239
|
+
"Filter conditions": "Filter conditions",
|
|
240
|
+
"Add condition": "Add condition",
|
|
241
|
+
"Select field": "Select field",
|
|
242
|
+
"No conditions. Add a condition above.": "No conditions. Add a condition above.",
|
|
243
|
+
"Description": "Description",
|
|
244
|
+
"Icon": "Icon",
|
|
245
|
+
"Color": "Color",
|
|
246
|
+
"Filter parameters": "Filter parameters",
|
|
247
|
+
"Change filter conditions and parameters": "Change filter conditions and parameters",
|
|
248
|
+
"Configure filter conditions": "Configure filter conditions",
|
|
249
|
+
"Specify name and parameters for saving": "Specify name and parameters for saving",
|
|
250
|
+
"Someone else's private filter": "Someone else's private filter",
|
|
251
|
+
"You cannot change someone else's filter visibility": "You cannot change someone else's filter visibility",
|
|
252
|
+
"Private": "Private",
|
|
253
|
+
"Public": "Public",
|
|
254
|
+
"Visibility": "Filter visibility",
|
|
255
|
+
"Export": "Export",
|
|
256
|
+
"Exporting...": "Exporting...",
|
|
257
|
+
"Export is only available with an active filter": "Export is only available with an active filter",
|
|
258
|
+
"Export to": "Export to",
|
|
259
|
+
"completed": "completed",
|
|
260
|
+
"Export error": "Export error",
|
|
261
|
+
"Conditions": "Conditions",
|
|
262
|
+
"Access for groups": "Access for groups",
|
|
263
|
+
"Selected groups": "Selected groups",
|
|
264
|
+
"Groups list": "Groups list",
|
|
265
|
+
"Columns": "Columns",
|
|
266
|
+
"Saving...": "Saving...",
|
|
267
|
+
"Error saving filter": "Error saving filter",
|
|
268
|
+
"Column configuration": "Column configuration",
|
|
269
|
+
"Select and arrange columns to display in the table": "Select and arrange columns to display in the table",
|
|
270
|
+
"Loading columns...": "Loading columns...",
|
|
271
|
+
"Use buttons": "Use buttons",
|
|
272
|
+
"to move and": "to move and",
|
|
273
|
+
"to change order": "to change order",
|
|
274
|
+
"Not contains": "not contains",
|
|
275
|
+
"Data in JSON format": "Data in JSON format",
|
|
276
|
+
"Text format CSV": "Text format CSV",
|
|
277
|
+
"Excel file": "Excel file",
|
|
278
|
+
"Select a saved filter or create a new one": "Select a saved filter or create a new one",
|
|
279
|
+
"Select a filter or create a new one": "Select a filter or create a new one",
|
|
280
|
+
"Filter visibility": "Filter visibility",
|
|
281
|
+
"Unknown": "Unknown",
|
|
282
|
+
"JSON URL": "JSON URL",
|
|
283
|
+
"XML URL": "XML URL",
|
|
284
|
+
"API key is not created": "API key is not created",
|
|
285
|
+
"The key is not created. Create it or contact an administrator.": "The key is not created. Create it or contact an administrator.",
|
|
286
|
+
"OK": "OK",
|
|
287
|
+
"Add": "Add",
|
|
288
|
+
"Save filter": "Save filter",
|
|
289
|
+
"and": "and",
|
|
290
|
+
"Error": "Error",
|
|
291
|
+
"Error applying filter": "Error applying filter",
|
|
292
|
+
"Model not found": "Model not found",
|
|
293
|
+
"Unauthorized": "Unauthorized",
|
|
294
|
+
"Forbidden": "Forbidden",
|
|
295
|
+
"Conditions are required": "Conditions are required",
|
|
296
|
+
"Filter name is required": "Filter name is required",
|
|
297
|
+
"Filter conditions are required": "Filter conditions are required",
|
|
298
|
+
"Filter with this name already exists": "Filter with this name already exists",
|
|
299
|
+
"Filter not found": "Filter not found",
|
|
300
|
+
"Failed to save filter": "Failed to save filter",
|
|
301
|
+
"Filter ID is required": "Filter ID is required",
|
|
302
|
+
"Failed to delete filter": "Failed to delete filter",
|
|
303
|
+
"Columns array is required": "Columns array is required",
|
|
304
|
+
"Filter not found or access denied": "Filter not found or access denied",
|
|
305
|
+
"Failed to update filter columns": "Failed to update filter columns",
|
|
306
|
+
"GroupAP model not found": "GroupAP model not found",
|
|
307
|
+
"Failed to load groups": "Failed to load groups",
|
|
308
|
+
"Internal server error": "Internal server error"
|
|
197
309
|
}
|