adminizer 4.3.0-build.80 → 4.3.0-build.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/assets/add-ChaPnvFv.js +1 -0
  2. package/assets/{add-form-C04ZI5LT.js → add-form-DNqlORQQ.js} +1 -1
  3. package/assets/add-group-D6YsQVrC.js +1 -0
  4. package/assets/{add-group-form-CyRwxTs3.js → add-group-form-CDi1y4af.js} +1 -1
  5. package/assets/{add-user-form-yp020h4r.js → add-user-form-BzXHahSY.js} +1 -1
  6. package/assets/add-user-psdNyGx8.js +1 -0
  7. package/assets/{app-CpGtjhxF.css → app-PLVuwM-H.css} +1 -1
  8. package/assets/{app-layout-BmT5KQwc.js → app-layout-AWzEe1aH.js} +1 -1
  9. package/assets/{app-sidebar-4lm9f_CG.js → app-sidebar-Bd4nWVXq.js} +1 -1
  10. package/assets/app-sidebar-header-jBFp1qZb.js +1 -0
  11. package/assets/app.js +3 -3
  12. package/assets/{catalog-CG_EB2kz.js → catalog-XiWBZptC.js} +1 -1
  13. package/assets/{dashboard-CsmJfdLb.js → dashboard-DcRJErQB.js} +1 -1
  14. package/assets/date-picker-A6CYw4SC.js +1 -0
  15. package/assets/del-modal-0klf0PNC.js +1 -0
  16. package/assets/{field-renderer-Bp1lfm0v.js → field-renderer-CYB5W2He.js} +3 -3
  17. package/assets/form-B-he6_tT.js +1 -0
  18. package/assets/{form-CSTeMDf5.js → form-BGRpsR-M.js} +1 -1
  19. package/assets/{home-D00XjLjD.js → home-B7aZTHTv.js} +2 -2
  20. package/assets/icon-k6999vVE.js +1 -0
  21. package/assets/{init-user-L-oxFTOv.js → init-user-Btm16ElL.js} +1 -1
  22. package/assets/input-error-Dbp_lp61.js +1 -0
  23. package/assets/list-_tZumymo.js +1 -0
  24. package/assets/{list-table-vIvydJV2.js → list-table-OzVUH7i4.js} +4 -4
  25. package/assets/{login-DLMJ6l_r.js → login-DeqxLVx3.js} +1 -1
  26. package/assets/manifest.json +74 -74
  27. package/assets/material-icon-B9BY_7p9.js +1 -0
  28. package/assets/{media-manager-ASGJ4PcS.js → media-manager-DQ5CA_na.js} +1 -1
  29. package/assets/{module-mxngd2cA.js → module-Drcr0QjC.js} +1 -1
  30. package/assets/{nav-footer-DbGCtmmN.js → nav-footer-DWHxIgb7.js} +1 -1
  31. package/assets/{nav-main-BcWhl71g.js → nav-main-CRT9ezos.js} +1 -1
  32. package/assets/notification-C7K-zK4k.js +27 -0
  33. package/assets/{register-C_W_hOmq.js → register-CMhPasDj.js} +1 -1
  34. package/assets/tabs-GDFuClHU.js +1 -0
  35. package/assets/{theme-switcher-D1G6OSMc.js → theme-switcher-C35zBCil.js} +1 -1
  36. package/assets/{welcome-FHRCdke0.js → welcome-CbhDDQlg.js} +1 -1
  37. package/controllers/add.js +1 -1
  38. package/controllers/catalog/FrontentCatalogAdapter.d.ts +4 -4
  39. package/controllers/edit.js +1 -15
  40. package/controllers/list.js +2 -2
  41. package/controllers/login.js +2 -2
  42. package/controllers/navigation/edit.js +1 -1
  43. package/controllers/notifications/NotificationController.d.ts +5 -5
  44. package/controllers/notifications/NotificationController.js +77 -78
  45. package/controllers/remove.js +1 -11
  46. package/controllers/view.js +1 -1
  47. package/helpers/configHelper.d.ts +1 -1
  48. package/helpers/fieldsHelper.d.ts +1 -1
  49. package/helpers/fieldsHelper.js +1 -1
  50. package/helpers/inertiaAddHelper.d.ts +1 -1
  51. package/helpers/translationHelper.d.ts +1 -1
  52. package/helpers/translationHelper.js +1 -1
  53. package/index.d.ts +14 -13
  54. package/index.js +14 -13
  55. package/interfaces/adminpanelConfig.d.ts +1 -1
  56. package/interfaces/global.d.ts +3 -3
  57. package/interfaces/types.d.ts +10 -1
  58. package/lib/Adminizer.d.ts +7 -7
  59. package/lib/Adminizer.js +7 -7
  60. package/lib/{v4/DataAccessor.d.ts → DataAccessor.d.ts} +4 -4
  61. package/lib/{v4/DataAccessor.js → DataAccessor.js} +3 -3
  62. package/lib/{v4/I18n.js → I18n.js} +2 -2
  63. package/lib/{v4/PolicyManager.d.ts → PolicyManager.d.ts} +1 -1
  64. package/lib/{v4/PolicyManager.js → PolicyManager.js} +2 -2
  65. package/lib/{v4/catalog → catalog}/AbstractCatalog.d.ts +1 -1
  66. package/lib/{v4/catalog → catalog}/Navigation.d.ts +2 -2
  67. package/lib/{v4/catalog → catalog}/Navigation.js +1 -1
  68. package/lib/{v4/controls → controls}/AbstractControls.d.ts +1 -1
  69. package/lib/{v4/controls → controls}/codeEditor/MonacoEditor.d.ts +1 -1
  70. package/lib/{v4/controls → controls}/geojsoneditor/GeoEditor.d.ts +1 -1
  71. package/lib/{v4/controls → controls}/jsoneditor/JsonEditor.d.ts +1 -1
  72. package/lib/{v4/controls → controls}/markdown/ToastUiEditor.d.ts +1 -1
  73. package/lib/{v4/controls → controls}/table/Handsontable.d.ts +1 -1
  74. package/lib/{v4/controls → controls}/wysiwyg/CKeditor.d.ts +1 -1
  75. package/lib/{v4/datatable → datatable}/NodeTable.d.ts +1 -1
  76. package/lib/{v4/model → model}/AbstractModel.d.ts +12 -0
  77. package/lib/model/AbstractModel.js +178 -0
  78. package/lib/{v4/model → model}/ModelHandler.js +1 -1
  79. package/lib/{v4/model → model}/adapter/sequelize.d.ts +0 -1
  80. package/lib/{v4/model → model}/adapter/sequelize.js +6 -3
  81. package/lib/{v4/notifications → notifications}/AbstractNotificationService.d.ts +14 -7
  82. package/lib/notifications/AbstractNotificationService.js +233 -0
  83. package/lib/{v4/notifications → notifications}/GeneralNotificationService.d.ts +1 -1
  84. package/lib/{v4/notifications → notifications}/GeneralNotificationService.js +4 -2
  85. package/lib/notifications/NotificationHandler.d.ts +27 -0
  86. package/lib/notifications/NotificationHandler.js +41 -0
  87. package/lib/{v4/notifications → notifications}/SystemNotificationService.d.ts +5 -4
  88. package/lib/notifications/SystemNotificationService.js +173 -0
  89. package/lib/{v4/widgets → widgets}/abstractCustom.d.ts +1 -1
  90. package/lib/{v4/widgets → widgets}/abstractLink.d.ts +1 -1
  91. package/lib/{v4/widgets → widgets}/abstractWidgetBase.d.ts +1 -1
  92. package/lib/{v4/widgets → widgets}/widgetHandler.d.ts +2 -2
  93. package/migrations/index.d.ts +3 -0
  94. package/migrations/index.js +4 -0
  95. package/migrations/index.ts +5 -0
  96. package/migrations/umzug/0001.d.ts +7 -0
  97. package/migrations/umzug/0001.js +119 -0
  98. package/migrations/umzug/0001.ts +132 -0
  99. package/migrations/umzug.d.ts +2 -0
  100. package/migrations/umzug.js +8 -0
  101. package/migrations/umzug.ts +9 -0
  102. package/models/NotificationAP.d.ts +8 -0
  103. package/models/NotificationAP.js +8 -0
  104. package/models/UserAP.d.ts +1 -1
  105. package/package.json +5 -4
  106. package/system/Router.js +4 -8
  107. package/system/bindControls.js +6 -6
  108. package/system/bindInertia.js +4 -3
  109. package/system/bindNavigation.js +1 -1
  110. package/system/bindNotifications.js +3 -3
  111. package/system/bindReqFunctions.js +8 -25
  112. package/system/defaults.js +1 -1
  113. package/ui/components/ui/table.d.ts +1 -1
  114. package/ui/components/ui/table.js +2 -2
  115. package/assets/add-DSapOiv0.js +0 -1
  116. package/assets/add-group-DWR7SBTO.js +0 -1
  117. package/assets/add-user-acATGxUL.js +0 -1
  118. package/assets/app-sidebar-header-CxXmzszq.js +0 -1
  119. package/assets/date-picker-By3kj-Rx.js +0 -1
  120. package/assets/del-modal-DlcbcdR5.js +0 -1
  121. package/assets/form-CxHRGp7p.js +0 -1
  122. package/assets/icon-ButfCBrt.js +0 -1
  123. package/assets/input-error-CHsDLcK0.js +0 -1
  124. package/assets/list-4TOTsjqE.js +0 -1
  125. package/assets/material-icon-sXk4BK-N.js +0 -1
  126. package/assets/notification-BEfA5sT6.js +0 -1
  127. package/assets/tabs-CgZW_LLn.js +0 -1
  128. package/lib/v4/model/AbstractModel.js +0 -79
  129. package/lib/v4/notifications/AbstractNotificationService.js +0 -150
  130. package/lib/v4/notifications/NotificationHandler.d.ts +0 -69
  131. package/lib/v4/notifications/NotificationHandler.js +0 -127
  132. package/lib/v4/notifications/SystemNotificationService.js +0 -124
  133. /package/lib/{v4/I18n.d.ts → I18n.d.ts} +0 -0
  134. /package/lib/{v4/POWCaptcha.d.ts → POWCaptcha.d.ts} +0 -0
  135. /package/lib/{v4/POWCaptcha.js → POWCaptcha.js} +0 -0
  136. /package/lib/{v4/catalog → catalog}/AbstractCatalog.js +0 -0
  137. /package/lib/{v4/catalog → catalog}/CatalogHandler.d.ts +0 -0
  138. /package/lib/{v4/catalog → catalog}/CatalogHandler.js +0 -0
  139. /package/lib/{v4/controls → controls}/AbstractControls.js +0 -0
  140. /package/lib/{v4/controls → controls}/ControlsHandler.d.ts +0 -0
  141. /package/lib/{v4/controls → controls}/ControlsHandler.js +0 -0
  142. /package/lib/{v4/controls → controls}/codeEditor/MonacoEditor.js +0 -0
  143. /package/lib/{v4/controls → controls}/geojsoneditor/GeoEditor.js +0 -0
  144. /package/lib/{v4/controls → controls}/jsoneditor/JsonEditor.js +0 -0
  145. /package/lib/{v4/controls → controls}/markdown/ToastUiEditor.js +0 -0
  146. /package/lib/{v4/controls → controls}/table/Handsontable.js +0 -0
  147. /package/lib/{v4/controls → controls}/wysiwyg/CKeditor.js +0 -0
  148. /package/lib/{v4/datatable → datatable}/NodeTable.js +0 -0
  149. /package/lib/{v4/helper → helper}/jwt.d.ts +0 -0
  150. /package/lib/{v4/helper → helper}/jwt.js +0 -0
  151. /package/lib/{v4/inertia → inertia}/flash.d.ts +0 -0
  152. /package/lib/{v4/inertia → inertia}/flash.js +0 -0
  153. /package/lib/{v4/inertia → inertia}/inertiaAdapter.d.ts +0 -0
  154. /package/lib/{v4/inertia → inertia}/inertiaAdapter.js +0 -0
  155. /package/lib/{v4/model → model}/ModelHandler.d.ts +0 -0
  156. /package/lib/{v4/model → model}/adapter/waterline.d.ts +0 -0
  157. /package/lib/{v4/model → model}/adapter/waterline.js +0 -0
  158. /package/lib/{v4/widgets → widgets}/abstractAction.d.ts +0 -0
  159. /package/lib/{v4/widgets → widgets}/abstractAction.js +0 -0
  160. /package/lib/{v4/widgets → widgets}/abstractCustom.js +0 -0
  161. /package/lib/{v4/widgets → widgets}/abstractInfo.d.ts +0 -0
  162. /package/lib/{v4/widgets → widgets}/abstractInfo.js +0 -0
  163. /package/lib/{v4/widgets → widgets}/abstractLink.js +0 -0
  164. /package/lib/{v4/widgets → widgets}/abstractSwitch.d.ts +0 -0
  165. /package/lib/{v4/widgets → widgets}/abstractSwitch.js +0 -0
  166. /package/lib/{v4/widgets → widgets}/abstractWidgetBase.js +0 -0
  167. /package/lib/{v4/widgets → widgets}/widgetHandler.js +0 -0
