adminizer 4.2.0 → 4.3.0-build.100
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/assets/add-1E1UsMVZ.js +1 -0
- package/assets/add-form-CGa9QbwE.js +1 -0
- package/assets/add-group-7yAK6uFY.js +1 -0
- package/assets/add-group-form-BNmpvW8K.js +1 -0
- package/assets/add-user-NoYkTfZi.js +1 -0
- package/assets/add-user-form-DrclnTOd.js +1 -0
- package/assets/{app-CVnUv8s_.css → app-D8oqdt8J.css} +1 -1
- package/assets/app-layout-i2zN9Rn-.js +1 -0
- package/assets/app-shell-CHEYhVco.js +1 -0
- package/assets/app-sidebar-DeF8WNmW.js +1 -0
- package/assets/app-sidebar-header-DdM1EOrb.js +1 -0
- package/assets/app.js +1699 -1657
- package/assets/breadcrumbs-C439DWrC.js +1 -0
- package/assets/catalog-B9hdop59.js +6 -0
- package/assets/dashboard-Bi5KeZu2.js +3 -0
- package/assets/date-picker-DbJ8nHp5.js +1 -0
- package/assets/del-modal-_b3CSNHb.js +1 -0
- package/assets/dynamic-controls-BOYmRX_z.js +1 -0
- package/assets/field-renderer-4obZ_jUo.js +407 -0
- package/assets/{field-renderer-CsBa_tMB.css → field-renderer-CRNLShJD.css} +1 -1
- package/assets/form-Bte5kzjB.js +1 -0
- package/assets/form-oUlsuu7h.js +1 -0
- package/assets/geo-json-CadjdhwW.js +4 -0
- package/assets/handsontable-PVakPtJV.js +281 -0
- package/assets/home-CsUXA-O6.js +2 -0
- package/assets/icon-DM49pZW3.js +1 -0
- package/assets/init-user-DNrB8Xt5.js +1 -0
- package/assets/input-error--IOnWghB.js +1 -0
- package/assets/jsoneditor-D95dIAP2.js +3878 -0
- package/assets/list-CdfSnSN1.js +1 -0
- package/assets/list-table-Byzv346I.js +22 -0
- package/assets/login-6Xb8bcPq.js +1 -0
- package/assets/manifest.json +331 -221
- package/assets/material-icon-BedgD2NE.js +1 -0
- package/assets/media-manager-UQT6RhI8.js +14 -0
- package/assets/module-B4-7WkY5.js +1 -0
- package/assets/monaco-ICtx6xoc.js +11 -0
- package/assets/nav-footer-BwkQkwow.js +1 -0
- package/assets/nav-main-9Eb_A0rf.js +1 -0
- package/assets/nav-user-CRAfyE-x.js +1 -0
- package/assets/notification-ma2x7vka.js +27 -0
- package/assets/pagination-render-xsEktzA8.js +1 -0
- package/assets/register-BIyjCy8M.js +1 -0
- package/assets/tabs-BK_5wdPA.js +1 -0
- package/assets/theme-switcher-CKiJbMkh.js +1 -0
- package/assets/toast-editor-BZM5RHph.js +845 -0
- package/assets/user-info-CcYdmjMZ.js +1 -0
- package/assets/user-menu-content-DbUk8ZeY.js +1 -0
- package/assets/vanilla-picker-l5rcX3cq.js +8 -0
- package/assets/vendor-wzZzN_Jv.js +17 -0
- package/assets/welcome-cWh1qnl_.js +1 -0
- package/controllers/add.js +1 -1
- package/controllers/catalog/FrontentCatalogAdapter.d.ts +4 -4
- package/controllers/ckeditorUpload.d.ts +1 -1
- package/controllers/ckeditorUpload.js +50 -26
- package/controllers/edit.js +2 -2
- package/controllers/form.js +28 -13
- package/controllers/list.js +2 -2
- package/controllers/login.js +2 -2
- package/controllers/media-manager/mediaManagerAdapter.js +13 -2
- package/controllers/media-manager/mediaManagerApi.js +4 -3
- package/controllers/navigation/edit.js +1 -1
- package/controllers/notifications/NotificationController.d.ts +11 -0
- package/controllers/notifications/NotificationController.js +219 -0
- package/controllers/remove.js +2 -1
- package/controllers/view.js +1 -1
- package/files/favicon.png +0 -0
- package/helpers/configHelper.d.ts +1 -1
- package/helpers/controllerHelper.js +1 -1
- package/helpers/diffHelpers.d.ts +2 -0
- package/helpers/diffHelpers.js +69 -0
- package/helpers/fieldsHelper.d.ts +1 -1
- package/helpers/fieldsHelper.js +1 -1
- package/helpers/formHelper.js +3 -1
- package/helpers/inertiaAddHelper.d.ts +1 -1
- package/helpers/inertiaAutHelper.js +19 -0
- package/helpers/inertiaFromHelper.js +12 -0
- package/helpers/translationHelper.d.ts +1 -1
- package/helpers/translationHelper.js +1 -1
- package/index.d.ts +16 -14
- package/index.js +16 -14
- package/interfaces/adminpanelConfig.d.ts +18 -0
- package/interfaces/global.d.ts +3 -3
- package/interfaces/types.d.ts +44 -2
- package/lib/Adminizer.d.ts +16 -8
- package/lib/Adminizer.js +95 -12
- package/lib/{v4/DataAccessor.d.ts → DataAccessor.d.ts} +5 -5
- package/lib/{v4/DataAccessor.js → DataAccessor.js} +3 -3
- package/lib/{v4/I18n.js → I18n.js} +2 -2
- package/lib/{v4/PolicyManager.d.ts → PolicyManager.d.ts} +1 -1
- package/lib/{v4/PolicyManager.js → PolicyManager.js} +2 -2
- package/lib/{v4/catalog → catalog}/AbstractCatalog.d.ts +1 -1
- package/lib/{v4/catalog → catalog}/Navigation.d.ts +2 -2
- package/lib/{v4/catalog → catalog}/Navigation.js +1 -1
- package/lib/{v4/controls → controls}/AbstractControls.d.ts +1 -1
- package/lib/{v4/controls → controls}/codeEditor/MonacoEditor.d.ts +1 -1
- package/lib/{v4/controls → controls}/geojsoneditor/GeoEditor.d.ts +1 -1
- package/lib/{v4/controls → controls}/jsoneditor/JsonEditor.d.ts +1 -1
- package/lib/{v4/controls → controls}/markdown/ToastUiEditor.d.ts +1 -1
- package/lib/{v4/controls → controls}/table/Handsontable.d.ts +1 -1
- package/lib/{v4/controls → controls}/wysiwyg/CKeditor.d.ts +1 -1
- package/lib/{v4/controls → controls}/wysiwyg/CKeditor.js +1 -1
- package/lib/{v4/datatable → datatable}/NodeTable.d.ts +1 -1
- package/lib/media-manager/AbstractMediaManager.d.ts +3 -3
- package/lib/media-manager/AbstractMediaManager.js +2 -2
- package/lib/media-manager/DefaultMediaManager.d.ts +1 -1
- package/lib/media-manager/DefaultMediaManager.js +6 -8
- package/lib/media-manager/Items.d.ts +2 -1
- package/lib/media-manager/Items.js +7 -0
- package/lib/media-manager/helpers/MediaManagerHelper.d.ts +10 -0
- package/lib/media-manager/helpers/MediaManagerHelper.js +27 -10
- package/lib/{v4/model → model}/AbstractModel.d.ts +12 -0
- package/lib/model/AbstractModel.js +178 -0
- package/lib/{v4/model → model}/ModelHandler.js +1 -1
- package/lib/{v4/model → model}/adapter/sequelize.d.ts +3 -4
- package/lib/{v4/model → model}/adapter/sequelize.js +41 -14
- package/lib/notifications/AbstractNotificationService.d.ts +163 -0
- package/lib/notifications/AbstractNotificationService.js +353 -0
- package/lib/notifications/GeneralNotificationService.d.ts +8 -0
- package/lib/notifications/GeneralNotificationService.js +61 -0
- package/lib/notifications/NotificationHandler.d.ts +27 -0
- package/lib/notifications/NotificationHandler.js +41 -0
- package/lib/notifications/SystemNotificationService.d.ts +19 -0
- package/lib/notifications/SystemNotificationService.js +173 -0
- package/lib/{v4/widgets → widgets}/abstractCustom.d.ts +1 -1
- package/lib/{v4/widgets → widgets}/abstractLink.d.ts +1 -1
- package/lib/{v4/widgets → widgets}/abstractWidgetBase.d.ts +1 -1
- package/lib/{v4/widgets → widgets}/widgetHandler.d.ts +2 -2
- package/migrations/index.d.ts +3 -0
- package/migrations/index.js +4 -0
- package/migrations/umzug/0001.d.ts +7 -0
- package/migrations/umzug/0001.js +121 -0
- package/migrations/umzugExports.d.ts +2 -0
- package/migrations/umzugExports.js +9 -0
- package/models/MediaManagerAP.d.ts +9 -3
- package/models/MediaManagerAP.js +11 -5
- package/models/MediaManagerAssociationsAP.d.ts +9 -3
- package/models/MediaManagerAssociationsAP.js +11 -5
- package/models/MediaManagerMetaAP.d.ts +9 -3
- package/models/MediaManagerMetaAP.js +11 -5
- package/models/NotificationAP.d.ts +44 -0
- package/models/NotificationAP.js +30 -0
- package/models/UserAP.d.ts +1 -1
- package/models/UserNotificationAP.d.ts +26 -0
- package/models/UserNotificationAP.js +18 -0
- package/package.json +17 -8
- package/system/Router.js +21 -7
- package/system/bindAssets.js +1 -0
- package/system/bindControls.js +6 -6
- package/system/bindInertia.js +9 -3
- package/system/bindMediaManager.js +2 -1
- package/system/bindNavigation.js +3 -4
- package/system/bindNotifications.d.ts +2 -0
- package/system/bindNotifications.js +14 -0
- package/system/bindReqFunctions.js +8 -25
- package/system/defaults.js +6 -0
- package/translations/ar.json +5 -4
- package/translations/cn.json +5 -4
- package/translations/de.json +72 -71
- package/translations/en.json +5 -4
- package/translations/es.json +5 -4
- package/translations/fr.json +5 -4
- package/translations/hi.json +5 -4
- package/translations/jp.json +5 -4
- package/translations/ko.json +5 -4
- package/translations/pt.json +5 -4
- package/translations/ru.json +2 -1
- package/translations/ua.json +5 -4
- package/translations/uz.json +73 -72
- package/translations/vi.json +5 -4
- package/ui/components/VanillaJSONEditor.d.ts +2 -0
- package/ui/components/VanillaJSONEditor.js +101 -0
- package/ui/components/handsontable.d.ts +10 -0
- package/ui/components/handsontable.js +51 -0
- package/ui/components/monaco-editor.d.ts +11 -0
- package/ui/components/monaco-editor.js +57 -0
- package/ui/components/ui/table.d.ts +1 -1
- package/ui/components/ui/table.js +2 -2
- package/ui/hooks/form-state.d.ts +4 -0
- package/ui/hooks/form-state.js +45 -0
- package/ui/hooks/use-appearance.d.ts +7 -0
- package/ui/hooks/use-appearance.js +76 -0
- package/ui/hooks/use-window-size.d.ts +5 -0
- package/ui/hooks/use-window-size.js +21 -0
- package/assets/VanillaJSONEditor-x8tDbio1.js +0 -3833
- package/assets/add-DOaZgoTz.js +0 -1
- package/assets/add-form-BjackXJe.js +0 -1
- package/assets/add-group-Br44s2D6.js +0 -1
- package/assets/add-group-form-YI6KS37x.js +0 -1
- package/assets/add-user-DWcH0s9-.js +0 -1
- package/assets/add-user-form-bv5BNX5A.js +0 -1
- package/assets/app-layout-DecN527i.js +0 -1
- package/assets/app-shell-DHzMWA1L.js +0 -1
- package/assets/app-sidebar-4JFP8UdU.js +0 -1
- package/assets/app-sidebar-header-CIKLfLsF.js +0 -1
- package/assets/breadcrumbs-Bo2z-LNC.js +0 -1
- package/assets/catalog-DVyrGTNR.js +0 -6
- package/assets/dashboard-Dy3pk9t7.js +0 -3
- package/assets/date-picker-B2z-aeuv.js +0 -1
- package/assets/debounce-D6eaSoDg.js +0 -1
- package/assets/del-modal-l3LxJWCN.js +0 -1
- package/assets/dynamic-controls-CSVVCONh.js +0 -1
- package/assets/field-renderer-BHo944Cn.js +0 -407
- package/assets/form-BXfnz6h5.js +0 -1
- package/assets/form-hP8sjbND.js +0 -1
- package/assets/form-state-702tb_BV.js +0 -1
- package/assets/geo-json-CVaNUZbb.js +0 -4
- package/assets/handsontable-CZQ5Ietj.js +0 -347
- package/assets/home-BD4MWmm9.js +0 -2
- package/assets/icon-C_X2cQ6W.js +0 -1
- package/assets/index-C148XJoK.js +0 -1
- package/assets/index-Vcq4gwWv.js +0 -1
- package/assets/init-user-DgCD4ZN1.js +0 -1
- package/assets/input-error-Bab-HPbn.js +0 -1
- package/assets/list-C-27EH39.js +0 -1
- package/assets/list-table-_OiQmr2A.js +0 -22
- package/assets/login-jzvVXgAV.js +0 -1
- package/assets/material-icon-DsiW0iQG.js +0 -1
- package/assets/media-manager-CSB_XRcE.js +0 -14
- package/assets/module-Ceq6vuwa.js +0 -1
- package/assets/monaco-editor-XX8Hz76f.js +0 -11
- package/assets/multi-select-BbKSrMw2.js +0 -1
- package/assets/nav-footer-B8gMV6Wp.js +0 -1
- package/assets/nav-main-BUp9qA8R.js +0 -1
- package/assets/nav-user-DeF3SDRj.js +0 -1
- package/assets/pagination-render-B9U_hVbB.js +0 -1
- package/assets/register-C6acWsLe.js +0 -1
- package/assets/theme-switcher-D8T9NgWG.js +0 -1
- package/assets/toast-editor-C0550yms.js +0 -845
- package/assets/use-appearance-CXP5cHaQ.js +0 -1
- package/assets/use-window-size-DLSEoR6e.js +0 -1
- package/assets/user-info-CAgkqARx.js +0 -1
- package/assets/user-menu-content-BxL0QMC9.js +0 -1
- package/assets/vanilla-picker-B6E6ObS_.js +0 -8
- package/assets/welcome-Dk7GoS5R.js +0 -1
- package/lib/v4/model/AbstractModel.js +0 -67
- package/lib/v4/model/adapter/typeorm.d.ts +0 -23
- package/lib/v4/model/adapter/typeorm.js +0 -68
- package/migrations/20230303171134-adminpanel-init.js +0 -122
- package/migrations/20231223215835-add-widgets.js +0 -32
- package/migrations/20240804191001-added-navigationap.js +0 -53
- package/migrations/20241121184236-v4-init.js +0 -134
- /package/lib/{v4/I18n.d.ts → I18n.d.ts} +0 -0
- /package/lib/{v4/POWCaptcha.d.ts → POWCaptcha.d.ts} +0 -0
- /package/lib/{v4/POWCaptcha.js → POWCaptcha.js} +0 -0
- /package/lib/{v4/catalog → catalog}/AbstractCatalog.js +0 -0
- /package/lib/{v4/catalog → catalog}/CatalogHandler.d.ts +0 -0
- /package/lib/{v4/catalog → catalog}/CatalogHandler.js +0 -0
- /package/lib/{v4/controls → controls}/AbstractControls.js +0 -0
- /package/lib/{v4/controls → controls}/ControlsHandler.d.ts +0 -0
- /package/lib/{v4/controls → controls}/ControlsHandler.js +0 -0
- /package/lib/{v4/controls → controls}/codeEditor/MonacoEditor.js +0 -0
- /package/lib/{v4/controls → controls}/geojsoneditor/GeoEditor.js +0 -0
- /package/lib/{v4/controls → controls}/jsoneditor/JsonEditor.js +0 -0
- /package/lib/{v4/controls → controls}/markdown/ToastUiEditor.js +0 -0
- /package/lib/{v4/controls → controls}/table/Handsontable.js +0 -0
- /package/lib/{v4/datatable → datatable}/NodeTable.js +0 -0
- /package/lib/{v4/helper → helper}/jwt.d.ts +0 -0
- /package/lib/{v4/helper → helper}/jwt.js +0 -0
- /package/lib/{v4/inertia → inertia}/flash.d.ts +0 -0
- /package/lib/{v4/inertia → inertia}/flash.js +0 -0
- /package/lib/{v4/inertia → inertia}/inertiaAdapter.d.ts +0 -0
- /package/lib/{v4/inertia → inertia}/inertiaAdapter.js +0 -0
- /package/lib/{v4/model → model}/ModelHandler.d.ts +0 -0
- /package/lib/{v4/model → model}/adapter/waterline.d.ts +0 -0
- /package/lib/{v4/model → model}/adapter/waterline.js +0 -0
- /package/lib/{v4/widgets → widgets}/abstractAction.d.ts +0 -0
- /package/lib/{v4/widgets → widgets}/abstractAction.js +0 -0
- /package/lib/{v4/widgets → widgets}/abstractCustom.js +0 -0
- /package/lib/{v4/widgets → widgets}/abstractInfo.d.ts +0 -0
- /package/lib/{v4/widgets → widgets}/abstractInfo.js +0 -0
- /package/lib/{v4/widgets → widgets}/abstractLink.js +0 -0
- /package/lib/{v4/widgets → widgets}/abstractSwitch.d.ts +0 -0
- /package/lib/{v4/widgets → widgets}/abstractSwitch.js +0 -0
- /package/lib/{v4/widgets → widgets}/abstractWidgetBase.js +0 -0
- /package/lib/{v4/widgets → widgets}/widgetHandler.js +0 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { Adminizer } from '../../lib/Adminizer';
|
|
2
|
+
export class NotificationController {
|
|
3
|
+
static async search(req, res) {
|
|
4
|
+
NotificationController.checkNotifPermission(req, res);
|
|
5
|
+
if (req.method.toUpperCase() === 'POST') {
|
|
6
|
+
const { s, notificationClass } = req.body;
|
|
7
|
+
const hasPermission = req.adminizer.accessRightsHelper.hasPermission(`notification-${notificationClass}`, req.user);
|
|
8
|
+
if (!hasPermission) {
|
|
9
|
+
res.status(403).json({ error: 'Forbidden' });
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const service = req.adminizer.notificationHandler.getService(notificationClass);
|
|
13
|
+
res.json(await service.search(s, req.user.id));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
static async viewAll(req, res) {
|
|
17
|
+
NotificationController.checkNotifPermission(req, res);
|
|
18
|
+
if (req.method.toUpperCase() === 'POST') {
|
|
19
|
+
const messages = {
|
|
20
|
+
"Make read": "",
|
|
21
|
+
"View All": "",
|
|
22
|
+
"Search": "",
|
|
23
|
+
"Make all read": "",
|
|
24
|
+
"Title": "",
|
|
25
|
+
"Message": "",
|
|
26
|
+
"Date": "",
|
|
27
|
+
"Diff": "",
|
|
28
|
+
"The end of the list has been reached": "",
|
|
29
|
+
};
|
|
30
|
+
return res.json(Object.fromEntries(Object.keys(messages).map(key => [key, req.i18n.__(key)])));
|
|
31
|
+
}
|
|
32
|
+
if (req.method.toUpperCase() === 'GET') {
|
|
33
|
+
return req.Inertia.render({
|
|
34
|
+
component: 'notification',
|
|
35
|
+
props: {
|
|
36
|
+
title: req.i18n.__('Notifications'),
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return res.status(405);
|
|
41
|
+
}
|
|
42
|
+
static async getNotificationClasses(req, res) {
|
|
43
|
+
NotificationController.checkNotifPermission(req, res);
|
|
44
|
+
if (req.adminizer.config.notifications.enabled === false)
|
|
45
|
+
return res.json([]);
|
|
46
|
+
const services = req.adminizer.notificationHandler.getAllServices();
|
|
47
|
+
let activeServices = [];
|
|
48
|
+
for (const service of services) {
|
|
49
|
+
// Получаем только клиентов текущего пользователя
|
|
50
|
+
const userClients = service.getUserClients(req.user.id);
|
|
51
|
+
if (userClients.size > 0) {
|
|
52
|
+
activeServices.push(service.notificationClass);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return res.json(activeServices);
|
|
56
|
+
}
|
|
57
|
+
// Единый SSE endpoint для всех уведомлений
|
|
58
|
+
static async getNotificationsStream(req, res) {
|
|
59
|
+
NotificationController.checkNotifPermission(req, res);
|
|
60
|
+
// Устанавливаем заголовки для SSE
|
|
61
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
62
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
63
|
+
res.setHeader('Connection', 'keep-alive');
|
|
64
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
65
|
+
res.flushHeaders();
|
|
66
|
+
const clientId = `user-${req.user?.id}-${Date.now()}`;
|
|
67
|
+
// Функция для отправки событий клиенту
|
|
68
|
+
const sendEvent = (event) => {
|
|
69
|
+
// Фильтруем уведомления по правам пользователя
|
|
70
|
+
if (event.type === 'notification') {
|
|
71
|
+
const notificationClass = event.notificationClass;
|
|
72
|
+
// ЕДИНАЯ проверка прав через AccessRightsHelper
|
|
73
|
+
const hasPermission = req.adminizer.accessRightsHelper.hasPermission(`notification-${notificationClass}`, req.user);
|
|
74
|
+
if (!hasPermission) {
|
|
75
|
+
return; // Пользователь не имеет прав на этот класс уведомлений
|
|
76
|
+
}
|
|
77
|
+
// Проверка персональных уведомлений (только для целевого пользователя)
|
|
78
|
+
if (event.userId !== null && event.userId !== req.user.id) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
res.write(`event: ${event.type}\n`);
|
|
83
|
+
res.write(`data: ${JSON.stringify(event.data)}\n\n`);
|
|
84
|
+
};
|
|
85
|
+
// Подключаем клиента ко всем сервисам
|
|
86
|
+
const services = req.adminizer.notificationHandler.getAllServices();
|
|
87
|
+
const allowedServices = services.filter(service => req.adminizer.accessRightsHelper.hasPermission(`notification-${service.notificationClass}`, req.user));
|
|
88
|
+
allowedServices.forEach(service => {
|
|
89
|
+
service.addClient(clientId, sendEvent, req.user);
|
|
90
|
+
// Для системного сервиса добавляем клиента в CRUD каналы
|
|
91
|
+
if (service.notificationClass === 'system') {
|
|
92
|
+
const systemService = service;
|
|
93
|
+
// Добавляем клиента в основные CRUD каналы с указанием userId
|
|
94
|
+
['created', 'updated', 'deleted', 'system'].forEach(channel => {
|
|
95
|
+
systemService.addClientToChannel(clientId, channel, req.user.id);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Отправляем приветственное сообщение
|
|
100
|
+
sendEvent({
|
|
101
|
+
type: 'connected',
|
|
102
|
+
data: {
|
|
103
|
+
message: 'Connected to unified notification stream',
|
|
104
|
+
clientId: clientId
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// Обработка закрытия соединения
|
|
108
|
+
req.on('close', () => {
|
|
109
|
+
// Отключаем клиента от всех сервисов
|
|
110
|
+
services.forEach(service => {
|
|
111
|
+
service.removeClient(clientId);
|
|
112
|
+
// Для системного сервиса удаляем из всех каналов
|
|
113
|
+
if (service.notificationClass === 'system') {
|
|
114
|
+
const systemService = service;
|
|
115
|
+
if (systemService.removeClientFromAllChannels) {
|
|
116
|
+
systemService.removeClientFromAllChannels(clientId, req.user.id);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
res.end();
|
|
121
|
+
});
|
|
122
|
+
// Heartbeat для поддержания соединения
|
|
123
|
+
const heartbeatInterval = setInterval(() => {
|
|
124
|
+
if (!res.writableEnded) {
|
|
125
|
+
services.forEach(service => {
|
|
126
|
+
service.sendHeartbeat(clientId);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
clearInterval(heartbeatInterval);
|
|
131
|
+
}
|
|
132
|
+
}, 30000);
|
|
133
|
+
req.on('close', () => {
|
|
134
|
+
clearInterval(heartbeatInterval);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// API для получения уведомлений по классу
|
|
138
|
+
static async getNotificationsByClass(req, res) {
|
|
139
|
+
NotificationController.checkNotifPermission(req, res);
|
|
140
|
+
try {
|
|
141
|
+
const { notificationClass } = req.params;
|
|
142
|
+
const { limit = 20, skip = 0, unreadOnly = false } = req.query;
|
|
143
|
+
// Проверяем права доступа
|
|
144
|
+
const hasPermission = req.adminizer.accessRightsHelper.hasPermission(`notification-${notificationClass}`, req.user);
|
|
145
|
+
if (!hasPermission) {
|
|
146
|
+
res.status(403).json({ error: 'Forbidden' });
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const service = req.adminizer.notificationHandler.getService(notificationClass);
|
|
150
|
+
const notifications = await service.getNotifications(req.user?.id, Number(limit), Number(skip), unreadOnly === 'true');
|
|
151
|
+
res.json(notifications);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
Adminizer.log.error('Error getting notifications:', error);
|
|
155
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// API для получения всех уведомлений пользователя
|
|
159
|
+
static async getUserNotifications(req, res) {
|
|
160
|
+
NotificationController.checkNotifPermission(req, res);
|
|
161
|
+
const { limit = 4, skip = 0, unreadOnly = false } = req.query;
|
|
162
|
+
try {
|
|
163
|
+
// Фильтруем сервисы по правам доступа
|
|
164
|
+
const services = req.adminizer.notificationHandler.getAllServices();
|
|
165
|
+
const allowedServices = services.filter(service => req.adminizer.accessRightsHelper.hasPermission(`notification-${service.notificationClass}`, req.user));
|
|
166
|
+
const allNotifications = [];
|
|
167
|
+
for (const service of allowedServices) {
|
|
168
|
+
const notifications = await service.getNotifications(req.user.id, Number(limit), Number(skip), unreadOnly === 'true');
|
|
169
|
+
allNotifications.push(...notifications);
|
|
170
|
+
}
|
|
171
|
+
// Сортируем по дате создания
|
|
172
|
+
const sortedNotifications = allNotifications.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, Number(limit));
|
|
173
|
+
res.json(sortedNotifications);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
Adminizer.log.error('Error getting user notifications:', error);
|
|
177
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// API для пометки как прочитанного
|
|
181
|
+
static async markAsRead(req, res) {
|
|
182
|
+
NotificationController.checkNotifPermission(req, res);
|
|
183
|
+
try {
|
|
184
|
+
const { notificationClass, id } = req.params;
|
|
185
|
+
const service = req.adminizer.notificationHandler.getService(notificationClass);
|
|
186
|
+
await service.markAsRead(req.user.id, id);
|
|
187
|
+
res.json({ success: true });
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
Adminizer.log.error('Error marking notification as read:', error);
|
|
191
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
static async markAllAsRead(req, res) {
|
|
195
|
+
NotificationController.checkNotifPermission(req, res);
|
|
196
|
+
try {
|
|
197
|
+
const services = req.adminizer.notificationHandler.getAllServices();
|
|
198
|
+
for (const service of services) {
|
|
199
|
+
await service.markAllAsRead(req.user.id);
|
|
200
|
+
}
|
|
201
|
+
res.json({ success: true });
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
Adminizer.log.error('Error marking all notifications as read:', error);
|
|
205
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
static checkNotifPermission(req, res) {
|
|
209
|
+
if (!req.adminizer?.notificationHandler) {
|
|
210
|
+
res.status(500).json({ error: 'Notification system not initialized' });
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
// // Проверяем аутентификацию
|
|
214
|
+
if (req.adminizer.config.auth.enable && !req.user) {
|
|
215
|
+
res.status(401).json({ error: 'Unauthorized' });
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
package/controllers/remove.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ControllerHelper } from "../helpers/controllerHelper";
|
|
2
2
|
import { deleteRelationsMediaManager } from "../lib/media-manager/helpers/MediaManagerHelper";
|
|
3
|
-
import { DataAccessor } from "../lib/
|
|
3
|
+
import { DataAccessor } from "../lib/DataAccessor";
|
|
4
4
|
import { Adminizer } from "../lib/Adminizer";
|
|
5
5
|
export default async function remove(req, res) {
|
|
6
6
|
// Checking id of the record
|
|
@@ -60,6 +60,7 @@ export default async function remove(req, res) {
|
|
|
60
60
|
const q = {};
|
|
61
61
|
q[fieldId] = record[fieldId];
|
|
62
62
|
destroyedRecord = await entity.model.destroy(q, dataAccessor);
|
|
63
|
+
console.log(destroyedRecord[0]);
|
|
63
64
|
// delete relations media manager
|
|
64
65
|
await deleteRelationsMediaManager(req.adminizer, entity.name, destroyedRecord);
|
|
65
66
|
}
|
package/controllers/view.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ControllerHelper } from "../helpers/controllerHelper";
|
|
2
|
-
import { DataAccessor } from "../lib/
|
|
2
|
+
import { DataAccessor } from "../lib/DataAccessor";
|
|
3
3
|
import { Adminizer } from "../lib/Adminizer";
|
|
4
4
|
import { inertiaUserHelper } from "../helpers/inertiaUserHelper";
|
|
5
5
|
import { inertiaGroupHelper } from "../helpers/inertiaGroupHelper";
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AdminpanelConfig, BaseFieldConfig } from "../interfaces/adminpanelConfig";
|
|
2
|
-
import { Attribute } from "../lib/
|
|
2
|
+
import { Attribute } from "../lib/model/AbstractModel";
|
|
3
3
|
import { Adminizer } from "../lib/Adminizer";
|
|
4
4
|
export declare class ConfigHelper {
|
|
5
5
|
adminizer: Adminizer;
|
|
@@ -129,7 +129,7 @@ export class ControllerHelper {
|
|
|
129
129
|
}
|
|
130
130
|
return Object.keys(models).find(key => key.toLowerCase() === entityName.toLowerCase());
|
|
131
131
|
}
|
|
132
|
-
throw new Error(`Unsupported entity type
|
|
132
|
+
throw new Error(`Unsupported entity type ${entityType} in URL`);
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
135
135
|
* Searches for config from admin panel
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export function sanitizeForDiff(data) {
|
|
2
|
+
if (!data)
|
|
3
|
+
return {};
|
|
4
|
+
const result = { ...data };
|
|
5
|
+
// Удаляем системные поля
|
|
6
|
+
const systemFields = ['id', 'createdAt', 'updatedAt', 'deletedAt', '__v', '_id'];
|
|
7
|
+
systemFields.forEach(field => delete result[field]);
|
|
8
|
+
// Очищаем чувствительные данные
|
|
9
|
+
// TODO: Вынести в переменные окружения или в конфиг
|
|
10
|
+
const sensitiveFields = ['password', 'token', 'secret', 'apiKey', 'creditCard'];
|
|
11
|
+
sensitiveFields.forEach(field => {
|
|
12
|
+
if (result[field] !== undefined) {
|
|
13
|
+
result[field] = '***HIDDEN***';
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
export function formatChanges(diffObj, oldData, newData, operation) {
|
|
19
|
+
const changes = [];
|
|
20
|
+
// Специальная обработка для операции добавления
|
|
21
|
+
if (operation === 'add') {
|
|
22
|
+
for (const [key, value] of Object.entries(newData)) {
|
|
23
|
+
if (value === '***HIDDEN***')
|
|
24
|
+
continue;
|
|
25
|
+
changes.push({
|
|
26
|
+
field: key,
|
|
27
|
+
oldValue: undefined,
|
|
28
|
+
newValue: value,
|
|
29
|
+
type: typeof value,
|
|
30
|
+
operation: 'add'
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return changes;
|
|
34
|
+
}
|
|
35
|
+
// Стандартная обработка для remove и update
|
|
36
|
+
for (const [key, value] of Object.entries(diffObj)) {
|
|
37
|
+
// Для добавленных полей (когда oldData[key] undefined)
|
|
38
|
+
if (oldData[key] === undefined && newData[key] !== undefined) {
|
|
39
|
+
changes.push({
|
|
40
|
+
field: key,
|
|
41
|
+
oldValue: undefined,
|
|
42
|
+
newValue: newData[key],
|
|
43
|
+
type: 'added',
|
|
44
|
+
operation: 'add'
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// Для удаленных полей (когда newData[key] undefined)
|
|
48
|
+
else if (newData[key] === undefined && oldData[key] !== undefined) {
|
|
49
|
+
changes.push({
|
|
50
|
+
field: key,
|
|
51
|
+
oldValue: oldData[key],
|
|
52
|
+
newValue: undefined,
|
|
53
|
+
type: 'deleted',
|
|
54
|
+
operation: 'remove'
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Для измененных полей
|
|
58
|
+
else {
|
|
59
|
+
changes.push({
|
|
60
|
+
field: key,
|
|
61
|
+
oldValue: oldData[key],
|
|
62
|
+
newValue: newData[key],
|
|
63
|
+
type: typeof value,
|
|
64
|
+
operation: 'update'
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return changes;
|
|
69
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ActionType, BaseFieldConfig, FieldsTypes, ModelConfig } from "../interfaces/adminpanelConfig";
|
|
2
|
-
import { Attribute } from "../lib/
|
|
2
|
+
import { Attribute } from "../lib/model/AbstractModel";
|
|
3
3
|
export type Field = {
|
|
4
4
|
config: BaseFieldConfig & {
|
|
5
5
|
/** @deprecated record should not be in config anymore */
|
package/helpers/fieldsHelper.js
CHANGED
package/helpers/formHelper.js
CHANGED
|
@@ -22,7 +22,9 @@ export class FormHelper {
|
|
|
22
22
|
}
|
|
23
23
|
let form = path.basename(formJson, '.json');
|
|
24
24
|
try {
|
|
25
|
-
|
|
25
|
+
const filePath = path.join(formsDirectoryPath, formJson);
|
|
26
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
27
|
+
adminizer.config.forms.data[form] = JSON.parse(fileContent);
|
|
26
28
|
}
|
|
27
29
|
catch (error) {
|
|
28
30
|
Adminizer.log.error(`Adminpanel > Error when reading ${formJson}: ${error}`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Entity, PropsField } from "../interfaces/types";
|
|
2
2
|
import { Actions } from "./inertiaActionsHelper";
|
|
3
3
|
import { Fields, Field } from "./fieldsHelper";
|
|
4
|
-
import { AbstractControls, ControlType } from "../lib/
|
|
4
|
+
import { AbstractControls, ControlType } from "../lib/controls/AbstractControls";
|
|
5
5
|
export type PropsFieldType = 'text' | 'number' | 'range' | 'week' | 'month' | 'email' | 'color' | 'time' | 'date' | 'datetime-local' | 'password' | 'select' | 'select-many' | 'association-many' | 'association' | 'textarea' | 'mediamanager' | 'checkbox' | ControlType;
|
|
6
6
|
interface FieldProps extends Record<string | number | symbol, unknown> {
|
|
7
7
|
edit: boolean;
|
|
@@ -11,6 +11,25 @@ export function inertiaLoginHelper(req) {
|
|
|
11
11
|
link: `${req.adminizer.config.routePrefix}/model/userap/register`
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
+
// Optional additional link at the bottom of login page
|
|
15
|
+
const addPage = req.adminizer.config.auth?.addishinalLoginPage;
|
|
16
|
+
if (addPage && typeof addPage.link === 'string' && addPage.link.length > 0) {
|
|
17
|
+
const raw = addPage.link;
|
|
18
|
+
let link = raw;
|
|
19
|
+
if (/^https?:\/\//i.test(raw)) {
|
|
20
|
+
link = raw; // absolute URL
|
|
21
|
+
}
|
|
22
|
+
else if (raw.startsWith(`/${req.adminizer.config.routePrefix}`)) {
|
|
23
|
+
link = `${raw}`;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
link = `${req.adminizer.config.routePrefix}/${raw}`;
|
|
27
|
+
}
|
|
28
|
+
props.addishinalLoginPage = {
|
|
29
|
+
title: req.i18n.__(addPage.textKey || 'Additional login page'),
|
|
30
|
+
link,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
14
33
|
return props;
|
|
15
34
|
}
|
|
16
35
|
export function inertiaRegisterHelper(req) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { inputText, setSelectMany, getControlsOptions } from "./inertiaAddHelper";
|
|
2
|
+
import { MediaManagerHandler } from "../lib/media-manager/MediaManagerHandler";
|
|
2
3
|
export default function inertiaFormHelper(req, postLink, formData) {
|
|
3
4
|
let props = {
|
|
4
5
|
fields: [],
|
|
@@ -71,6 +72,17 @@ export default function inertiaFormHelper(req, postLink, formData) {
|
|
|
71
72
|
fieldType = 'geoJson';
|
|
72
73
|
options = getControlsOptions(field, req, fieldType, 'leaflet');
|
|
73
74
|
}
|
|
75
|
+
if (type === 'mediamanager') {
|
|
76
|
+
const mOptions = field.options;
|
|
77
|
+
const mediaManager = MediaManagerHandler.get(mOptions.id || 'default');
|
|
78
|
+
if (!mediaManager) {
|
|
79
|
+
options = {};
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
fieldType = 'mediamanager';
|
|
83
|
+
options = mOptions;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
74
86
|
props.fields.push({
|
|
75
87
|
label: label,
|
|
76
88
|
tooltip: tooltip,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Adminizer } from "../lib/Adminizer";
|
|
2
|
-
import { I18n } from "../lib/
|
|
2
|
+
import { I18n } from "../lib/I18n";
|
|
3
3
|
export declare class TranslationHelper {
|
|
4
4
|
static loadTranslations(adminizer: Adminizer, translationsPath: string): void;
|
|
5
5
|
static translateProperties(i18n: I18n, object: any, fields: string[]): any;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
2
|
import * as fs from "fs";
|
|
3
3
|
import { Adminizer } from "../lib/Adminizer";
|
|
4
|
-
import { I18n } from "../lib/
|
|
4
|
+
import { I18n } from "../lib/I18n";
|
|
5
5
|
export class TranslationHelper {
|
|
6
6
|
static loadTranslations(adminizer, translationsPath) {
|
|
7
7
|
let translationsConfig = adminizer.config.translation;
|
package/index.d.ts
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
export * from "./helpers/configHelper";
|
|
2
2
|
export * from "./helpers/accessRightsHelper";
|
|
3
|
-
export * from "./lib/
|
|
4
|
-
export * from "./lib/
|
|
5
|
-
export * from "./lib/
|
|
6
|
-
export * from "./lib/
|
|
7
|
-
export * from "./lib/
|
|
8
|
-
export * from "./lib/
|
|
9
|
-
export * from "./lib/
|
|
10
|
-
export * from "./lib/
|
|
11
|
-
export * from "./lib/
|
|
12
|
-
export * from "./lib/
|
|
3
|
+
export * from "./lib/widgets/abstractAction";
|
|
4
|
+
export * from "./lib/widgets/abstractInfo";
|
|
5
|
+
export * from "./lib/widgets/abstractCustom";
|
|
6
|
+
export * from "./lib/widgets/abstractLink";
|
|
7
|
+
export * from "./lib/widgets/abstractWidgetBase";
|
|
8
|
+
export * from "./lib/widgets/abstractSwitch";
|
|
9
|
+
export * from "./lib/widgets/widgetHandler";
|
|
10
|
+
export * from "./lib/catalog/AbstractCatalog";
|
|
11
|
+
export * from "./lib/catalog/Navigation";
|
|
12
|
+
export * from "./lib/catalog/CatalogHandler";
|
|
13
13
|
export * from "./lib/media-manager/MediaManagerHandler";
|
|
14
14
|
export * from "./interfaces/adminpanelConfig";
|
|
15
|
-
export * from "./
|
|
16
|
-
export * from "./
|
|
17
|
-
export * from "./lib/
|
|
18
|
-
export * from "./lib/
|
|
15
|
+
export * from "./interfaces/types";
|
|
16
|
+
export * from "./interfaces/MaaterialIcons";
|
|
17
|
+
export * from "./lib/model/AbstractModel";
|
|
18
|
+
export * from "./lib/model/adapter/waterline";
|
|
19
|
+
export * from "./lib/model/adapter/sequelize";
|
|
19
20
|
export * from "./lib/Adminizer";
|
|
20
21
|
export * from "./models/GroupAP";
|
|
21
22
|
export * from "./models/UserAP";
|
|
@@ -23,3 +24,4 @@ export * from "./models/MediaManagerAP";
|
|
|
23
24
|
export * from "./models/MediaManagerAssociationsAP";
|
|
24
25
|
export * from "./models/MediaManagerMetaAP";
|
|
25
26
|
export * from "./models/NavigationAP";
|
|
27
|
+
export * from "./migrations";
|
package/index.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
export * from "./helpers/configHelper";
|
|
2
2
|
export * from "./helpers/accessRightsHelper";
|
|
3
|
-
export * from "./lib/
|
|
4
|
-
export * from "./lib/
|
|
5
|
-
export * from "./lib/
|
|
6
|
-
export * from "./lib/
|
|
7
|
-
export * from "./lib/
|
|
8
|
-
export * from "./lib/
|
|
9
|
-
export * from "./lib/
|
|
10
|
-
export * from "./lib/
|
|
11
|
-
export * from "./lib/
|
|
12
|
-
export * from "./lib/
|
|
3
|
+
export * from "./lib/widgets/abstractAction";
|
|
4
|
+
export * from "./lib/widgets/abstractInfo";
|
|
5
|
+
export * from "./lib/widgets/abstractCustom";
|
|
6
|
+
export * from "./lib/widgets/abstractLink";
|
|
7
|
+
export * from "./lib/widgets/abstractWidgetBase";
|
|
8
|
+
export * from "./lib/widgets/abstractSwitch";
|
|
9
|
+
export * from "./lib/widgets/widgetHandler";
|
|
10
|
+
export * from "./lib/catalog/AbstractCatalog";
|
|
11
|
+
export * from "./lib/catalog/Navigation";
|
|
12
|
+
export * from "./lib/catalog/CatalogHandler";
|
|
13
13
|
export * from "./lib/media-manager/MediaManagerHandler";
|
|
14
14
|
export * from "./interfaces/adminpanelConfig";
|
|
15
|
-
export * from "./
|
|
16
|
-
export * from "./
|
|
17
|
-
export * from "./lib/
|
|
18
|
-
export * from "./lib/
|
|
15
|
+
export * from "./interfaces/types";
|
|
16
|
+
export * from "./interfaces/MaaterialIcons";
|
|
17
|
+
export * from "./lib/model/AbstractModel";
|
|
18
|
+
export * from "./lib/model/adapter/waterline";
|
|
19
|
+
export * from "./lib/model/adapter/sequelize";
|
|
19
20
|
export * from "./lib/Adminizer";
|
|
20
21
|
export * from "./models/GroupAP";
|
|
21
22
|
export * from "./models/UserAP";
|
|
@@ -23,3 +24,4 @@ export * from "./models/MediaManagerAP";
|
|
|
23
24
|
export * from "./models/MediaManagerAssociationsAP";
|
|
24
25
|
export * from "./models/MediaManagerMetaAP";
|
|
25
26
|
export * from "./models/NavigationAP";
|
|
27
|
+
export * from "./migrations";
|
|
@@ -36,6 +36,18 @@ export interface AdminpanelConfig {
|
|
|
36
36
|
captcha?: boolean;
|
|
37
37
|
/** Description displayed on login page */
|
|
38
38
|
description?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Optional additional link at the bottom of the login page
|
|
41
|
+
* Example:
|
|
42
|
+
* addishinalLoginPage: { link: '/model/userap/register', textKey: 'Additional login page' }
|
|
43
|
+
* link can be relative to routePrefix (e.g. 'model/help' or '/model/help') or absolute (https://...)
|
|
44
|
+
*/
|
|
45
|
+
addishinalLoginPage?: {
|
|
46
|
+
/** Target URL; relative to routePrefix unless absolute */
|
|
47
|
+
link: string;
|
|
48
|
+
/** Optional i18n key for label; defaults to 'Additional login page' */
|
|
49
|
+
textKey?: string;
|
|
50
|
+
};
|
|
39
51
|
};
|
|
40
52
|
/**
|
|
41
53
|
* @alpha
|
|
@@ -173,6 +185,12 @@ export interface AdminpanelConfig {
|
|
|
173
185
|
/** Default ORM adapter for system models */
|
|
174
186
|
defaultORM: string;
|
|
175
187
|
};
|
|
188
|
+
bind?: {
|
|
189
|
+
public: boolean;
|
|
190
|
+
};
|
|
191
|
+
notifications?: {
|
|
192
|
+
enabled: boolean;
|
|
193
|
+
};
|
|
176
194
|
}
|
|
177
195
|
export interface ModelConfig {
|
|
178
196
|
adapter?: string;
|
package/interfaces/global.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Adminizer } from "../lib/Adminizer";
|
|
2
2
|
import { NextFunction, Request, Response } from "express";
|
|
3
3
|
import multer from "multer";
|
|
4
|
-
import { I18n } from "../lib/
|
|
5
|
-
import { Inertia } from "../lib/
|
|
6
|
-
import { Flash } from "../lib/
|
|
4
|
+
import { I18n } from "../lib/I18n";
|
|
5
|
+
import { Inertia } from "../lib/inertia/inertiaAdapter";
|
|
6
|
+
import { Flash } from "../lib/inertia/flash";
|
|
7
7
|
import { UserAP } from "models/UserAP";
|
|
8
8
|
declare global {
|
|
9
9
|
/** @deprecated use import from TS model decalration */
|
package/interfaces/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractModel } from "../lib/
|
|
1
|
+
import { AbstractModel } from "../lib/model/AbstractModel";
|
|
2
2
|
import { ModelConfig } from "./adminpanelConfig";
|
|
3
3
|
export type EntityType = "form" | "model";
|
|
4
4
|
export interface Entity {
|
|
@@ -23,5 +23,47 @@ export interface PropsField {
|
|
|
23
23
|
disabled?: boolean;
|
|
24
24
|
required?: boolean;
|
|
25
25
|
isIn?: string[] | number[] | boolean[];
|
|
26
|
-
options?: Record<string,
|
|
26
|
+
options?: Record<string, any> | Record<string, any>[];
|
|
27
27
|
}
|
|
28
|
+
export interface DiffChanges {
|
|
29
|
+
field: string;
|
|
30
|
+
oldValue: any;
|
|
31
|
+
newValue: any;
|
|
32
|
+
type: string;
|
|
33
|
+
}
|
|
34
|
+
export interface Diff {
|
|
35
|
+
changes: DiffChanges[];
|
|
36
|
+
summary: string;
|
|
37
|
+
}
|
|
38
|
+
export interface INotification {
|
|
39
|
+
id: string;
|
|
40
|
+
title: string;
|
|
41
|
+
message: string;
|
|
42
|
+
createdAt: Date;
|
|
43
|
+
userId?: number;
|
|
44
|
+
read?: boolean;
|
|
45
|
+
icon: {
|
|
46
|
+
icon: string;
|
|
47
|
+
iconColor: string;
|
|
48
|
+
};
|
|
49
|
+
notificationClass: string;
|
|
50
|
+
channel: string | 'created' | 'updated' | 'deleted' | 'system';
|
|
51
|
+
metadata?: Record<string | number, any> | Diff;
|
|
52
|
+
}
|
|
53
|
+
export interface INotificationEvent {
|
|
54
|
+
type: 'notification' | 'heartbeat' | 'connected' | 'error';
|
|
55
|
+
data: INotification | string;
|
|
56
|
+
notificationClass?: string;
|
|
57
|
+
channel?: string;
|
|
58
|
+
userId?: number;
|
|
59
|
+
}
|
|
60
|
+
export type Migration = {
|
|
61
|
+
name: string;
|
|
62
|
+
timestamp: number;
|
|
63
|
+
up: (args: {
|
|
64
|
+
context: any;
|
|
65
|
+
}) => Promise<unknown> | unknown;
|
|
66
|
+
down: (args: {
|
|
67
|
+
context: any;
|
|
68
|
+
}) => Promise<unknown> | unknown;
|
|
69
|
+
};
|