adminizer 4.4.0-build.153 → 4.4.0-build.155
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-CohxwHV4.js → add-WS8qGCdZ.js} +1 -1
- package/assets/{add-form-jLwBgqxD.js → add-form-D-yC67U1.js} +1 -1
- package/assets/{app-mw7Ur3rJ.css → app-CFt5jdVM.css} +1 -1
- package/assets/app.js +2 -2
- package/assets/{catalog-lfHtOKlW.js → catalog-xElikv0n.js} +1 -1
- package/assets/{field-renderer-BTbMeyVH.js → field-renderer-5eDbYf4v.js} +65 -65
- package/assets/{form-WmXKykFy.js → form-CsehoH9m.js} +1 -1
- package/assets/{form-DEDPXI5l.js → form-HOkteeF9.js} +1 -1
- package/assets/{home-BDd8zDuH.js → home-Cw9UXSLl.js} +2 -2
- package/assets/manifest.json +17 -17
- package/assets/{media-manager-CcPYTimK.js → media-manager-Bq3fLKR0.js} +3 -3
- package/controllers/media-manager/mediaManagerAdapter.js +2 -1
- package/lib/media-manager/AbstractMediaManager.d.ts +1 -0
- package/lib/media-manager/DefaultMediaManager.js +1 -0
- package/lib/model/adapter/waterline.d.ts +1 -1
- package/lib/model/adapter/waterline.js +14 -3
- package/lib/notifications/AbstractNotificationService.d.ts +25 -0
- package/lib/notifications/AbstractNotificationService.js +57 -0
- package/package.json +1 -1
- package/translations/en.json +7 -6
- package/translations/ru.json +2 -1
|
@@ -8,7 +8,7 @@ export declare class WaterlineModel<T> extends AbstractModel<T> {
|
|
|
8
8
|
/** Custom populate all function */
|
|
9
9
|
private populateAll;
|
|
10
10
|
protected _findOne(criteria: Partial<T>): Promise<T | null>;
|
|
11
|
-
protected _find(criteria?: Partial<
|
|
11
|
+
protected _find(criteria?: Partial<any>, options?: FindOptions): Promise<T[]>;
|
|
12
12
|
protected _updateOne(criteria: Partial<T>, data: Partial<T>): Promise<T | null>;
|
|
13
13
|
protected _update(criteria: Partial<T>, data: Partial<T>): Promise<T[]>;
|
|
14
14
|
protected _destroyOne(criteria: Partial<T>): Promise<T | null>;
|
|
@@ -36,9 +36,20 @@ export class WaterlineModel extends AbstractModel {
|
|
|
36
36
|
// Hack
|
|
37
37
|
const attributes = this.model.attributes;
|
|
38
38
|
const associations = Object.keys(attributes).filter(attr => attributes[attr].model || attributes[attr].collection);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
criteria
|
|
39
|
+
if (JSON.stringify(criteria.where) === '{}') {
|
|
40
|
+
let sortField;
|
|
41
|
+
if (criteria?.sort) {
|
|
42
|
+
if (typeof criteria.sort === 'string') {
|
|
43
|
+
sortField = criteria.sort.split(' ')[0];
|
|
44
|
+
}
|
|
45
|
+
else if (Array.isArray(criteria.sort)) {
|
|
46
|
+
sortField = criteria.sort[0];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (sortField && associations.includes(sortField)) {
|
|
50
|
+
criteria.sort = undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
42
53
|
let query = this.model.find(criteria);
|
|
43
54
|
if (options.populate && Array.isArray(options.populate) && options.populate.length > 0) {
|
|
44
55
|
options.populate.forEach(([field, populateCriteria]) => {
|
|
@@ -161,4 +161,29 @@ export declare abstract class AbstractNotificationService extends EventEmitter {
|
|
|
161
161
|
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
|
162
162
|
*/
|
|
163
163
|
markAllAsRead(userId: number): Promise<void>;
|
|
164
|
+
/**
|
|
165
|
+
* Returns the count of user notifications: all notifications or only unread ones.
|
|
166
|
+
* If unreadOnly is true, returns the number of unread notifications.
|
|
167
|
+
* If unreadOnly is false, returns the total number of notifications (read + unread) associated with the user.
|
|
168
|
+
*
|
|
169
|
+
* @param {number} userId - The ID of the user whose notification count is requested.
|
|
170
|
+
* @param {boolean} [unreadOnly=false] - If true, counts only unread notifications; if false, counts all notifications.
|
|
171
|
+
* @returns {Promise<number>} A promise that resolves with the number of matching notifications.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* const total = await service.getNotificationsCount(123); // all notifications
|
|
175
|
+
* const unreadCount = await service.getNotificationsCount(123, true); // only unread
|
|
176
|
+
*/
|
|
177
|
+
getNotificationsCount(userId: number, unreadOnly?: boolean): Promise<number>;
|
|
178
|
+
/**
|
|
179
|
+
* Convenience method to get the number of unread notifications for a user.
|
|
180
|
+
* Equivalent to calling getNotificationsCount(userId, true).
|
|
181
|
+
*
|
|
182
|
+
* @param {number} userId - The ID of the user.
|
|
183
|
+
* @returns {Promise<number>} A promise that resolves with the number of unread notifications.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* const unread = await service.getUnreadNotificationsCount(123);
|
|
187
|
+
*/
|
|
188
|
+
getUnreadNotificationsCount(userId: number): Promise<number>;
|
|
164
189
|
}
|
|
@@ -350,4 +350,61 @@ export class AbstractNotificationService extends EventEmitter {
|
|
|
350
350
|
Adminizer.log.error('Error marking all notifications as read:', error);
|
|
351
351
|
}
|
|
352
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* Returns the count of user notifications: all notifications or only unread ones.
|
|
355
|
+
* If unreadOnly is true, returns the number of unread notifications.
|
|
356
|
+
* If unreadOnly is false, returns the total number of notifications (read + unread) associated with the user.
|
|
357
|
+
*
|
|
358
|
+
* @param {number} userId - The ID of the user whose notification count is requested.
|
|
359
|
+
* @param {boolean} [unreadOnly=false] - If true, counts only unread notifications; if false, counts all notifications.
|
|
360
|
+
* @returns {Promise<number>} A promise that resolves with the number of matching notifications.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* const total = await service.getNotificationsCount(123); // all notifications
|
|
364
|
+
* const unreadCount = await service.getNotificationsCount(123, true); // only unread
|
|
365
|
+
*/
|
|
366
|
+
async getNotificationsCount(userId, unreadOnly = false) {
|
|
367
|
+
try {
|
|
368
|
+
// Формируем условие фильтрации по статусу прочтения
|
|
369
|
+
const whereClause = { userId: userId };
|
|
370
|
+
if (unreadOnly) {
|
|
371
|
+
whereClause.read = false; // только непрочитанные
|
|
372
|
+
}
|
|
373
|
+
// если unreadOnly = false — получаем ВСЕ записи (и прочитанные, и нет)
|
|
374
|
+
// Получаем все user-notification связи
|
|
375
|
+
const userNotifications = await this.adminizer.modelHandler.model.get('usernotificationap')["_find"]({
|
|
376
|
+
where: whereClause
|
|
377
|
+
}, { populate: [['notificationId', {}]] });
|
|
378
|
+
if (userNotifications.length === 0)
|
|
379
|
+
return 0;
|
|
380
|
+
// Фильтруем по классу уведомлений через notificationId
|
|
381
|
+
const validNotificationIds = userNotifications
|
|
382
|
+
.map((un) => un.notificationId.id)
|
|
383
|
+
.filter((id) => id != null);
|
|
384
|
+
if (validNotificationIds.length === 0)
|
|
385
|
+
return 0;
|
|
386
|
+
// Пересчитываем только те, у которых notificationClass совпадает
|
|
387
|
+
return await this.adminizer.modelHandler.model.get('notificationap')["_count"]({
|
|
388
|
+
id: validNotificationIds,
|
|
389
|
+
notificationClass: this.notificationClass
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
catch (error) {
|
|
393
|
+
Adminizer.log.error(`Error counting ${unreadOnly ? 'unread' : 'all'} notifications:`, error);
|
|
394
|
+
return 0;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Convenience method to get the number of unread notifications for a user.
|
|
399
|
+
* Equivalent to calling getNotificationsCount(userId, true).
|
|
400
|
+
*
|
|
401
|
+
* @param {number} userId - The ID of the user.
|
|
402
|
+
* @returns {Promise<number>} A promise that resolves with the number of unread notifications.
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* const unread = await service.getUnreadNotificationsCount(123);
|
|
406
|
+
*/
|
|
407
|
+
async getUnreadNotificationsCount(userId) {
|
|
408
|
+
return this.getNotificationsCount(userId, true);
|
|
409
|
+
}
|
|
353
410
|
}
|
package/package.json
CHANGED
package/translations/en.json
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"Actions": "Actions",
|
|
4
4
|
"All": "All",
|
|
5
5
|
"Are you sure?": "Are you sure?",
|
|
6
|
-
"Back": "Back",
|
|
7
|
-
"Back to Login": "Back to Login",
|
|
8
|
-
"Additional login page": "Additional login page",
|
|
9
|
-
"Clean": "Clean",
|
|
6
|
+
"Back": "Back",
|
|
7
|
+
"Back to Login": "Back to Login",
|
|
8
|
+
"Additional login page": "Additional login page",
|
|
9
|
+
"Clean": "Clean",
|
|
10
10
|
"Confirm Password": "Confirm Password",
|
|
11
11
|
"Confirm Password*": "Confirm Password*",
|
|
12
12
|
"Create": "Create",
|
|
@@ -139,5 +139,6 @@
|
|
|
139
139
|
"W x H (orig.)": "W x H (orig.)",
|
|
140
140
|
"Sizes/Ver": "Sizes/Ver",
|
|
141
141
|
"Locales": "Locales",
|
|
142
|
-
"Date": "Date"
|
|
143
|
-
|
|
142
|
+
"Date": "Date",
|
|
143
|
+
"File type are not supported": "File type are not supported"
|
|
144
|
+
}
|
package/translations/ru.json
CHANGED
|
@@ -119,5 +119,6 @@
|
|
|
119
119
|
"W x H (orig.)": "W x H (orig.)",
|
|
120
120
|
"Sizes/Ver": "Sizes/Ver",
|
|
121
121
|
"Locales": "Locales",
|
|
122
|
-
"Leave this field empty if you don't want to change the password": "Оставьте это поле пустым, если не хотите менять пароль"
|
|
122
|
+
"Leave this field empty if you don't want to change the password": "Оставьте это поле пустым, если не хотите менять пароль",
|
|
123
|
+
"File type are not supported": "Этот файл не поддерживается"
|
|
123
124
|
}
|