@@ -0,0 +1,41 @@
1
+ import { EventEmitter } from 'events';
2
+ import { Adminizer } from '../Adminizer';
3
+ export class NotificationHandler extends EventEmitter {
4
+ services = new Map();
5
+ constructor() {
6
+ super();
7
+ }
8
+ /**
9
+ * Register a new notification service
10
+ * @param service
11
+ */
12
+ registerService(service) {
13
+ this.services.set(service.notificationClass, service);
14
+ Adminizer.log.info(`Notification service registered: ${service.notificationClass}`);
15
+ }
16
+ /**
17
+ * Get a notification service by class
18
+ * @param notificationClass
19
+ */
20
+ getService(notificationClass) {
21
+ return this.services.get(notificationClass);
22
+ }
23
+ /**
24
+ * Get all registered services
25
+ */
26
+ getAllServices() {
27
+ return Array.from(this.services.values());
28
+ }
29
+ /**
30
+ * Dispatch a notification to a service
31
+ * @param notificationClass
32
+ * @param notification
33
+ */
34
+ async dispatchNotification(notificationClass, notification) {
35
+ const service = this.getService(notificationClass);
36
+ if (!service) {
37
+ throw new Error(`Notification service not found: ${notificationClass}`);
38
+ }
39
+ return service.dispatchNotification(notification);
40
+ }
41
+ }
@@ -1,5 +1,5 @@
1
1
  import { AbstractNotificationService } from './AbstractNotificationService';
