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,173 @@
|
|
|
1
|
+
import { AbstractNotificationService } from './AbstractNotificationService';
|
|
2
|
+
import { Adminizer } from '../Adminizer';
|
|
3
|
+
export class SystemNotificationService extends AbstractNotificationService {
|
|
4
|
+
notificationClass = 'system';
|
|
5
|
+
icon = 'settings';
|
|
6
|
+
iconColor = '#1eb707';
|
|
7
|
+
// Изменяем структуру каналов: храним по userId -> channel -> clientIds
|
|
8
|
+
crudChannels = new Map();
|
|
9
|
+
async dispatchNotification(notification) {
|
|
10
|
+
const fullNotification = {
|
|
11
|
+
...notification,
|
|
12
|
+
notificationClass: this.notificationClass,
|
|
13
|
+
channel: notification.channel ?? ''
|
|
14
|
+
};
|
|
15
|
+
let notificationDB;
|
|
16
|
+
// Сохраняем в базу
|
|
17
|
+
if (this.adminizer.modelHandler.model.has('notificationap')) {
|
|
18
|
+
try {
|
|
19
|
+
notificationDB = await this.adminizer.modelHandler.model.get('notificationap')["_create"](fullNotification);
|
|
20
|
+
const users = await this.adminizer.modelHandler.model.get('userap')["_find"]({});
|
|
21
|
+
for (const user of users) {
|
|
22
|
+
try {
|
|
23
|
+
if (this.adminizer.accessRightsHelper.hasPermission(`notification-${this.notificationClass}`, user)) {
|
|
24
|
+
await this.createUserNotification(notificationDB.id, user.id);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
Adminizer.log.error('Error creating UserNotificationAP:', error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const event = {
|
|
32
|
+
type: 'notification',
|
|
33
|
+
data: {
|
|
34
|
+
...notificationDB,
|
|
35
|
+
icon: {
|
|
36
|
+
icon: this.icon,
|
|
37
|
+
iconColor: this.iconColor
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
notificationClass: this.notificationClass,
|
|
41
|
+
userId: notification.userId ?? null,
|
|
42
|
+
channel: notification.channel ?? 'system'
|
|
43
|
+
};
|
|
44
|
+
// Отправляем на все каналы или на конкретный канал
|
|
45
|
+
if (notification.channel) {
|
|
46
|
+
this.broadcastToChannel(notification.channel, event);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.broadcastToChannel('system', event);
|
|
50
|
+
}
|
|
51
|
+
Adminizer.log.info(`[System] Notification dispatched: ${fullNotification.title}`);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
Adminizer.log.error('Error saving system notification to database:', error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
// Обновляем broadcastToChannel для работы с новой структурой
|
|
61
|
+
broadcastToChannel(channel, event) {
|
|
62
|
+
// Отправляем всем пользователям, подписанным на этот канал
|
|
63
|
+
this.crudChannels.forEach((userChannels, userId) => {
|
|
64
|
+
const channelClients = userChannels.get(channel);
|
|
65
|
+
if (channelClients) {
|
|
66
|
+
const userClients = this.clients.get(userId);
|
|
67
|
+
if (userClients) {
|
|
68
|
+
channelClients.forEach(clientId => {
|
|
69
|
+
const sendFn = userClients.get(clientId);
|
|
70
|
+
if (sendFn) {
|
|
71
|
+
try {
|
|
72
|
+
sendFn(event);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
Adminizer.log.error(`[${this.notificationClass}] Error sending to client ${clientId} on channel ${channel}:`, error);
|
|
76
|
+
this.removeClient(clientId);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Добавляем клиента к каналу с привязкой к пользователю
|
|
85
|
+
addClientToChannel(clientId, channel, userId) {
|
|
86
|
+
if (!this.crudChannels.has(userId)) {
|
|
87
|
+
this.crudChannels.set(userId, new Map());
|
|
88
|
+
}
|
|
89
|
+
const userChannels = this.crudChannels.get(userId);
|
|
90
|
+
if (!userChannels.has(channel)) {
|
|
91
|
+
userChannels.set(channel, new Set());
|
|
92
|
+
}
|
|
93
|
+
userChannels.get(channel).add(clientId);
|
|
94
|
+
Adminizer.log.info(`[${this.notificationClass}] Client ${clientId} (user ${userId}) added to channel ${channel}`);
|
|
95
|
+
}
|
|
96
|
+
// Удаляем клиента из канала конкретного пользователя
|
|
97
|
+
removeClientFromChannel(clientId, channel, userId) {
|
|
98
|
+
const userChannels = this.crudChannels.get(userId);
|
|
99
|
+
if (userChannels) {
|
|
100
|
+
const channelClients = userChannels.get(channel);
|
|
101
|
+
if (channelClients) {
|
|
102
|
+
channelClients.delete(clientId);
|
|
103
|
+
Adminizer.log.info(`[${this.notificationClass}] Client ${clientId} (user ${userId}) removed from channel ${channel}`);
|
|
104
|
+
// Если в канале больше нет клиентов - удаляем канал
|
|
105
|
+
if (channelClients.size === 0) {
|
|
106
|
+
userChannels.delete(channel);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Если у пользователя больше нет каналов - удаляем запись пользователя
|
|
110
|
+
if (userChannels.size === 0) {
|
|
111
|
+
this.crudChannels.delete(userId);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Удаляем клиента из всех каналов пользователя
|
|
116
|
+
removeClientFromAllChannels(clientId, userId) {
|
|
117
|
+
const userChannels = this.crudChannels.get(userId);
|
|
118
|
+
if (userChannels) {
|
|
119
|
+
userChannels.forEach((clients, channel) => {
|
|
120
|
+
clients.delete(clientId);
|
|
121
|
+
Adminizer.log.info(`[${this.notificationClass}] Client ${clientId} (user ${userId}) removed from channel ${channel}`);
|
|
122
|
+
// Если в канале больше нет клиентов - удаляем канал
|
|
123
|
+
if (clients.size === 0) {
|
|
124
|
+
userChannels.delete(channel);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
// Если у пользователя больше нет каналов - удаляем запись пользователя
|
|
128
|
+
if (userChannels.size === 0) {
|
|
129
|
+
this.crudChannels.delete(userId);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Переопределяем removeClient для очистки каналов
|
|
134
|
+
removeClient(clientId) {
|
|
135
|
+
// Находим userId по clientId
|
|
136
|
+
let foundUserId = null;
|
|
137
|
+
for (const [userId, userClients] of this.clients.entries()) {
|
|
138
|
+
if (userClients.has(clientId)) {
|
|
139
|
+
foundUserId = userId;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Удаляем клиента из основного хранилища
|
|
144
|
+
super.removeClient(clientId);
|
|
145
|
+
// Удаляем клиента из каналов
|
|
146
|
+
if (foundUserId !== null) {
|
|
147
|
+
this.removeClientFromAllChannels(clientId, foundUserId);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Специальный метод для системных событий с указанием канала
|
|
151
|
+
async logSystemEvent(title, message, channel, metadata) {
|
|
152
|
+
return this.dispatchNotification({
|
|
153
|
+
title: title,
|
|
154
|
+
message: message,
|
|
155
|
+
metadata: metadata,
|
|
156
|
+
channel: channel
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// Методы для CRUD операций
|
|
160
|
+
async logCreatedEvent(title, message, metadata) {
|
|
161
|
+
return this.logSystemEvent(title, message, 'created', metadata);
|
|
162
|
+
}
|
|
163
|
+
async logUpdatedEvent(title, message, metadata) {
|
|
164
|
+
return this.logSystemEvent(title, message, 'updated', metadata);
|
|
165
|
+
}
|
|
166
|
+
async logDeletedEvent(title, message, metadata) {
|
|
167
|
+
return this.logSystemEvent(title, message, 'deleted', metadata);
|
|
168
|
+
}
|
|
169
|
+
// Новый метод для получения каналов пользователя
|
|
170
|
+
getUserChannels(userId) {
|
|
171
|
+
return this.crudChannels.get(userId) || new Map();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -3,8 +3,8 @@ import { InfoBase } from "./abstractInfo";
|
|
|
3
3
|
import { ActionBase } from "./abstractAction";
|
|
4
4
|
import { LinkBase } from "./abstractLink";
|
|
5
5
|
import { CustomBase } from "./abstractCustom";
|
|
6
|
-
import { AdminpanelIcon } from "
|
|
7
|
-
import { Adminizer } from "
|
|
6
|
+
import { AdminpanelIcon } from "../../interfaces/adminpanelConfig";
|
|
7
|
+
import { Adminizer } from "../Adminizer";
|
|
8
8
|
import { UserAP } from "models/UserAP";
|
|
9
9
|
import { I18n } from "../I18n";
|
|
10
10
|
export type WidgetType = (SwitchBase | InfoBase | ActionBase | LinkBase | CustomBase);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { DataTypes } from "sequelize";
|
|
2
|
+
// Creates all system model tables according to src/models/* and
|
|
3
|
+
// SequelizeAdapter.generateSequelizeModel naming: tableName = modelName.toLowerCase()
|
|
4
|
+
// Associations:
|
|
5
|
+
// - UserAP <-> GroupAP: M:N via through table "groupapuserap" (UserAPId, GroupAPId)
|
|
6
|
+
// - MediaManagerAP.parent -> MediaManagerAP (parentId)
|
|
7
|
+
// - MediaManagerAP hasMany MediaManagerMetaAP via parent (MediaManagerMetaAP.parentId)
|
|
8
|
+
// - MediaManagerAP hasMany MediaManagerAssociationsAP via file (MediaManagerAssociationsAP.fileId)
|
|
9
|
+
// - UserNotificationAP belongsTo NotificationAP via alias "notificationId" -> FK column "notificationIdId"
|
|
10
|
+
export async function up({ context }) {
|
|
11
|
+
// userap
|
|
12
|
+
await context.createTable("userap", {
|
|
13
|
+
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
|
|
14
|
+
login: { type: DataTypes.STRING, unique: true },
|
|
15
|
+
fullName: { type: DataTypes.STRING },
|
|
16
|
+
email: { type: DataTypes.STRING },
|
|
17
|
+
avatar: { type: DataTypes.STRING },
|
|
18
|
+
passwordHashed: { type: DataTypes.STRING },
|
|
19
|
+
timezone: { type: DataTypes.STRING },
|
|
20
|
+
expires: { type: DataTypes.STRING },
|
|
21
|
+
locale: { type: DataTypes.STRING },
|
|
22
|
+
isDeleted: { type: DataTypes.BOOLEAN },
|
|
23
|
+
isActive: { type: DataTypes.BOOLEAN },
|
|
24
|
+
isAdministrator: { type: DataTypes.BOOLEAN },
|
|
25
|
+
widgets: { type: DataTypes.JSON },
|
|
26
|
+
isConfirmed: { type: DataTypes.BOOLEAN },
|
|
27
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
28
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
29
|
+
});
|
|
30
|
+
// groupap
|
|
31
|
+
await context.createTable("groupap", {
|
|
32
|
+
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
|
|
33
|
+
name: { type: DataTypes.STRING, unique: true },
|
|
34
|
+
description: { type: DataTypes.STRING },
|
|
35
|
+
tokens: { type: DataTypes.JSON },
|
|
36
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
37
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
38
|
+
});
|
|
39
|
+
// mediamanagerap (self-ref via parentId)
|
|
40
|
+
await context.createTable("mediamanagerap", {
|
|
41
|
+
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, allowNull: false },
|
|
42
|
+
parentId: { type: DataTypes.UUID, allowNull: true, references: { model: "mediamanagerap", key: "id" } },
|
|
43
|
+
mimeType: { type: DataTypes.STRING },
|
|
44
|
+
path: { type: DataTypes.STRING },
|
|
45
|
+
size: { type: DataTypes.INTEGER },
|
|
46
|
+
group: { type: DataTypes.STRING },
|
|
47
|
+
tag: { type: DataTypes.STRING },
|
|
48
|
+
url: { type: DataTypes.STRING },
|
|
49
|
+
filename: { type: DataTypes.STRING },
|
|
50
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
51
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
52
|
+
});
|
|
53
|
+
// mediamanagermetaap (belongsTo mediamanagerap via parentId)
|
|
54
|
+
await context.createTable("mediamanagermetaap", {
|
|
55
|
+
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, allowNull: false },
|
|
56
|
+
key: { type: DataTypes.STRING },
|
|
57
|
+
value: { type: DataTypes.JSON },
|
|
58
|
+
isPublic: { type: DataTypes.BOOLEAN },
|
|
59
|
+
parentId: { type: DataTypes.UUID, allowNull: true, references: { model: "mediamanagerap", key: "id" } },
|
|
60
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
61
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
62
|
+
});
|
|
63
|
+
// mediamanagerassociationsap (belongsTo mediamanagerap via fileId)
|
|
64
|
+
await context.createTable("mediamanagerassociationsap", {
|
|
65
|
+
id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, allowNull: false },
|
|
66
|
+
mediaManagerId: { type: DataTypes.STRING },
|
|
67
|
+
model: { type: DataTypes.JSON },
|
|
68
|
+
modelId: { type: DataTypes.JSON },
|
|
69
|
+
widgetName: { type: DataTypes.STRING },
|
|
70
|
+
sortOrder: { type: DataTypes.INTEGER },
|
|
71
|
+
fileId: { type: DataTypes.UUID, allowNull: true, references: { model: "mediamanagerap", key: "id" } },
|
|
72
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
73
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
74
|
+
});
|
|
75
|
+
// notificationap
|
|
76
|
+
await context.createTable("notificationap", {
|
|
77
|
+
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
|
|
78
|
+
title: { type: DataTypes.STRING },
|
|
79
|
+
message: { type: DataTypes.STRING },
|
|
80
|
+
notificationClass: { type: DataTypes.STRING },
|
|
81
|
+
channel: { type: DataTypes.STRING },
|
|
82
|
+
metadata: { type: DataTypes.JSON },
|
|
83
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
84
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
85
|
+
});
|
|
86
|
+
// usernotificationap (FK to notificationap via column notificationIdId)
|
|
87
|
+
await context.createTable("usernotificationap", {
|
|
88
|
+
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
|
|
89
|
+
userId: { type: DataTypes.INTEGER },
|
|
90
|
+
notificationIdId: { type: DataTypes.INTEGER, allowNull: true, references: { model: "notificationap", key: "id" } },
|
|
91
|
+
read: { type: DataTypes.BOOLEAN },
|
|
92
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
93
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
94
|
+
});
|
|
95
|
+
// navigationap
|
|
96
|
+
await context.createTable("navigationap", {
|
|
97
|
+
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
|
|
98
|
+
label: { type: DataTypes.STRING, unique: true },
|
|
99
|
+
tree: { type: DataTypes.JSON },
|
|
100
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
101
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
102
|
+
});
|
|
103
|
+
// M:N join: GroupAP <-> UserAP via "groupapuserap"
|
|
104
|
+
await context.createTable("groupapuserap", {
|
|
105
|
+
UserAPId: { type: DataTypes.INTEGER, allowNull: false, references: { model: "userap", key: "id" } },
|
|
106
|
+
GroupAPId: { type: DataTypes.INTEGER, allowNull: false, references: { model: "groupap", key: "id" } },
|
|
107
|
+
createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
108
|
+
updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
export async function down({ context }) {
|
|
112
|
+
await context.dropTable("groupapuserap");
|
|
113
|
+
await context.dropTable("usernotificationap");
|
|
114
|
+
await context.dropTable("mediamanagermetaap");
|
|
115
|
+
await context.dropTable("mediamanagerassociationsap");
|
|
116
|
+
await context.dropTable("mediamanagerap");
|
|
117
|
+
await context.dropTable("navigationap");
|
|
118
|
+
await context.dropTable("notificationap");
|
|
119
|
+
await context.dropTable("groupap");
|
|
120
|
+
await context.dropTable("userap");
|
|
121
|
+
}
|
|
@@ -3,10 +3,8 @@ import { MediaManagerMetaAP } from "./MediaManagerMetaAP";
|
|
|
3
3
|
declare const _default: {
|
|
4
4
|
id: {
|
|
5
5
|
type: string;
|
|
6
|
-
|
|
7
|
-
uuid: boolean;
|
|
6
|
+
autoIncrement: boolean;
|
|
8
7
|
primaryKey: boolean;
|
|
9
|
-
required: boolean;
|
|
10
8
|
};
|
|
11
9
|
parent: {
|
|
12
10
|
model: string;
|
|
@@ -44,6 +42,14 @@ declare const _default: {
|
|
|
44
42
|
collection: string;
|
|
45
43
|
via: string;
|
|
46
44
|
};
|
|
45
|
+
createdAt: {
|
|
46
|
+
type: string;
|
|
47
|
+
autoCreatedAt: boolean;
|
|
48
|
+
};
|
|
49
|
+
updatedAt: {
|
|
50
|
+
type: string;
|
|
51
|
+
autoUpdatedAt: boolean;
|
|
52
|
+
};
|
|
47
53
|
};
|
|
48
54
|
export default _default;
|
|
49
55
|
export interface MediaManagerAP {
|
package/models/MediaManagerAP.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
id: {
|
|
3
|
-
type: "
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
primaryKey: true,
|
|
7
|
-
required: true
|
|
3
|
+
type: "number",
|
|
4
|
+
autoIncrement: true,
|
|
5
|
+
primaryKey: true
|
|
8
6
|
},
|
|
9
7
|
parent: {
|
|
10
8
|
model: "MediaManagerAP"
|
|
@@ -41,5 +39,13 @@ export default {
|
|
|
41
39
|
modelAssociation: {
|
|
42
40
|
collection: "MediaManagerAssociationsAP",
|
|
43
41
|
via: "file"
|
|
42
|
+
},
|
|
43
|
+
createdAt: {
|
|
44
|
+
type: 'number',
|
|
45
|
+
autoCreatedAt: true
|
|
46
|
+
},
|
|
47
|
+
updatedAt: {
|
|
48
|
+
type: 'number',
|
|
49
|
+
autoUpdatedAt: true
|
|
44
50
|
}
|
|
45
51
|
};
|
|
@@ -2,10 +2,8 @@ import { MediaManagerAP } from "./MediaManagerAP";
|
|
|
2
2
|
declare const _default: {
|
|
3
3
|
id: {
|
|
4
4
|
type: string;
|
|
5
|
-
|
|
6
|
-
uuid: boolean;
|
|
5
|
+
autoIncrement: boolean;
|
|
7
6
|
primaryKey: boolean;
|
|
8
|
-
required: boolean;
|
|
9
7
|
};
|
|
10
8
|
mediaManagerId: {
|
|
11
9
|
type: string;
|
|
@@ -25,6 +23,14 @@ declare const _default: {
|
|
|
25
23
|
file: {
|
|
26
24
|
model: string;
|
|
27
25
|
};
|
|
26
|
+
createdAt: {
|
|
27
|
+
type: string;
|
|
28
|
+
autoCreatedAt: boolean;
|
|
29
|
+
};
|
|
30
|
+
updatedAt: {
|
|
31
|
+
type: string;
|
|
32
|
+
autoUpdatedAt: boolean;
|
|
33
|
+
};
|
|
28
34
|
};
|
|
29
35
|
export default _default;
|
|
30
36
|
export interface MediaManagerAssociationsAP {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
id: {
|
|
3
|
-
type: "
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
primaryKey: true,
|
|
7
|
-
required: true
|
|
3
|
+
type: "number",
|
|
4
|
+
autoIncrement: true,
|
|
5
|
+
primaryKey: true
|
|
8
6
|
},
|
|
9
7
|
mediaManagerId: {
|
|
10
8
|
type: "string"
|
|
@@ -23,5 +21,13 @@ export default {
|
|
|
23
21
|
},
|
|
24
22
|
file: {
|
|
25
23
|
model: "MediaManagerAP"
|
|
24
|
+
},
|
|
25
|
+
createdAt: {
|
|
26
|
+
type: 'number',
|
|
27
|
+
autoCreatedAt: true
|
|
28
|
+
},
|
|
29
|
+
updatedAt: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
autoUpdatedAt: true
|
|
26
32
|
}
|
|
27
33
|
};
|
|
@@ -2,10 +2,8 @@ import { MediaManagerAP } from "./MediaManagerAP";
|
|
|
2
2
|
declare const _default: {
|
|
3
3
|
id: {
|
|
4
4
|
type: string;
|
|
5
|
-
|
|
6
|
-
uuid: boolean;
|
|
5
|
+
autoIncrement: boolean;
|
|
7
6
|
primaryKey: boolean;
|
|
8
|
-
required: boolean;
|
|
9
7
|
};
|
|
10
8
|
key: {
|
|
11
9
|
type: string;
|
|
@@ -19,6 +17,14 @@ declare const _default: {
|
|
|
19
17
|
parent: {
|
|
20
18
|
model: string;
|
|
21
19
|
};
|
|
20
|
+
createdAt: {
|
|
21
|
+
type: string;
|
|
22
|
+
autoCreatedAt: boolean;
|
|
23
|
+
};
|
|
24
|
+
updatedAt: {
|
|
25
|
+
type: string;
|
|
26
|
+
autoUpdatedAt: boolean;
|
|
27
|
+
};
|
|
22
28
|
};
|
|
23
29
|
export default _default;
|
|
24
30
|
export interface MediaManagerMetaAP {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
id: {
|
|
3
|
-
type: "
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
primaryKey: true,
|
|
7
|
-
required: true
|
|
3
|
+
type: "number",
|
|
4
|
+
autoIncrement: true,
|
|
5
|
+
primaryKey: true
|
|
8
6
|
},
|
|
9
7
|
key: {
|
|
10
8
|
type: "string"
|
|
@@ -17,5 +15,13 @@ export default {
|
|
|
17
15
|
},
|
|
18
16
|
parent: {
|
|
19
17
|
model: "MediaManagerAP"
|
|
18
|
+
},
|
|
19
|
+
createdAt: {
|
|
20
|
+
type: 'number',
|
|
21
|
+
autoCreatedAt: true
|
|
22
|
+
},
|
|
23
|
+
updatedAt: {
|
|
24
|
+
type: 'number',
|
|
25
|
+
autoUpdatedAt: true
|
|
20
26
|
}
|
|
21
27
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Model } from "sequelize";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
id: {
|
|
4
|
+
type: string;
|
|
5
|
+
autoIncrement: boolean;
|
|
6
|
+
primaryKey: boolean;
|
|
7
|
+
};
|
|
8
|
+
title: {
|
|
9
|
+
type: string;
|
|
10
|
+
};
|
|
11
|
+
message: {
|
|
12
|
+
type: string;
|
|
13
|
+
};
|
|
14
|
+
notificationClass: {
|
|
15
|
+
type: string;
|
|
16
|
+
};
|
|
17
|
+
channel: {
|
|
18
|
+
type: string;
|
|
19
|
+
};
|
|
20
|
+
metadata: {
|
|
21
|
+
type: string;
|
|
22
|
+
};
|
|
23
|
+
createdAt: {
|
|
24
|
+
type: string;
|
|
25
|
+
autoCreatedAt: boolean;
|
|
26
|
+
};
|
|
27
|
+
updatedAt: {
|
|
28
|
+
type: string;
|
|
29
|
+
autoUpdatedAt: boolean;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export default _default;
|
|
33
|
+
export interface NotificationAP {
|
|
34
|
+
id: string;
|
|
35
|
+
title: string;
|
|
36
|
+
message: string;
|
|
37
|
+
channel: string;
|
|
38
|
+
notificationClass: string;
|
|
39
|
+
metadata?: Record<string, unknown>;
|
|
40
|
+
createdAt: Date;
|
|
41
|
+
}
|
|
42
|
+
export interface NotificationAPModel extends Model<NotificationAP>, NotificationAP {
|
|
43
|
+
toJSON(): NotificationAP;
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: {
|
|
3
|
+
type: "number",
|
|
4
|
+
autoIncrement: true,
|
|
5
|
+
primaryKey: true
|
|
6
|
+
},
|
|
7
|
+
title: {
|
|
8
|
+
type: "string"
|
|
9
|
+
},
|
|
10
|
+
message: {
|
|
11
|
+
type: "string"
|
|
12
|
+
},
|
|
13
|
+
notificationClass: {
|
|
14
|
+
type: "string",
|
|
15
|
+
},
|
|
16
|
+
channel: {
|
|
17
|
+
type: "string",
|
|
18
|
+
},
|
|
19
|
+
metadata: {
|
|
20
|
+
type: 'json'
|
|
21
|
+
},
|
|
22
|
+
createdAt: {
|
|
23
|
+
type: 'number',
|
|
24
|
+
autoCreatedAt: true
|
|
25
|
+
},
|
|
26
|
+
updatedAt: {
|
|
27
|
+
type: 'number',
|
|
28
|
+
autoUpdatedAt: true
|
|
29
|
+
}
|
|
30
|
+
};
|
package/models/UserAP.d.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { NotificationAP } from "./NotificationAP";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
id: {
|
|
4
|
+
type: string;
|
|
5
|
+
autoIncrement: boolean;
|
|
6
|
+
primaryKey: boolean;
|
|
7
|
+
};
|
|
8
|
+
userId: {
|
|
9
|
+
type: string;
|
|
10
|
+
required: boolean;
|
|
11
|
+
};
|
|
12
|
+
notificationId: {
|
|
13
|
+
model: string;
|
|
14
|
+
};
|
|
15
|
+
read: {
|
|
16
|
+
type: string;
|
|
17
|
+
defaultsTo: boolean;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export default _default;
|
|
21
|
+
export interface UserNotificationAP {
|
|
22
|
+
id: number;
|
|
23
|
+
userId: number;
|
|
24
|
+
notificationId: NotificationAP;
|
|
25
|
+
read: boolean;
|
|
26
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: {
|
|
3
|
+
type: "number",
|
|
4
|
+
autoIncrement: true,
|
|
5
|
+
primaryKey: true
|
|
6
|
+
},
|
|
7
|
+
userId: {
|
|
8
|
+
type: "number",
|
|
9
|
+
required: true
|
|
10
|
+
},
|
|
11
|
+
notificationId: {
|
|
12
|
+
model: "NotificationAP"
|
|
13
|
+
},
|
|
14
|
+
read: {
|
|
15
|
+
type: "boolean",
|
|
16
|
+
defaultsTo: false
|
|
17
|
+
}
|
|
18
|
+
};
|