2
- import { INotification } from '../../../interfaces/types';
2
+ import { INotification } from '../../interfaces/types';
3
3
  export declare class SystemNotificationService extends AbstractNotificationService {
4
4
  readonly notificationClass = "system";
5
5
  readonly icon: string;
@@ -7,12 +7,13 @@ export declare class SystemNotificationService extends AbstractNotificationServi
7
7
  private crudChannels;
8
8
  dispatchNotification(notification: Omit<INotification, 'id' | 'createdAt' | 'notificationClass' | 'icon'>): Promise<boolean>;
9
9
  private broadcastToChannel;
10
- addClientToChannel(clientId: string, channel: string): void;
11
- removeClientFromChannel(clientId: string, channel: string): void;
12
- removeClientFromAllChannels(clientId: string): void;
10
+ addClientToChannel(clientId: string, channel: string, userId: number): void;
11
+ removeClientFromChannel(clientId: string, channel: string, userId: number): void;
12
+ removeClientFromAllChannels(clientId: string, userId: number): void;
13
13
  removeClient(clientId: string): void;
14
14
  logSystemEvent(title: string, message: string, channel?: string, metadata?: Record<string | number, any>): Promise<boolean>;
15
15
  logCreatedEvent(title: string, message: string, metadata?: Record<string | number, any>): Promise<boolean>;
16
16
  logUpdatedEvent(title: string, message: string, metadata?: Record<string | number, any>): Promise<boolean>;
17
17
  logDeletedEvent(title: string, message: string, metadata?: Record<string | number, any>): Promise<boolean>;
18
+ getUserChannels(userId: number): Map<string, Set<string>>;
18
19
  }
@@ -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
+ }
@@ -1,4 +1,4 @@
1
- import { MaterialIcon } from "../../../interfaces/MaaterialIcons";
1
+ import { MaterialIcon } from "../../interfaces/MaaterialIcons";
2
2
  export declare abstract class CustomBase {
3
3
  /** Widget unique id */
4
4
  abstract readonly id: string;
@@ -1,5 +1,5 @@
1
1
  import { BaseWidget } from "./abstractWidgetBase";
2
- import { MaterialIcon } from "../../../interfaces/MaaterialIcons";
2
+ import { MaterialIcon } from "../../interfaces/MaaterialIcons";
3
3
  export interface Links {
4
4
  name: string;
5
5
  description: string;
@@ -1,4 +1,4 @@
1
- import { MaterialIcon } from "../../../interfaces/MaaterialIcons";
1
+ import { MaterialIcon } from "../../interfaces/MaaterialIcons";
2
2
  export declare abstract class BaseWidget {
3
3
  /** Widget unique id */
4
4
  abstract readonly id: string;
@@ -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 "../../../interfaces/adminpanelConfig";
7
- import { Adminizer } from "../../Adminizer";
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,3 @@
1
+ export declare const migrations: {
2
+ umzug: import("..").Migration[];
3
+ };
@@ -0,0 +1,4 @@
1
+ import { migrationsUmzug as umzug } from "./umzug";
2
+ export const migrations = {
3
+ umzug
4
+ };
@@ -0,0 +1,5 @@
1
+ import { migrationsUmzug as umzug } from "./umzug";
2
+
3
+ export const migrations = {
4
+ umzug
5
+ }
@@ -0,0 +1,7 @@
1
+ import { QueryInterface } from "sequelize";
2
+ type Ctx = {
3
+ context: QueryInterface;
4
+ };
5
+ export declare function up({ context }: Ctx): Promise<void>;
6
+ export declare function down({ context }: Ctx): Promise<void>;
7
+ export {};
@@ -0,0 +1,119 @@
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
+ });
108
+ }
109
+ export async function down({ context }) {
110
+ await context.dropTable("groupapuserap");
111
+ await context.dropTable("usernotificationap");
112
+ await context.dropTable("mediamanagermetaap");
113
+ await context.dropTable("mediamanagerassociationsap");
114
+ await context.dropTable("mediamanagerap");
115
+ await context.dropTable("navigationap");
116
+ await context.dropTable("notificationap");
117
+ await context.dropTable("groupap");
118
+ await context.dropTable("userap");
119
+ }
@@ -0,0 +1,132 @@
1
+ import { QueryInterface, DataTypes } from "sequelize";
2
+
3
+ type Ctx = { context: QueryInterface };
4
+
5
+ // Creates all system model tables according to src/models/* and
6
+ // SequelizeAdapter.generateSequelizeModel naming: tableName = modelName.toLowerCase()
7
+ // Associations:
8
+ // - UserAP <-> GroupAP: M:N via through table "groupapuserap" (UserAPId, GroupAPId)
9
+ // - MediaManagerAP.parent -> MediaManagerAP (parentId)
10
+ // - MediaManagerAP hasMany MediaManagerMetaAP via parent (MediaManagerMetaAP.parentId)
11
+ // - MediaManagerAP hasMany MediaManagerAssociationsAP via file (MediaManagerAssociationsAP.fileId)
12
+ // - UserNotificationAP belongsTo NotificationAP via alias "notificationId" -> FK column "notificationIdId"
13
+
14
+ export async function up({ context }: Ctx): Promise<void> {
15
+ // userap
16
+ await context.createTable("userap", {
17
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
18
+ login: { type: DataTypes.STRING, unique: true },
19
+ fullName: { type: DataTypes.STRING },
20
+ email: { type: DataTypes.STRING },
21
+ avatar: { type: DataTypes.STRING },
22
+ passwordHashed: { type: DataTypes.STRING },
23
+ timezone: { type: DataTypes.STRING },
24
+ expires: { type: DataTypes.STRING },
25
+ locale: { type: DataTypes.STRING },
26
+ isDeleted: { type: DataTypes.BOOLEAN },
27
+ isActive: { type: DataTypes.BOOLEAN },
28
+ isAdministrator: { type: DataTypes.BOOLEAN },
29
+ widgets: { type: DataTypes.JSON },
30
+ isConfirmed: { type: DataTypes.BOOLEAN },
31
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
32
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
33
+ });
34
+
35
+ // groupap
36
+ await context.createTable("groupap", {
37
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
38
+ name: { type: DataTypes.STRING, unique: true },
39
+ description: { type: DataTypes.STRING },
40
+ tokens: { type: DataTypes.JSON },
41
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
42
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
43
+ });
44
+
45
+ // mediamanagerap (self-ref via parentId)
46
+ await context.createTable("mediamanagerap", {
47
+ id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, allowNull: false },
48
+ parentId: { type: DataTypes.UUID, allowNull: true, references: { model: "mediamanagerap", key: "id" } },
49
+ mimeType: { type: DataTypes.STRING },
50
+ path: { type: DataTypes.STRING },
51
+ size: { type: DataTypes.INTEGER },
52
+ group: { type: DataTypes.STRING },
53
+ tag: { type: DataTypes.STRING },
54
+ url: { type: DataTypes.STRING },
55
+ filename: { type: DataTypes.STRING },
56
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
57
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
58
+ });
59
+
60
+ // mediamanagermetaap (belongsTo mediamanagerap via parentId)
61
+ await context.createTable("mediamanagermetaap", {
62
+ id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, allowNull: false },
63
+ key: { type: DataTypes.STRING },
64
+ value: { type: DataTypes.JSON },
65
+ isPublic: { type: DataTypes.BOOLEAN },
66
+ parentId: { type: DataTypes.UUID, allowNull: true, references: { model: "mediamanagerap", key: "id" } },
67
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
68
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
69
+ });
70
+
71
+ // mediamanagerassociationsap (belongsTo mediamanagerap via fileId)
72
+ await context.createTable("mediamanagerassociationsap", {
73
+ id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, allowNull: false },
74
+ mediaManagerId: { type: DataTypes.STRING },
75
+ model: { type: DataTypes.JSON },
76
+ modelId: { type: DataTypes.JSON },
77
+ widgetName: { type: DataTypes.STRING },
78
+ sortOrder: { type: DataTypes.INTEGER },
79
+ fileId: { type: DataTypes.UUID, allowNull: true, references: { model: "mediamanagerap", key: "id" } },
80
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
81
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
82
+ });
83
+
84
+ // notificationap
85
+ await context.createTable("notificationap", {
86
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
87
+ title: { type: DataTypes.STRING },
88
+ message: { type: DataTypes.STRING },
89
+ notificationClass: { type: DataTypes.STRING },
90
+ channel: { type: DataTypes.STRING },
91
+ metadata: { type: DataTypes.JSON },
92
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
93
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
94
+ });
95
+
96
+ // usernotificationap (FK to notificationap via column notificationIdId)
97
+ await context.createTable("usernotificationap", {
98
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
99
+ userId: { type: DataTypes.INTEGER },
100
+ notificationIdId: { type: DataTypes.INTEGER, allowNull: true, references: { model: "notificationap", key: "id" } },
101
+ read: { type: DataTypes.BOOLEAN },
102
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
103
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
104
+ });
105
+
106
+ // navigationap
107
+ await context.createTable("navigationap", {
108
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, allowNull: false },
109
+ label: { type: DataTypes.STRING, unique: true },
110
+ tree: { type: DataTypes.JSON },
111
+ createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
112
+ updatedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
113
+ });
114
+
115
+ // M:N join: GroupAP <-> UserAP via "groupapuserap"
116
+ await context.createTable("groupapuserap", {
117
+ UserAPId: { type: DataTypes.INTEGER, allowNull: false, references: { model: "userap", key: "id" } },
118
+ GroupAPId: { type: DataTypes.INTEGER, allowNull: false, references: { model: "groupap", key: "id" } },
119
+ });
120
+ }
121
+
122
+ export async function down({ context }: Ctx): Promise<void> {
123
+ await context.dropTable("groupapuserap");
124
+ await context.dropTable("usernotificationap");
125
+ await context.dropTable("mediamanagermetaap");
126
+ await context.dropTable("mediamanagerassociationsap");
127
+ await context.dropTable("mediamanagerap");
128
+ await context.dropTable("navigationap");
129
+ await context.dropTable("notificationap");
130
+ await context.dropTable("groupap");
131
+ await context.dropTable("userap");
132
+ }
@@ -0,0 +1,2 @@
1
+ import { Migration } from "interfaces/types";
2
+ export declare const migrationsUmzug: Migration[];
@@ -0,0 +1,8 @@
1
+ import { up as up0001, down as down0001 } from "./umzug/0001";
2
+ export const migrationsUmzug = [
3
+ {
4
+ name: "0001",
5
+ up: up0001,
6
+ down: down0001
7
+ }
8
+ ];
@@ -0,0 +1,9 @@
1
+ import { Migration } from "interfaces/types"
2
+ import {up as up0001, down as down0001 } from "./umzug/0001"
3
+ export const migrationsUmzug: Migration[] = [
4
+ {
5
+ name: "0001",
6
+ up: up0001,
7
+ down: down0001
8
+ }
9
+ ]
@@ -20,6 +20,14 @@ declare const _default: {
20
20
  metadata: {
21
21
  type: string;
22
22
  };
23
+ createdAt: {
24
+ type: string;
25
+ autoCreatedAt: boolean;
26
+ };
27
+ updatedAt: {
28
+ type: string;
29
+ autoUpdatedAt: boolean;
30
+ };
23
31
  };
24
32
  export default _default;
25
33
  export interface NotificationAP {
@@ -18,5 +18,13 @@ export default {
18
18
  },
19
19
  metadata: {
20
20
  type: 'json'
21
+ },
22
+ createdAt: {
23
+ type: 'number',
24
+ autoCreatedAt: true
25
+ },
26
+ updatedAt: {
27
+ type: 'number',
28
+ autoUpdatedAt: true
21
29
  }
22
30
  };
@@ -1,4 +1,4 @@
1
- import { WidgetConfig, WidgetsLayouts } from "lib/v4/widgets/widgetHandler";
1
+ import { WidgetConfig, WidgetsLayouts } from "lib/widgets/widgetHandler";
2
2
  import { GroupAP } from "./GroupAP";
3
3
  declare const _default: {
4
4
  id: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "adminizer",
3
3
  "type": "module",
4
- "version": "4.3.0-build.80",
4
+ "version": "4.3.0-build.81",
5
5
  "main": "index.js",
6
6
  "exports": {
7
7
  ".": "./index.js",
@@ -15,6 +15,7 @@
15
15
  "dev:no-seed": "cross-env VITE_ENV=dev NO_SEED_DATA=true ORM=sequelize tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
16
16
  "dev:no-seed-clean": "cross-env VITE_ENV=dev NO_SEED_DATA=true CLEAN_TMP=true ORM=sequelize tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
17
17
  "dev:waterline": "cross-env VITE_ENV=dev ORM=waterline tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
18
+ "dev:waterline:no-seed": "cross-env VITE_ENV=dev NO_SEED_DATA=true ORM=waterline tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
18
19
  "build:assets": "vite build",
19
20
  "compile:backend": "tsc -p src/tsconfig.json",
20
21
  "compile:ui": "tsc -p tsconfig.ui.json",
@@ -67,12 +68,11 @@
67
68
  "react-dnd": "^16.0.1",
68
69
  "reflect-metadata": "^0.2.2",
69
70
  "sharp": "^0.33.5",
71
+ "sprintf-js": "^1.1.3",
70
72
  "typeorm": "^0.3.20",
71
73
  "uuid": "^11.0.5",
72
74
  "waterline": "^0.15.2",
73
- "winston": "^3.17.0",
74
- "sprintf-js": "^1.1.3",
75
- "sequelize": "^6.37.7"
75
+ "winston": "^3.17.0"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@babel/plugin-proposal-decorators": "^7.27.1",
@@ -147,6 +147,7 @@
147
147
  "sails-disk": "^2.1.2",
148
148
  "sails-postgresql": "^5.0.1",
149
149
  "sequelize-typescript": "^2.1.6",
150
+ "sequelize": "^6.37.7",
150
151
  "shelljs": "^0.9.2",
151
152
  "sonner": "^2.0.3",
152
153
  "sqlite3": "^5.1.7",