@acorex/modules 19.3.1 → 19.3.2
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/common/lib/common.module.d.ts +2 -1
- package/dashboard-management/lib/entities/dashboard/dashboard.types.d.ts +2 -2
- package/dashboard-management/lib/features/home-dashboard/dashboard-home/home-dashboard.d.ts +7 -7
- package/dashboard-management/lib/features/home-dashboard/dashboard-home/home-dashboard.store.d.ts +6 -6
- package/dashboard-management/lib/features/home-dashboard/dashboard-home/home-dashboard.type.d.ts +3 -3
- package/dashboard-management/lib/features/home-dashboard/dashboard-popups/add-dashboard-popup.d.ts +3 -3
- package/dashboard-management/lib/features/home-dashboard/dashboard-popups/configuration-popup.d.ts +3 -3
- package/dashboard-management/lib/features/home-dashboard/dashboard-popups/dashboard-popup.service.d.ts +5 -5
- package/dashboard-management/lib/features/home-dashboard/widget-wrapper/dashboard-widget-wrapper.d.ts +4 -3
- package/dashboard-management/lib/features/shared/widgets/bar-chart/bar-chart-widget.component.d.ts +9 -64
- package/dashboard-management/lib/features/shared/widgets/clock-calendar/clock-calendar-widget.component.d.ts +0 -1
- package/dashboard-management/lib/features/shared/widgets/donut-chart/donut-chart-widget.component.d.ts +9 -50
- package/dashboard-management/lib/features/shared/widgets/gauge-chart/gauge-chart-widget.component.d.ts +8 -67
- package/dashboard-management/lib/features/shared/widgets/gauge-chart/index.d.ts +0 -1
- package/dashboard-management/lib/features/shared/widgets/index.d.ts +0 -2
- package/dashboard-management/lib/features/shared/widgets/line-chart/index.d.ts +0 -1
- package/dashboard-management/lib/features/shared/widgets/line-chart/line-chart-widget.component.d.ts +9 -68
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-B1HTJdsE.mjs → acorex-modules-auth-acorex-modules-auth-DJZcD1j3.mjs} +23 -83
- package/fesm2022/acorex-modules-auth-acorex-modules-auth-DJZcD1j3.mjs.map +1 -0
- package/fesm2022/acorex-modules-auth-app-chooser.component-DlYxDGQr.mjs +65 -0
- package/fesm2022/acorex-modules-auth-app-chooser.component-DlYxDGQr.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-login.module-TtdNj0aL.mjs → acorex-modules-auth-login.module-D-XgzifC.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-login.module-TtdNj0aL.mjs.map → acorex-modules-auth-login.module-D-XgzifC.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-master.layout-CtVrY1hn.mjs → acorex-modules-auth-master.layout-ZaCb3CED.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-master.layout-CtVrY1hn.mjs.map → acorex-modules-auth-master.layout-ZaCb3CED.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-Dmj9zZSI.mjs → acorex-modules-auth-password.component-C-xRIhrM.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-Dmj9zZSI.mjs.map → acorex-modules-auth-password.component-C-xRIhrM.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-BXm2NAaN.mjs → acorex-modules-auth-password.component-CLTZoufP.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-BXm2NAaN.mjs.map → acorex-modules-auth-password.component-CLTZoufP.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-routes-DkgsKi3a.mjs → acorex-modules-auth-routes-4T5jq7su.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-routes-DkgsKi3a.mjs.map → acorex-modules-auth-routes-4T5jq7su.mjs.map} +1 -1
- package/fesm2022/acorex-modules-auth-tenant-chooser.component-Ow7QtAWc.mjs +98 -0
- package/fesm2022/acorex-modules-auth-tenant-chooser.component-Ow7QtAWc.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-two-factor.module-DDOSqjYs.mjs → acorex-modules-auth-two-factor.module-D72KIpvA.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-two-factor.module-DDOSqjYs.mjs.map → acorex-modules-auth-two-factor.module-D72KIpvA.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-user-sessions.component-B3i44VC5.mjs → acorex-modules-auth-user-sessions.component-Btnu_Oeq.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-user-sessions.component-B3i44VC5.mjs.map → acorex-modules-auth-user-sessions.component-Btnu_Oeq.mjs.map} +1 -1
- package/fesm2022/acorex-modules-auth.mjs +1 -1
- package/fesm2022/acorex-modules-common.mjs +3 -5
- package/fesm2022/acorex-modules-common.mjs.map +1 -1
- package/fesm2022/{acorex-modules-dashboard-management-acorex-modules-dashboard-management-CReOsVhq.mjs → acorex-modules-dashboard-management-acorex-modules-dashboard-management-VORBD1g-.mjs} +846 -2174
- package/fesm2022/acorex-modules-dashboard-management-acorex-modules-dashboard-management-VORBD1g-.mjs.map +1 -0
- package/fesm2022/{acorex-modules-dashboard-management-home-dashboard-CHXDeuSF.mjs → acorex-modules-dashboard-management-home-dashboard-DiPn_RhH.mjs} +49 -48
- package/fesm2022/acorex-modules-dashboard-management-home-dashboard-DiPn_RhH.mjs.map +1 -0
- package/fesm2022/acorex-modules-dashboard-management.mjs +1 -1
- package/fesm2022/{acorex-modules-issue-management-acorex-modules-issue-management-Q47ZZSSE.mjs → acorex-modules-issue-management-acorex-modules-issue-management-U5EJyG5e.mjs} +42 -42
- package/fesm2022/{acorex-modules-issue-management-acorex-modules-issue-management-Q47ZZSSE.mjs.map → acorex-modules-issue-management-acorex-modules-issue-management-U5EJyG5e.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-issue-management-capture-screen.component-Dns1Wrkd.mjs → acorex-modules-issue-management-capture-screen.component-3ZAOJBfn.mjs} +2 -2
- package/fesm2022/{acorex-modules-issue-management-capture-screen.component-Dns1Wrkd.mjs.map → acorex-modules-issue-management-capture-screen.component-3ZAOJBfn.mjs.map} +1 -1
- package/fesm2022/acorex-modules-issue-management.mjs +1 -1
- package/fesm2022/acorex-modules-notification-management.mjs +621 -52
- package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-DIsYLKbA.mjs → acorex-modules-platform-management-acorex-modules-platform-management-5lToZD6T.mjs} +6 -6
- package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-5lToZD6T.mjs.map +1 -0
- package/fesm2022/{acorex-modules-platform-management-list-version.component-D83yTFAm.mjs → acorex-modules-platform-management-list-version.component-BElZjmXr.mjs} +2 -2
- package/fesm2022/{acorex-modules-platform-management-list-version.component-D83yTFAm.mjs.map → acorex-modules-platform-management-list-version.component-BElZjmXr.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-platform-management-settings.provider-DKkXCwrd.mjs → acorex-modules-platform-management-settings.provider-CemrvnbH.mjs} +2 -2
- package/fesm2022/{acorex-modules-platform-management-settings.provider-DKkXCwrd.mjs.map → acorex-modules-platform-management-settings.provider-CemrvnbH.mjs.map} +1 -1
- package/fesm2022/acorex-modules-platform-management.mjs +1 -1
- package/fesm2022/acorex-modules-project-management.mjs +218 -155
- package/fesm2022/acorex-modules-project-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-security-management.mjs +472 -787
- package/fesm2022/acorex-modules-security-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-training-management.mjs +5574 -0
- package/fesm2022/acorex-modules-training-management.mjs.map +1 -0
- package/notification-management/index.d.ts +1 -0
- package/notification-management/lib/entities/notification/notification.service.d.ts +6 -6
- package/notification-management/lib/features/components/admin-notification-panel/admin-notification-panel.component.d.ts +13 -7
- package/{dashboard-management/lib/features/shared/widgets/notification → notification-management/lib/features/dashboard/widgets/my-notification}/index.d.ts +0 -1
- package/{dashboard-management/lib/features/shared/widgets/notification → notification-management/lib/features/dashboard/widgets/my-notification}/notification-widget.component.d.ts +37 -9
- package/notification-management/lib/features/dashboard/widgets/my-notification/notification-widget.config.d.ts +5 -0
- package/notification-management/lib/features/shared/notification-connector.service.d.ts +57 -0
- package/notification-management/lib/notification-management.module.d.ts +2 -1
- package/notification-management/lib/notification-management.type.d.ts +3 -0
- package/package.json +5 -1
- package/security-management/lib/entities/index.d.ts +1 -2
- package/security-management/lib/entities/profile/index.d.ts +0 -1
- package/security-management/lib/entities/users/users.service.d.ts +2 -2
- package/security-management/lib/entities/users/users.types.d.ts +2 -2
- package/security-management/lib/user-avatar.provider.d.ts +5 -0
- package/training-management/README.md +3 -0
- package/training-management/index.d.ts +7 -0
- package/training-management/lib/const.d.ts +85 -0
- package/training-management/lib/entities/certificate/certificate.entity.d.ts +3 -0
- package/training-management/lib/entities/certificate/certificate.service.d.ts +10 -0
- package/training-management/lib/entities/certificate/certificate.types.d.ts +12 -0
- package/training-management/lib/entities/certificate/index.d.ts +3 -0
- package/training-management/lib/entities/course/course.entity.d.ts +3 -0
- package/training-management/lib/entities/course/course.service.d.ts +10 -0
- package/training-management/lib/entities/course/course.types.d.ts +8 -0
- package/training-management/lib/entities/course/index.d.ts +3 -0
- package/training-management/lib/entities/course-location/course-location.entity.d.ts +3 -0
- package/training-management/lib/entities/course-location/course-location.service.d.ts +10 -0
- package/training-management/lib/entities/course-location/course-location.types.d.ts +6 -0
- package/training-management/lib/entities/course-location/index.d.ts +3 -0
- package/training-management/lib/entities/course-period/course-period.entity.d.ts +3 -0
- package/training-management/lib/entities/course-period/course-period.service.d.ts +10 -0
- package/training-management/lib/entities/course-period/course-period.types.d.ts +6 -0
- package/training-management/lib/entities/course-period/index.d.ts +3 -0
- package/training-management/lib/entities/course-type/course-type.entity.d.ts +3 -0
- package/training-management/lib/entities/course-type/course-type.service.d.ts +10 -0
- package/training-management/lib/entities/course-type/course-type.types.d.ts +5 -0
- package/training-management/lib/entities/course-type/index.d.ts +3 -0
- package/training-management/lib/entities/facilitator-type/facilitator-type.entity.d.ts +3 -0
- package/training-management/lib/entities/facilitator-type/facilitator-type.service.d.ts +10 -0
- package/training-management/lib/entities/facilitator-type/facilitator-type.types.d.ts +6 -0
- package/training-management/lib/entities/facilitator-type/index.d.ts +3 -0
- package/training-management/lib/entities/index.d.ts +12 -0
- package/training-management/lib/entities/location/index.d.ts +3 -0
- package/training-management/lib/entities/location/location.entity.d.ts +3 -0
- package/training-management/lib/entities/location/location.service.d.ts +10 -0
- package/training-management/lib/entities/location/location.types.d.ts +7 -0
- package/training-management/lib/entities/period/index.d.ts +3 -0
- package/training-management/lib/entities/period/period.entity.d.ts +3 -0
- package/training-management/lib/entities/period/period.service.d.ts +10 -0
- package/training-management/lib/entities/period/period.types.d.ts +6 -0
- package/training-management/lib/entities/training/index.d.ts +3 -0
- package/training-management/lib/entities/training/training.entity.d.ts +3 -0
- package/training-management/lib/entities/training/training.service.d.ts +10 -0
- package/training-management/lib/entities/training/training.types.d.ts +13 -0
- package/training-management/lib/entities/training-facilitator/index.d.ts +3 -0
- package/training-management/lib/entities/training-facilitator/training-facilitator.entity.d.ts +3 -0
- package/training-management/lib/entities/training-facilitator/training-facilitator.service.d.ts +10 -0
- package/training-management/lib/entities/training-facilitator/training-facilitator.types.d.ts +7 -0
- package/training-management/lib/entities/training-participant/index.d.ts +3 -0
- package/training-management/lib/entities/training-participant/training-participant.entity.d.ts +3 -0
- package/training-management/lib/entities/training-participant/training-participant.service.d.ts +10 -0
- package/training-management/lib/entities/training-participant/training-participant.types.d.ts +7 -0
- package/training-management/lib/entities/training-type/index.d.ts +3 -0
- package/training-management/lib/entities/training-type/training-type.entity.d.ts +3 -0
- package/training-management/lib/entities/training-type/training-type.service.d.ts +10 -0
- package/training-management/lib/entities/training-type/training-type.types.d.ts +7 -0
- package/training-management/lib/entity.provider.d.ts +10 -0
- package/training-management/lib/menu.provider.d.ts +5 -0
- package/training-management/lib/permission-definition.provider.d.ts +4 -0
- package/training-management/lib/search-command.provider.d.ts +4 -0
- package/training-management/lib/setting.provider.d.ts +4 -0
- package/training-management/lib/training-management.module.d.ts +6 -0
- package/auth/lib/pages/account/avatar/avatar.component.d.ts +0 -20
- package/dashboard-management/lib/features/shared/widgets/bar-chart/bar-chart.type.d.ts +0 -34
- package/dashboard-management/lib/features/shared/widgets/donut-chart/donut-chart.type.d.ts +0 -67
- package/dashboard-management/lib/features/shared/widgets/gauge-chart/gauge-chart.type.d.ts +0 -29
- package/dashboard-management/lib/features/shared/widgets/line-chart/line-chart.type.d.ts +0 -41
- package/dashboard-management/lib/features/shared/widgets/notification/notification-widget.config.d.ts +0 -10
- package/dashboard-management/lib/features/shared/widgets/notification/notification.type.d.ts +0 -47
- package/dashboard-management/lib/features/shared/widgets/shared/chart-base.component.d.ts +0 -44
- package/dashboard-management/lib/features/shared/widgets/shared/chart-base.type.d.ts +0 -37
- package/dashboard-management/lib/features/shared/widgets/shared/components/chart-tooltip/chart-tooltip.component.d.ts +0 -28
- package/dashboard-management/lib/features/shared/widgets/shared/components/chart-tooltip/index.d.ts +0 -1
- package/dashboard-management/lib/features/shared/widgets/shared/index.d.ts +0 -3
- package/fesm2022/acorex-modules-auth-acorex-modules-auth-B1HTJdsE.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-app-chooser.component-Ct-vco0y.mjs +0 -64
- package/fesm2022/acorex-modules-auth-app-chooser.component-Ct-vco0y.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-tenant-chooser.component-D9C6LCjn.mjs +0 -97
- package/fesm2022/acorex-modules-auth-tenant-chooser.component-D9C6LCjn.mjs.map +0 -1
- package/fesm2022/acorex-modules-dashboard-management-acorex-modules-dashboard-management-CReOsVhq.mjs.map +0 -1
- package/fesm2022/acorex-modules-dashboard-management-home-dashboard-CHXDeuSF.mjs.map +0 -1
- package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-DIsYLKbA.mjs.map +0 -1
- package/security-management/lib/entities/profile/profile.service.d.ts +0 -13
@@ -1,34 +1,37 @@
|
|
1
1
|
import { RootConfig as RootConfig$1 } from '@acorex/modules/text-template-management';
|
2
2
|
import * as i1$2 from '@acorex/platform/common';
|
3
3
|
import { AXPEntityCommandScope, AXPEntityQueryType, AXPComponentSlotModule, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER } from '@acorex/platform/common';
|
4
|
-
import
|
4
|
+
import * as i2$1 from '@acorex/platform/layout/builder';
|
5
|
+
import { AXPWidgetsCatalog, AXPValueWidgetComponent, cloneProperty, AXPWidgetGroupEnum, AXPLayoutBuilderModule } from '@acorex/platform/layout/builder';
|
5
6
|
import { AXMEntityCrudServiceImpl, AXPEntityService, AXP_ENTITY_DEFINITION_LOADER, AXPEntityStorageService, AXPEntityDataProviderImpl } from '@acorex/platform/layout/entity';
|
6
7
|
import * as i0 from '@angular/core';
|
7
|
-
import { Injectable, NgModule, inject,
|
8
|
+
import { Injectable, NgModule, inject, signal, computed, effect, input, output, ChangeDetectionStrategy, Component, Injector, ChangeDetectorRef } from '@angular/core';
|
8
9
|
import { AXPSessionService } from '@acorex/platform/auth';
|
9
10
|
import { firstValueFrom } from 'rxjs';
|
10
|
-
import * as i4
|
11
|
+
import * as i4 from '@acorex/components/badge';
|
11
12
|
import { AXBadgeModule } from '@acorex/components/badge';
|
12
13
|
import * as i1$1 from '@acorex/components/button';
|
13
14
|
import { AXButtonModule } from '@acorex/components/button';
|
14
|
-
import * as
|
15
|
+
import * as i3 from '@acorex/components/decorators';
|
15
16
|
import { AXDecoratorModule } from '@acorex/components/decorators';
|
16
|
-
import * as i4$
|
17
|
+
import * as i4$1 from '@acorex/components/popover';
|
17
18
|
import { AXPopoverModule } from '@acorex/components/popover';
|
18
19
|
import * as i1 from '@angular/common';
|
19
|
-
import { CommonModule } from '@angular/common';
|
20
|
-
import * as i2
|
20
|
+
import { CommonModule, DatePipe } from '@angular/common';
|
21
|
+
import * as i2 from '@acorex/components/tabs';
|
21
22
|
import { AXTabsModule } from '@acorex/components/tabs';
|
22
23
|
import { AXToastService } from '@acorex/components/toast';
|
23
|
-
import * as
|
24
|
+
import * as i3$1 from '@acorex/core/format';
|
24
25
|
import { AXFormatModule } from '@acorex/core/format';
|
25
26
|
import { Router } from '@angular/router';
|
26
|
-
import * as i3 from '@acorex/components/avatar';
|
27
|
-
import { AXAvatarModule } from '@acorex/components/avatar';
|
28
|
-
import * as i4 from '@acorex/components/image';
|
29
27
|
import { AXImageModule } from '@acorex/components/image';
|
28
|
+
import { AXPUserAvatarComponent } from '@acorex/platform/layout/components';
|
29
|
+
import { AXAvatarModule } from '@acorex/components/avatar';
|
30
|
+
import * as i5 from '@acorex/core/translation';
|
31
|
+
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
|
32
|
+
import { AXP_WIDGETS_UTILITY_CATEGORY } from '@acorex/modules/dashboard-management';
|
33
|
+
import { AXP_APPEARANCE_PROPERTY_GROUP, AXP_STYLING_PROPERTY_GROUP, AXP_DATA_PATH_PROPERTY } from '@acorex/platform/widgets';
|
30
34
|
import { RootConfig as RootConfig$2 } from '@acorex/modules/form-template-management';
|
31
|
-
import { AXTranslationService } from '@acorex/core/translation';
|
32
35
|
import { AXPWidgetsList } from '@acorex/modules/common';
|
33
36
|
import { AXPDataGenerator } from '@acorex/platform/core';
|
34
37
|
|
@@ -1442,6 +1445,215 @@ class AXMNotificationManagmentModuleMenuProvider {
|
|
1442
1445
|
}
|
1443
1446
|
}
|
1444
1447
|
|
1448
|
+
/**
|
1449
|
+
* Signal store that provides a reactive interface for notification-related operations
|
1450
|
+
* Acts as a layer between notification components and the entity service
|
1451
|
+
*/
|
1452
|
+
class AXMNotificationConnectorService {
|
1453
|
+
// Effects
|
1454
|
+
constructor() {
|
1455
|
+
this.notificationService = inject(AXMNotificationEntityService);
|
1456
|
+
// State signals
|
1457
|
+
this.isLoading = signal(false);
|
1458
|
+
this.error = signal(null);
|
1459
|
+
this.notifications = signal([]);
|
1460
|
+
this.totalCount = signal(0);
|
1461
|
+
// Public computed signals
|
1462
|
+
this.loading = computed(() => this.isLoading());
|
1463
|
+
this.errorMessage = computed(() => this.error());
|
1464
|
+
this.notificationList = computed(() => this.notifications());
|
1465
|
+
this.total = computed(() => this.totalCount());
|
1466
|
+
this.unreadCount = computed(() => this.notifications().filter((notification) => notification.readAt === null).length);
|
1467
|
+
// Auto-fetch notifications when service is initialized
|
1468
|
+
effect(() => {
|
1469
|
+
this.getList();
|
1470
|
+
});
|
1471
|
+
}
|
1472
|
+
// Methods from entity service with additional state management
|
1473
|
+
/**
|
1474
|
+
* Get list of notifications
|
1475
|
+
*/
|
1476
|
+
async getList() {
|
1477
|
+
try {
|
1478
|
+
this.isLoading.set(true);
|
1479
|
+
this.error.set(null);
|
1480
|
+
const response = await this.notificationService.getList();
|
1481
|
+
this.notifications.set(response.items);
|
1482
|
+
this.totalCount.set(response.total);
|
1483
|
+
return response;
|
1484
|
+
}
|
1485
|
+
catch (err) {
|
1486
|
+
this.error.set(err instanceof Error ? err.message : 'Failed to fetch notifications');
|
1487
|
+
return { total: 0, items: [] };
|
1488
|
+
}
|
1489
|
+
finally {
|
1490
|
+
this.isLoading.set(false);
|
1491
|
+
}
|
1492
|
+
}
|
1493
|
+
/**
|
1494
|
+
* Mark notifications as read or toggle read status
|
1495
|
+
* If no specific IDs are provided, mark all as read
|
1496
|
+
* If specific IDs are provided, toggle their read status (mark as read if unread, mark as unread if read)
|
1497
|
+
*/
|
1498
|
+
async markAsRead(payload = { id: [] }) {
|
1499
|
+
try {
|
1500
|
+
this.isLoading.set(true);
|
1501
|
+
this.error.set(null);
|
1502
|
+
await this.notificationService.markAsRead(payload);
|
1503
|
+
// Update local state to reflect toggled read status
|
1504
|
+
if (payload?.id?.length) {
|
1505
|
+
// Toggle read status for specific notifications
|
1506
|
+
this.notifications.update((notifications) => notifications.map((notification) => {
|
1507
|
+
if (payload.id.includes(notification.id)) {
|
1508
|
+
// Toggle read status
|
1509
|
+
return {
|
1510
|
+
...notification,
|
1511
|
+
readAt: notification.readAt ? null : new Date(),
|
1512
|
+
};
|
1513
|
+
}
|
1514
|
+
return notification;
|
1515
|
+
}));
|
1516
|
+
}
|
1517
|
+
else {
|
1518
|
+
// If no specific IDs are provided, mark all unread notifications as read
|
1519
|
+
this.notifications.update((notifications) => notifications.map((notification) => notification.readAt ? notification : { ...notification, readAt: new Date() }));
|
1520
|
+
}
|
1521
|
+
}
|
1522
|
+
catch (err) {
|
1523
|
+
this.error.set(err instanceof Error ? err.message : 'Failed to mark notifications as read');
|
1524
|
+
}
|
1525
|
+
finally {
|
1526
|
+
this.isLoading.set(false);
|
1527
|
+
}
|
1528
|
+
}
|
1529
|
+
/**
|
1530
|
+
* Create a new notification
|
1531
|
+
*/
|
1532
|
+
async create(payload) {
|
1533
|
+
try {
|
1534
|
+
this.isLoading.set(true);
|
1535
|
+
this.error.set(null);
|
1536
|
+
await this.notificationService.create(payload);
|
1537
|
+
// Refresh list after creating a notification
|
1538
|
+
await this.getList();
|
1539
|
+
}
|
1540
|
+
catch (err) {
|
1541
|
+
this.error.set(err instanceof Error ? err.message : 'Failed to create notification');
|
1542
|
+
}
|
1543
|
+
finally {
|
1544
|
+
this.isLoading.set(false);
|
1545
|
+
}
|
1546
|
+
}
|
1547
|
+
// Methods from AXMEntityCrudServiceImpl
|
1548
|
+
/**
|
1549
|
+
* Insert one notification
|
1550
|
+
*/
|
1551
|
+
async insertOne(request) {
|
1552
|
+
try {
|
1553
|
+
this.isLoading.set(true);
|
1554
|
+
this.error.set(null);
|
1555
|
+
const id = await this.notificationService.insertOne(request);
|
1556
|
+
// Refresh list after inserting
|
1557
|
+
await this.getList();
|
1558
|
+
return id;
|
1559
|
+
}
|
1560
|
+
catch (err) {
|
1561
|
+
this.error.set(err instanceof Error ? err.message : 'Failed to insert notification');
|
1562
|
+
throw err;
|
1563
|
+
}
|
1564
|
+
finally {
|
1565
|
+
this.isLoading.set(false);
|
1566
|
+
}
|
1567
|
+
}
|
1568
|
+
/**
|
1569
|
+
* Get one notification by id
|
1570
|
+
*/
|
1571
|
+
async getOne(id) {
|
1572
|
+
try {
|
1573
|
+
this.isLoading.set(true);
|
1574
|
+
this.error.set(null);
|
1575
|
+
return await this.notificationService.getOne(id);
|
1576
|
+
}
|
1577
|
+
catch (err) {
|
1578
|
+
this.error.set(err instanceof Error ? err.message : `Failed to get notification with id ${id}`);
|
1579
|
+
throw err;
|
1580
|
+
}
|
1581
|
+
finally {
|
1582
|
+
this.isLoading.set(false);
|
1583
|
+
}
|
1584
|
+
}
|
1585
|
+
/**
|
1586
|
+
* Delete one notification
|
1587
|
+
*/
|
1588
|
+
async deleteOne(id) {
|
1589
|
+
try {
|
1590
|
+
this.isLoading.set(true);
|
1591
|
+
this.error.set(null);
|
1592
|
+
await this.notificationService.deleteOne(id);
|
1593
|
+
// Update local state to remove deleted notification
|
1594
|
+
this.notifications.update((notifications) => notifications.filter((notification) => notification.id !== id));
|
1595
|
+
// Update total count
|
1596
|
+
this.totalCount.update((count) => count - 1);
|
1597
|
+
}
|
1598
|
+
catch (err) {
|
1599
|
+
this.error.set(err instanceof Error ? err.message : `Failed to delete notification with id ${id}`);
|
1600
|
+
throw err;
|
1601
|
+
}
|
1602
|
+
finally {
|
1603
|
+
this.isLoading.set(false);
|
1604
|
+
}
|
1605
|
+
}
|
1606
|
+
/**
|
1607
|
+
* Update one notification
|
1608
|
+
*/
|
1609
|
+
async updateOne(id, values) {
|
1610
|
+
try {
|
1611
|
+
this.isLoading.set(true);
|
1612
|
+
this.error.set(null);
|
1613
|
+
const updated = await this.notificationService.updateOne(id, values);
|
1614
|
+
// Update local state to reflect changes
|
1615
|
+
this.notifications.update((notifications) => notifications.map((notification) => notification.id === id ? { ...notification, ...values } : notification));
|
1616
|
+
return updated;
|
1617
|
+
}
|
1618
|
+
catch (err) {
|
1619
|
+
this.error.set(err instanceof Error ? err.message : `Failed to update notification with id ${id}`);
|
1620
|
+
throw err;
|
1621
|
+
}
|
1622
|
+
finally {
|
1623
|
+
this.isLoading.set(false);
|
1624
|
+
}
|
1625
|
+
}
|
1626
|
+
/**
|
1627
|
+
* Query notifications
|
1628
|
+
*/
|
1629
|
+
async query(request = { skip: 0, take: 100 }) {
|
1630
|
+
try {
|
1631
|
+
this.isLoading.set(true);
|
1632
|
+
this.error.set(null);
|
1633
|
+
const result = await this.notificationService.query(request);
|
1634
|
+
// Update local state with query results
|
1635
|
+
this.notifications.set(result.items);
|
1636
|
+
this.totalCount.set(result.total);
|
1637
|
+
return result;
|
1638
|
+
}
|
1639
|
+
catch (err) {
|
1640
|
+
this.error.set(err instanceof Error ? err.message : 'Failed to query notifications');
|
1641
|
+
throw err;
|
1642
|
+
}
|
1643
|
+
finally {
|
1644
|
+
this.isLoading.set(false);
|
1645
|
+
}
|
1646
|
+
}
|
1647
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationConnectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
1648
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationConnectorService, providedIn: 'root' }); }
|
1649
|
+
}
|
1650
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationConnectorService, decorators: [{
|
1651
|
+
type: Injectable,
|
1652
|
+
args: [{
|
1653
|
+
providedIn: 'root',
|
1654
|
+
}]
|
1655
|
+
}], ctorParameters: () => [] });
|
1656
|
+
|
1445
1657
|
class AXMAdminNotificationItemComponent {
|
1446
1658
|
constructor() {
|
1447
1659
|
this.data = input.required();
|
@@ -1452,7 +1664,7 @@ class AXMAdminNotificationItemComponent {
|
|
1452
1664
|
this.onPressNotificationItem.emit(id);
|
1453
1665
|
}
|
1454
1666
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMAdminNotificationItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1455
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXMAdminNotificationItemComponent, isStandalone: true, selector: "axp-master-notification-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onPressNotificationItem: "onPressNotificationItem" }, ngImport: i0, template: "<div\n class=\"notification-item\"\n [id]=\"data().id\"\n (click)=\"pressNotificationItem(data().id)\"\n [class]=\"[data().template.prority, data().readAt ? 'read' : 'unread']\"\n>\n <
|
1667
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXMAdminNotificationItemComponent, isStandalone: true, selector: "axp-master-notification-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onPressNotificationItem: "onPressNotificationItem" }, ngImport: i0, template: "<div\n class=\"notification-item\"\n [id]=\"data().id\"\n (click)=\"pressNotificationItem(data().id)\"\n [class]=\"[data().template.prority, data().readAt ? 'read' : 'unread']\"\n>\n <axp-user-avatar [size]=\"40\" [userId]=\"data().user.id!\"></axp-user-avatar>\n <div>\n <div class=\"notification-item-title\">{{ data().user.name || data().title }}</div>\n <div class=\"notification-item-body\">{{ data().body }}</div>\n <!-- @if(false){\n <div>\n <div class=\"notification-file\">\n <ax-avatar color=\"primary\">\n <ax-icon>\n <i class=\"fa-solid fa-file-word ax-text-2xl\"></i>\n </ax-icon>\n </ax-avatar>\n <div>\n <div class=\"notification-file-name\">New project details.docx</div>\n <div class=\"notification-file-size\">250 KB</div>\n </div>\n <ax-button look=\"blank\">\n <ax-icon>\n <i class=\"fa-solid fa-download\"></i>\n </ax-icon>\n </ax-button>\n </div>\n </div>\n } -->\n <div class=\"notification-item-time\">{{ differentTime() | format : 'timeleft' | async }}</div>\n </div>\n @if(!data().template.isPinned){\n <div class=\"pin-notification ltr:ax-rotate-45 rtl:ax-left-0 rtl:-ax-rotate-45 ltr:ax-right-0\">\n <ax-icon>\n <i class=\"fa-solid fa-thumbtack\"></i>\n </ax-icon>\n </div>\n }\n</div>\n", styles: [".notification-item{position:relative;display:flex;cursor:pointer;align-items:center;gap:.75rem;overflow-x:hidden;padding:1rem}.notification-item.read{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.notification-item.unread{background:rgb(var(--ax-color-on-surface))}.notification-item.Notice:before,.notification-item.Danger:before,.notification-item.Warning:before{content:\"\";position:absolute;height:95%;width:.2rem;inset-inline-start:0;top:50%;transform:translateY(-50%)}.notification-item.Notice:before{background:rgb(var(--ax-color-success-500))}.notification-item.Danger:before{background:rgb(var(--ax-color-danger-500))}.notification-item.Warning:before{background:rgb(var(--ax-color-warning-500))}.notification-item ax-avatar ax-badge{position:absolute;bottom:0;inset-inline-end:.25rem;top:auto;border-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1))}.notification-item>div{display:flex;flex:1 1 0%;flex-direction:column}.notification-item>div .notification-item-title,.notification-item>div .notification-file-name{max-width:20rem;font-size:1rem;font-weight:600;line-height:1.5rem}.notification-item>div .notification-item-time,.notification-item>div .notification-file-size{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.notification-item>div .notification-item-body{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;max-width:20rem;font-size:.875rem;font-weight:400;line-height:1.5rem}.notification-item>ax-badge{position:absolute;top:1rem;inset-inline-end:1rem}.notification-item .notification-file{margin-top:.5rem;margin-bottom:.5rem;display:flex;gap:.5rem;border-radius:.5rem;border-width:1px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-surface),var(--tw-bg-opacity, 1));padding:.5rem}.notification-item .notification-file>div{flex:1 1 0%}.notification-item .pin-notification{position:absolute;top:0;padding:1rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId"] }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXFormatModule }, { kind: "pipe", type: i3$1.AXFormatPipe, name: "format" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
1456
1668
|
}
|
1457
1669
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMAdminNotificationItemComponent, decorators: [{
|
1458
1670
|
type: Component,
|
@@ -1460,26 +1672,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
|
|
1460
1672
|
CommonModule,
|
1461
1673
|
AXButtonModule,
|
1462
1674
|
AXDecoratorModule,
|
1463
|
-
|
1675
|
+
AXPUserAvatarComponent,
|
1464
1676
|
AXImageModule,
|
1465
1677
|
AXBadgeModule,
|
1466
1678
|
AXFormatModule,
|
1467
|
-
], template: "<div\n class=\"notification-item\"\n [id]=\"data().id\"\n (click)=\"pressNotificationItem(data().id)\"\n [class]=\"[data().template.prority, data().readAt ? 'read' : 'unread']\"\n>\n <
|
1679
|
+
], template: "<div\n class=\"notification-item\"\n [id]=\"data().id\"\n (click)=\"pressNotificationItem(data().id)\"\n [class]=\"[data().template.prority, data().readAt ? 'read' : 'unread']\"\n>\n <axp-user-avatar [size]=\"40\" [userId]=\"data().user.id!\"></axp-user-avatar>\n <div>\n <div class=\"notification-item-title\">{{ data().user.name || data().title }}</div>\n <div class=\"notification-item-body\">{{ data().body }}</div>\n <!-- @if(false){\n <div>\n <div class=\"notification-file\">\n <ax-avatar color=\"primary\">\n <ax-icon>\n <i class=\"fa-solid fa-file-word ax-text-2xl\"></i>\n </ax-icon>\n </ax-avatar>\n <div>\n <div class=\"notification-file-name\">New project details.docx</div>\n <div class=\"notification-file-size\">250 KB</div>\n </div>\n <ax-button look=\"blank\">\n <ax-icon>\n <i class=\"fa-solid fa-download\"></i>\n </ax-icon>\n </ax-button>\n </div>\n </div>\n } -->\n <div class=\"notification-item-time\">{{ differentTime() | format : 'timeleft' | async }}</div>\n </div>\n @if(!data().template.isPinned){\n <div class=\"pin-notification ltr:ax-rotate-45 rtl:ax-left-0 rtl:-ax-rotate-45 ltr:ax-right-0\">\n <ax-icon>\n <i class=\"fa-solid fa-thumbtack\"></i>\n </ax-icon>\n </div>\n }\n</div>\n", styles: [".notification-item{position:relative;display:flex;cursor:pointer;align-items:center;gap:.75rem;overflow-x:hidden;padding:1rem}.notification-item.read{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.notification-item.unread{background:rgb(var(--ax-color-on-surface))}.notification-item.Notice:before,.notification-item.Danger:before,.notification-item.Warning:before{content:\"\";position:absolute;height:95%;width:.2rem;inset-inline-start:0;top:50%;transform:translateY(-50%)}.notification-item.Notice:before{background:rgb(var(--ax-color-success-500))}.notification-item.Danger:before{background:rgb(var(--ax-color-danger-500))}.notification-item.Warning:before{background:rgb(var(--ax-color-warning-500))}.notification-item ax-avatar ax-badge{position:absolute;bottom:0;inset-inline-end:.25rem;top:auto;border-width:1px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-border-surface),var(--tw-border-opacity, 1))}.notification-item>div{display:flex;flex:1 1 0%;flex-direction:column}.notification-item>div .notification-item-title,.notification-item>div .notification-file-name{max-width:20rem;font-size:1rem;font-weight:600;line-height:1.5rem}.notification-item>div .notification-item-time,.notification-item>div .notification-file-size{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.notification-item>div .notification-item-body{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;max-width:20rem;font-size:.875rem;font-weight:400;line-height:1.5rem}.notification-item>ax-badge{position:absolute;top:1rem;inset-inline-end:1rem}.notification-item .notification-file{margin-top:.5rem;margin-bottom:.5rem;display:flex;gap:.5rem;border-radius:.5rem;border-width:1px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-surface),var(--tw-bg-opacity, 1));padding:.5rem}.notification-item .notification-file>div{flex:1 1 0%}.notification-item .pin-notification{position:absolute;top:0;padding:1rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}\n"] }]
|
1468
1680
|
}] });
|
1469
1681
|
|
1470
1682
|
class AXMAdminNotificationPanelComponent {
|
1471
1683
|
constructor() {
|
1472
1684
|
this.onNewNotfication = output();
|
1473
|
-
this.
|
1685
|
+
this.notificationConnector = inject(AXMNotificationConnectorService);
|
1474
1686
|
this.toastService = inject(AXToastService);
|
1475
1687
|
this.router = inject(Router);
|
1476
1688
|
this.sessionService = inject(AXPSessionService);
|
1477
|
-
|
1478
|
-
this.
|
1689
|
+
// Use store's signals directly
|
1690
|
+
this.notifications = this.notificationConnector.notificationList;
|
1691
|
+
this.totalNotifications = this.notificationConnector.total;
|
1692
|
+
this.isLoading = this.notificationConnector.loading;
|
1693
|
+
this.errorMessage = this.notificationConnector.errorMessage;
|
1694
|
+
this.activeTab = signal('All');
|
1479
1695
|
this.tabItems = computed(() => this.getTabItems(this.notifications()), {
|
1480
1696
|
equal: (a, b) => JSON.stringify(a) === JSON.stringify(b),
|
1481
1697
|
});
|
1482
|
-
this.activeTab = signal('All');
|
1483
1698
|
this.NewNotification = computed(() => this.getNewNotification(this.tabItems()));
|
1484
1699
|
this.NewNotificationEffect = effect(() => this.onNewNotfication.emit(this.NewNotification()));
|
1485
1700
|
}
|
@@ -1491,15 +1706,7 @@ class AXMAdminNotificationPanelComponent {
|
|
1491
1706
|
}
|
1492
1707
|
async loadNotification() {
|
1493
1708
|
try {
|
1494
|
-
|
1495
|
-
this.totalNotifications.set(response.total);
|
1496
|
-
const orderedResponse = response.items.sort((a, b) => {
|
1497
|
-
if (a.template.isPinned === b.template.isPinned) {
|
1498
|
-
return new Date(a.createAt).getTime() - new Date(b.createAt).getTime();
|
1499
|
-
}
|
1500
|
-
return a.template.isPinned ? 1 : -1;
|
1501
|
-
});
|
1502
|
-
this.notifications.set(orderedResponse);
|
1709
|
+
await this.notificationConnector.getList();
|
1503
1710
|
}
|
1504
1711
|
catch (error) {
|
1505
1712
|
this.toastService.show({
|
@@ -1517,7 +1724,6 @@ class AXMAdminNotificationPanelComponent {
|
|
1517
1724
|
return [
|
1518
1725
|
{
|
1519
1726
|
text: 'All',
|
1520
|
-
//active: true,
|
1521
1727
|
count: 0,
|
1522
1728
|
},
|
1523
1729
|
];
|
@@ -1555,40 +1761,33 @@ class AXMAdminNotificationPanelComponent {
|
|
1555
1761
|
return this.notifications()?.filter((item) => item.template.category === category);
|
1556
1762
|
}
|
1557
1763
|
}
|
1558
|
-
|
1764
|
+
/**
|
1765
|
+
* Mark a notification as read or unread (toggle read status)
|
1766
|
+
*/
|
1559
1767
|
async markAsRead(id) {
|
1560
1768
|
try {
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1769
|
+
await this.notificationConnector.markAsRead({ id: [id] });
|
1770
|
+
}
|
1771
|
+
catch (error) {
|
1772
|
+
console.error('Failed to toggle notification read status:', error);
|
1564
1773
|
}
|
1565
|
-
catch (error) { }
|
1566
|
-
}
|
1567
|
-
toggleRead(id) {
|
1568
|
-
this.notifications.update((old) => old?.map((item) => (item.id === id ? { ...item, readAt: item.readAt ? null : new Date() } : item)));
|
1569
1774
|
}
|
1775
|
+
/**
|
1776
|
+
* Mark all unread notifications as read
|
1777
|
+
*/
|
1570
1778
|
async markAllAsRead() {
|
1571
1779
|
try {
|
1572
|
-
await this.
|
1573
|
-
this.toggleMarkAllAsRead();
|
1780
|
+
await this.notificationConnector.markAsRead({ id: [] });
|
1574
1781
|
}
|
1575
1782
|
catch (error) {
|
1576
|
-
console.error(error);
|
1783
|
+
console.error('Failed to mark all notifications as read:', error);
|
1577
1784
|
}
|
1578
1785
|
}
|
1579
|
-
toggleMarkAllAsRead() {
|
1580
|
-
this.notifications.update((notification) => notification?.map((item) => {
|
1581
|
-
if (!item.readAt) {
|
1582
|
-
return { ...item, readAt: new Date() };
|
1583
|
-
}
|
1584
|
-
return item;
|
1585
|
-
}));
|
1586
|
-
}
|
1587
1786
|
viewAllNotifications() {
|
1588
1787
|
this.router.navigate([`${this.sessionService.application?.name}/m/notification-management/e/my-notification/list`]);
|
1589
1788
|
}
|
1590
1789
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMAdminNotificationPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1591
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXMAdminNotificationPanelComponent, isStandalone: true, selector: "axm-admin-notification-panel", outputs: { onNewNotfication: "onNewNotfication" }, ngImport: i0, template: "<div class=\"ax-p-4 ax-flex ax-justify-between ax-items-center\">\n <span class=\"ax-text-xl\">Notifications</span>\n <ax-button color=\"default\" look=\"blank\">\n <ax-icon>\n <i class=\"fa-regular fa-gear fa-lg\"></i>\n </ax-icon>\n </ax-button>\n</div>\n<ax-tabs [content]=\"cons\" look=\"with-line\" location=\"bottom\">\n @for(tab of tabItems(); track tab.text){\n <ax-tab-item [text]=\"tab.text\" [active]=\"activeTab() === tab.text\" (activeChange)=\"changeActiveTab(tab.text)\">\n <ax-suffix>\n @if(tab.count){\n <ax-badge [color]=\"activeTab() === tab.text ? 'primary' : 'ghost'\" [text]=\"tab.count.toString()\"></ax-badge>\n }\n </ax-suffix>\n <ax-content>\n <div class=\"ax-max-h-[50vh] ax-overflow-y-auto\">\n @for(notif of getNotificationItems(tab.text); track notif.id){\n <axp-master-notification-item\n [data]=\"notif\"\n (onPressNotificationItem)=\"markAsRead($event)\"\n ></axp-master-notification-item>\n }\n </div>\n <div class=\"ax-flex ax-gap-4 ax-justify-between ax-p-4 ax-border-t ax-border-default\">\n <ax-button\n [disabled]=\"NewNotification() === 0\"\n [color]=\"'default'\"\n text=\"Mark all as read\"\n (onClick)=\"markAllAsRead()\"\n ></ax-button>\n <ax-button color=\"primary\" text=\"View all notifications\" (onClick)=\"viewAllNotifications()\"></ax-button>\n </div>\n </ax-content>\n </ax-tab-item>\n }\n</ax-tabs>\n\n<ng-template [axTabContent] #cons=\"axTabContent\"></ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2
|
1790
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXMAdminNotificationPanelComponent, isStandalone: true, selector: "axm-admin-notification-panel", outputs: { onNewNotfication: "onNewNotfication" }, ngImport: i0, template: "<div class=\"ax-p-4 ax-flex ax-justify-between ax-items-center\">\n <span class=\"ax-text-xl\">Notifications</span>\n <ax-button color=\"default\" look=\"blank\">\n <ax-icon>\n <i class=\"fa-regular fa-gear fa-lg\"></i>\n </ax-icon>\n </ax-button>\n</div>\n<ax-tabs [content]=\"cons\" look=\"with-line\" location=\"bottom\">\n @for(tab of tabItems(); track tab.text){\n <ax-tab-item [text]=\"tab.text\" [active]=\"activeTab() === tab.text\" (activeChange)=\"changeActiveTab(tab.text)\">\n <ax-suffix>\n @if(tab.count){\n <ax-badge [color]=\"activeTab() === tab.text ? 'primary' : 'ghost'\" [text]=\"tab.count.toString()\"></ax-badge>\n }\n </ax-suffix>\n <ax-content>\n <div class=\"ax-max-h-[50vh] ax-overflow-y-auto\">\n @for(notif of getNotificationItems(tab.text); track notif.id){\n <axp-master-notification-item\n [data]=\"notif\"\n (onPressNotificationItem)=\"markAsRead($event)\"\n ></axp-master-notification-item>\n }\n </div>\n <div class=\"ax-flex ax-gap-4 ax-justify-between ax-p-4 ax-border-t ax-border-default\">\n <ax-button\n [disabled]=\"NewNotification() === 0\"\n [color]=\"'default'\"\n text=\"Mark all as read\"\n (onClick)=\"markAllAsRead()\"\n ></ax-button>\n <ax-button color=\"primary\" text=\"View all notifications\" (onClick)=\"viewAllNotifications()\"></ax-button>\n </div>\n </ax-content>\n </ax-tab-item>\n }\n</ax-tabs>\n\n<ng-template [axTabContent] #cons=\"axTabContent\"></ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "directive", type: i2.AXTabContentDirective, selector: "[axTabContent]", inputs: ["axTabContent"], exportAs: ["axTabContent"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: AXMAdminNotificationItemComponent, selector: "axp-master-notification-item", inputs: ["data"], outputs: ["onPressNotificationItem"] }, { kind: "ngmodule", type: AXFormatModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
1592
1791
|
}
|
1593
1792
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMAdminNotificationPanelComponent, decorators: [{
|
1594
1793
|
type: Component,
|
@@ -1612,7 +1811,7 @@ class AXMAdminNotificationSlotComponent {
|
|
1612
1811
|
this.totalNewNotification.set(value);
|
1613
1812
|
}
|
1614
1813
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMAdminNotificationSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1615
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXMAdminNotificationSlotComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<ax-button class=\"ax-relative\" color=\"primary\" #notification>\n <ax-icon>\n <i class=\"fa-regular fa-bell\"></i>\n </ax-icon>\n <ax-suffix class=\"ax-absolute ax-top-0 ax-left-1/2\">\n @if(totalNewNotification()){\n <ax-badge color=\"success\" [text]=\"totalNewNotification().toString()\"></ax-badge>\n }\n </ax-suffix>\n</ax-button>\n<ax-popover [target]=\"notification\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" [adaptivityEnabled]=\"true\">\n <div class=\"ax-bg-lightest ax-border ax-border-default ax-rounded-md ax-shadow-md ax-w-full\">\n <axm-admin-notification-panel (onNewNotfication)=\"setTotalNewNotification($event)\"> </axm-admin-notification-panel>\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type:
|
1814
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXMAdminNotificationSlotComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<ax-button class=\"ax-relative\" color=\"primary\" #notification>\n <ax-icon>\n <i class=\"fa-regular fa-bell\"></i>\n </ax-icon>\n <ax-suffix class=\"ax-absolute ax-top-0 ax-left-1/2\">\n @if(totalNewNotification()){\n <ax-badge color=\"success\" [text]=\"totalNewNotification().toString()\"></ax-badge>\n }\n </ax-suffix>\n</ax-button>\n<ax-popover [target]=\"notification\" [openOn]=\"'toggle'\" [closeOn]=\"'clickOut'\" [adaptivityEnabled]=\"true\">\n <div class=\"ax-bg-lightest ax-border ax-border-default ax-rounded-md ax-shadow-md ax-w-full\">\n <axm-admin-notification-panel (onNewNotfication)=\"setTotalNewNotification($event)\"> </axm-admin-notification-panel>\n </div>\n</ax-popover>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i4$1.AXPopoverComponent, selector: "ax-popover", inputs: ["offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXMAdminNotificationPanelComponent, selector: "axm-admin-notification-panel", outputs: ["onNewNotfication"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
1616
1815
|
}
|
1617
1816
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMAdminNotificationSlotComponent, decorators: [{
|
1618
1817
|
type: Component,
|
@@ -1676,9 +1875,369 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
|
|
1676
1875
|
type: Injectable
|
1677
1876
|
}] });
|
1678
1877
|
|
1878
|
+
/**
|
1879
|
+
* Notification Widget Component
|
1880
|
+
* Displays notifications in a card with tabs
|
1881
|
+
*/
|
1882
|
+
class AXPNotificationWidgetViewComponent extends AXPValueWidgetComponent {
|
1883
|
+
constructor() {
|
1884
|
+
super();
|
1885
|
+
// Outputs
|
1886
|
+
this.notificationClick = output();
|
1887
|
+
this.markAsRead = output();
|
1888
|
+
// Dependencies
|
1889
|
+
this.cdr = inject(ChangeDetectorRef);
|
1890
|
+
this.datePipe = inject(DatePipe);
|
1891
|
+
this.notificationConnector = inject(AXMNotificationConnectorService);
|
1892
|
+
this.toastService = inject(AXToastService);
|
1893
|
+
// State
|
1894
|
+
this.activeTab = signal('new');
|
1895
|
+
this.refreshTimerId = null;
|
1896
|
+
// Configuration
|
1897
|
+
this.maxItems = computed(() => this.options()?.maxItems ?? 10);
|
1898
|
+
this.showAvatar = computed(() => this.options()?.showAvatar ?? true);
|
1899
|
+
this.showDate = computed(() => this.options()?.showDate ?? true);
|
1900
|
+
this.autoRefresh = computed(() => this.options()?.autoRefresh ?? true);
|
1901
|
+
this.refreshInterval = computed(() => (this.options()?.refreshInterval ?? 60) * 1000); // Convert to milliseconds
|
1902
|
+
// Use store's signals directly
|
1903
|
+
this.notifications = this.notificationConnector.notificationList;
|
1904
|
+
this.totalNotifications = this.notificationConnector.total;
|
1905
|
+
this.isLoading = this.notificationConnector.loading;
|
1906
|
+
// Computed data
|
1907
|
+
this.notificationItems = computed(() => {
|
1908
|
+
const items = this.notifications();
|
1909
|
+
if (!items?.length)
|
1910
|
+
return [];
|
1911
|
+
// Sort by pinned status and date
|
1912
|
+
const sortedItems = [...items].sort((a, b) => {
|
1913
|
+
if (a.template.isPinned === b.template.isPinned) {
|
1914
|
+
return new Date(b.createAt).getTime() - new Date(a.createAt).getTime();
|
1915
|
+
}
|
1916
|
+
return a.template.isPinned ? -1 : 1;
|
1917
|
+
});
|
1918
|
+
// Filter by active tab
|
1919
|
+
const filtered = this.activeTab() === 'new' ? sortedItems.filter((n) => !n.readAt) : sortedItems;
|
1920
|
+
return filtered.slice(0, this.maxItems());
|
1921
|
+
});
|
1922
|
+
// Watch for changes to auto-refresh settings
|
1923
|
+
effect(() => {
|
1924
|
+
this.setupAutoRefresh();
|
1925
|
+
});
|
1926
|
+
}
|
1927
|
+
ngOnInit() {
|
1928
|
+
this.loadNotifications();
|
1929
|
+
}
|
1930
|
+
ngOnDestroy() {
|
1931
|
+
this.clearRefreshTimer();
|
1932
|
+
}
|
1933
|
+
/**
|
1934
|
+
* Set up auto-refresh timer based on configuration
|
1935
|
+
*/
|
1936
|
+
setupAutoRefresh() {
|
1937
|
+
this.clearRefreshTimer();
|
1938
|
+
if (this.autoRefresh()) {
|
1939
|
+
const interval = this.refreshInterval();
|
1940
|
+
this.refreshTimerId = setInterval(() => {
|
1941
|
+
this.loadNotifications();
|
1942
|
+
}, interval);
|
1943
|
+
}
|
1944
|
+
}
|
1945
|
+
/**
|
1946
|
+
* Clear the refresh timer if it exists
|
1947
|
+
*/
|
1948
|
+
clearRefreshTimer() {
|
1949
|
+
if (this.refreshTimerId !== null) {
|
1950
|
+
clearInterval(this.refreshTimerId);
|
1951
|
+
this.refreshTimerId = null;
|
1952
|
+
}
|
1953
|
+
}
|
1954
|
+
/**
|
1955
|
+
* Load notifications data from service
|
1956
|
+
*/
|
1957
|
+
async loadNotifications() {
|
1958
|
+
try {
|
1959
|
+
await this.notificationConnector.getList();
|
1960
|
+
this.cdr.detectChanges();
|
1961
|
+
}
|
1962
|
+
catch (error) {
|
1963
|
+
this.toastService.show({
|
1964
|
+
content: typeof error === 'string' ? error : 'Failed to load notifications!',
|
1965
|
+
color: 'danger',
|
1966
|
+
location: 'bottom-center',
|
1967
|
+
closeButton: true,
|
1968
|
+
timeOut: 3000,
|
1969
|
+
timeOutProgress: true,
|
1970
|
+
});
|
1971
|
+
}
|
1972
|
+
}
|
1973
|
+
/**
|
1974
|
+
* Manually refresh notifications
|
1975
|
+
*/
|
1976
|
+
refreshNotifications() {
|
1977
|
+
this.loadNotifications();
|
1978
|
+
}
|
1979
|
+
/**
|
1980
|
+
* Get the count of new messages for the badge
|
1981
|
+
*/
|
1982
|
+
getNewMessageCount() {
|
1983
|
+
const items = this.notifications();
|
1984
|
+
if (!items?.length)
|
1985
|
+
return 0;
|
1986
|
+
return items.filter((n) => !n.readAt).length;
|
1987
|
+
}
|
1988
|
+
/**
|
1989
|
+
* Handle tab change event from ax-tabs component
|
1990
|
+
* @param data The tab change event data
|
1991
|
+
*/
|
1992
|
+
handleTabChange(data) {
|
1993
|
+
const index = data.index;
|
1994
|
+
// Map index to tab name: 0 = 'new', 1 = 'all'
|
1995
|
+
const tabName = index === 0 ? 'new' : 'all';
|
1996
|
+
this.onTabChange(tabName);
|
1997
|
+
}
|
1998
|
+
/**
|
1999
|
+
* Mark all notifications as read
|
2000
|
+
*/
|
2001
|
+
async markAllAsRead() {
|
2002
|
+
try {
|
2003
|
+
await this.notificationConnector.markAsRead({ id: [] });
|
2004
|
+
this.cdr.detectChanges();
|
2005
|
+
}
|
2006
|
+
catch (error) {
|
2007
|
+
this.toastService.show({
|
2008
|
+
content: 'Failed to mark notifications as read',
|
2009
|
+
color: 'danger',
|
2010
|
+
location: 'bottom-center',
|
2011
|
+
closeButton: true,
|
2012
|
+
timeOut: 3000,
|
2013
|
+
});
|
2014
|
+
}
|
2015
|
+
}
|
2016
|
+
/**
|
2017
|
+
* Change the active tab
|
2018
|
+
*/
|
2019
|
+
onTabChange(tabName) {
|
2020
|
+
this.activeTab.set(tabName);
|
2021
|
+
this.cdr.detectChanges();
|
2022
|
+
}
|
2023
|
+
/**
|
2024
|
+
* Handle notification click event
|
2025
|
+
*/
|
2026
|
+
onNotificationClick(notification) {
|
2027
|
+
this.markAsReadIfNeeded(notification);
|
2028
|
+
this.notificationClick.emit(notification);
|
2029
|
+
}
|
2030
|
+
/**
|
2031
|
+
* Format the timestamp in a user-friendly way
|
2032
|
+
*/
|
2033
|
+
formatTime(date) {
|
2034
|
+
if (!date)
|
2035
|
+
return '';
|
2036
|
+
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
2037
|
+
const diffDays = this.getDaysDifference(dateObj);
|
2038
|
+
// Format based on how recent the date is
|
2039
|
+
if (diffDays === 0)
|
2040
|
+
return this.datePipe.transform(dateObj, 'h:mm a') || ''; // Today
|
2041
|
+
if (diffDays === 1)
|
2042
|
+
return 'Yesterday';
|
2043
|
+
if (diffDays < 7)
|
2044
|
+
return this.datePipe.transform(dateObj, 'EEE') || ''; // Day of week
|
2045
|
+
return this.datePipe.transform(dateObj, 'MM/dd/yyyy') || ''; // Older date
|
2046
|
+
}
|
2047
|
+
/**
|
2048
|
+
* Mark notification as read if needed
|
2049
|
+
*/
|
2050
|
+
async markAsReadIfNeeded(notification) {
|
2051
|
+
try {
|
2052
|
+
// Always mark as read on click if unread, but don't toggle back to unread
|
2053
|
+
if (notification.readAt)
|
2054
|
+
return;
|
2055
|
+
await this.notificationConnector.markAsRead({ id: [notification.id] });
|
2056
|
+
// Emit the updated notification with readAt set
|
2057
|
+
// It will be read now because we only call this for unread notifications
|
2058
|
+
const updatedNotification = {
|
2059
|
+
...notification,
|
2060
|
+
readAt: new Date(),
|
2061
|
+
};
|
2062
|
+
this.markAsRead.emit(updatedNotification);
|
2063
|
+
this.cdr.detectChanges();
|
2064
|
+
}
|
2065
|
+
catch (error) {
|
2066
|
+
console.error('Failed to mark notification as read:', error);
|
2067
|
+
}
|
2068
|
+
}
|
2069
|
+
/**
|
2070
|
+
* Calculate days difference from now
|
2071
|
+
*/
|
2072
|
+
getDaysDifference(date) {
|
2073
|
+
const now = new Date();
|
2074
|
+
const diffMs = now.getTime() - date.getTime();
|
2075
|
+
return Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
2076
|
+
}
|
2077
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPNotificationWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
2078
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXPNotificationWidgetViewComponent, isStandalone: true, selector: "ng-component", outputs: { notificationClick: "notificationClick", markAsRead: "markAsRead" }, providers: [DatePipe], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-p-4 ax-size-full\">\n <ax-tabs\n class=\"ax-bg-light-start ax-border-b ax-border-default\"\n [fitParent]=\"true\"\n location=\"bottom\"\n (onActiveTabChanged)=\"handleTabChange($event)\"\n >\n <ax-tab-item [text]=\"('widget.notification.new' | translate | async) ?? 'New'\" class=\"ax-font-medium\">\n <ax-suffix>\n @if (getNewMessageCount() > 0) {\n <ax-badge color=\"primary\" [text]=\"getNewMessageCount().toString()\" size=\"sm\" class=\"ax-ml-1\"></ax-badge>\n }\n </ax-suffix>\n </ax-tab-item>\n <ax-tab-item [text]=\"('widget.notification.all' | translate | async) ?? 'All'\" class=\"ax-font-medium\"></ax-tab-item>\n </ax-tabs>\n <div class=\"ax-space-y-4 ax-mt-4 ax-px-2\">\n @for (item of notificationItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"chatItemTemplateRef\" [ngTemplateOutletContext]=\"{ $implicit: item }\">\n </ng-container>\n } @empty {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-py-12 ax-px-4 ax-text-gray-400\">\n <ax-icon class=\"ax-text-4xl ax-mb-3 ax-text-gray-300\">\n <i class=\"fa-light fa-bell-slash\"></i>\n </ax-icon>\n <p class=\"ax-text-center\">{{ 'widget.notification.noNotifications' | translate | async }}</p>\n </div>\n }\n </div>\n</div>\n\n<ng-template #chatItemTemplateRef let-data>\n <div class=\"ax-flex ax-gap-3\">\n @if(showAvatar()){\n <axp-user-avatar [size]=\"40\" [userId]=\"data.user?.id\"></axp-user-avatar>\n }\n <div class=\"ax-overflow-hidden ax-grow ax-text-start\">\n <h6 class=\"ax-pb-2 ax-font-semibold ax-truncate\">{{ data.user?.name || data.title }}</h6>\n <p class=\"ax-text-xs ax-truncate\">{{ data.body }}</p>\n </div>\n @if(showDate()){\n <div class=\"ax-text-xs ax-shrink-0\">\n <span>\n {{ formatTime(data.createdAt) }}\n </span>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "component", type: AXPUserAvatarComponent, selector: "axp-user-avatar", inputs: ["size", "userId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
2079
|
+
}
|
2080
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPNotificationWidgetViewComponent, decorators: [{
|
2081
|
+
type: Component,
|
2082
|
+
args: [{ standalone: true, imports: [
|
2083
|
+
CommonModule,
|
2084
|
+
AXTabsModule,
|
2085
|
+
AXDecoratorModule,
|
2086
|
+
AXButtonModule,
|
2087
|
+
AXBadgeModule,
|
2088
|
+
AXAvatarModule,
|
2089
|
+
AXImageModule,
|
2090
|
+
AXTranslationModule,
|
2091
|
+
AXPUserAvatarComponent,
|
2092
|
+
], providers: [DatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-p-4 ax-size-full\">\n <ax-tabs\n class=\"ax-bg-light-start ax-border-b ax-border-default\"\n [fitParent]=\"true\"\n location=\"bottom\"\n (onActiveTabChanged)=\"handleTabChange($event)\"\n >\n <ax-tab-item [text]=\"('widget.notification.new' | translate | async) ?? 'New'\" class=\"ax-font-medium\">\n <ax-suffix>\n @if (getNewMessageCount() > 0) {\n <ax-badge color=\"primary\" [text]=\"getNewMessageCount().toString()\" size=\"sm\" class=\"ax-ml-1\"></ax-badge>\n }\n </ax-suffix>\n </ax-tab-item>\n <ax-tab-item [text]=\"('widget.notification.all' | translate | async) ?? 'All'\" class=\"ax-font-medium\"></ax-tab-item>\n </ax-tabs>\n <div class=\"ax-space-y-4 ax-mt-4 ax-px-2\">\n @for (item of notificationItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"chatItemTemplateRef\" [ngTemplateOutletContext]=\"{ $implicit: item }\">\n </ng-container>\n } @empty {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-py-12 ax-px-4 ax-text-gray-400\">\n <ax-icon class=\"ax-text-4xl ax-mb-3 ax-text-gray-300\">\n <i class=\"fa-light fa-bell-slash\"></i>\n </ax-icon>\n <p class=\"ax-text-center\">{{ 'widget.notification.noNotifications' | translate | async }}</p>\n </div>\n }\n </div>\n</div>\n\n<ng-template #chatItemTemplateRef let-data>\n <div class=\"ax-flex ax-gap-3\">\n @if(showAvatar()){\n <axp-user-avatar [size]=\"40\" [userId]=\"data.user?.id\"></axp-user-avatar>\n }\n <div class=\"ax-overflow-hidden ax-grow ax-text-start\">\n <h6 class=\"ax-pb-2 ax-font-semibold ax-truncate\">{{ data.user?.name || data.title }}</h6>\n <p class=\"ax-text-xs ax-truncate\">{{ data.body }}</p>\n </div>\n @if(showDate()){\n <div class=\"ax-text-xs ax-shrink-0\">\n <span>\n {{ formatTime(data.createdAt) }}\n </span>\n </div>\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
2093
|
+
}], ctorParameters: () => [] });
|
2094
|
+
|
2095
|
+
var notificationWidget_component = /*#__PURE__*/Object.freeze({
|
2096
|
+
__proto__: null,
|
2097
|
+
AXPNotificationWidgetViewComponent: AXPNotificationWidgetViewComponent
|
2098
|
+
});
|
2099
|
+
|
2100
|
+
/**
|
2101
|
+
* Configuration for the Notification Widget
|
2102
|
+
*/
|
2103
|
+
const AXPMyNotificationDashboardWidget = {
|
2104
|
+
name: 'my-notification-dashboard',
|
2105
|
+
title: 'My Notification Widget',
|
2106
|
+
categories: [AXP_WIDGETS_UTILITY_CATEGORY],
|
2107
|
+
groups: [AXPWidgetGroupEnum.DashboardWidget],
|
2108
|
+
type: 'dashboard',
|
2109
|
+
description: 'Displays notifications in a widget format',
|
2110
|
+
icon: 'fa-regular fa-bell',
|
2111
|
+
properties: [
|
2112
|
+
cloneProperty(AXP_DATA_PATH_PROPERTY, { visible: false }),
|
2113
|
+
// ====== Title ======
|
2114
|
+
{
|
2115
|
+
name: 'title',
|
2116
|
+
title: 'Chart Title',
|
2117
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2118
|
+
schema: {
|
2119
|
+
defaultValue: '',
|
2120
|
+
dataType: 'string',
|
2121
|
+
interface: {
|
2122
|
+
name: 'title',
|
2123
|
+
path: 'options.title',
|
2124
|
+
type: AXPWidgetsCatalog.text,
|
2125
|
+
options: {
|
2126
|
+
placeholder: 'Enter chart title',
|
2127
|
+
},
|
2128
|
+
},
|
2129
|
+
},
|
2130
|
+
visible: true,
|
2131
|
+
},
|
2132
|
+
{
|
2133
|
+
name: 'maxItems',
|
2134
|
+
title: 'Max Items',
|
2135
|
+
description: 'Maximum number of notification items to display',
|
2136
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
2137
|
+
schema: {
|
2138
|
+
defaultValue: 10,
|
2139
|
+
dataType: 'number',
|
2140
|
+
interface: {
|
2141
|
+
name: 'maxItems',
|
2142
|
+
path: 'options.maxItems',
|
2143
|
+
type: AXPWidgetsCatalog.number,
|
2144
|
+
options: {
|
2145
|
+
minValue: 1,
|
2146
|
+
maxValue: 100,
|
2147
|
+
},
|
2148
|
+
},
|
2149
|
+
},
|
2150
|
+
visible: true,
|
2151
|
+
},
|
2152
|
+
{
|
2153
|
+
name: 'showAvatar',
|
2154
|
+
title: 'Show Avatar',
|
2155
|
+
description: 'Whether to show avatars in notifications',
|
2156
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2157
|
+
schema: {
|
2158
|
+
defaultValue: true,
|
2159
|
+
dataType: 'boolean',
|
2160
|
+
interface: {
|
2161
|
+
name: 'showAvatar',
|
2162
|
+
path: 'options.showAvatar',
|
2163
|
+
type: AXPWidgetsCatalog.toggle,
|
2164
|
+
},
|
2165
|
+
},
|
2166
|
+
visible: true,
|
2167
|
+
},
|
2168
|
+
{
|
2169
|
+
name: 'showDate',
|
2170
|
+
title: 'Show Date',
|
2171
|
+
description: 'Whether to show date in notifications',
|
2172
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2173
|
+
schema: {
|
2174
|
+
defaultValue: true,
|
2175
|
+
dataType: 'boolean',
|
2176
|
+
interface: {
|
2177
|
+
name: 'showDate',
|
2178
|
+
path: 'options.showDate',
|
2179
|
+
type: AXPWidgetsCatalog.toggle,
|
2180
|
+
},
|
2181
|
+
},
|
2182
|
+
visible: true,
|
2183
|
+
},
|
2184
|
+
{
|
2185
|
+
name: 'autoRefresh',
|
2186
|
+
title: 'Auto Refresh',
|
2187
|
+
description: 'Automatically refresh notifications at regular intervals',
|
2188
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2189
|
+
schema: {
|
2190
|
+
defaultValue: true,
|
2191
|
+
dataType: 'boolean',
|
2192
|
+
interface: {
|
2193
|
+
name: 'autoRefresh',
|
2194
|
+
path: 'options.autoRefresh',
|
2195
|
+
type: AXPWidgetsCatalog.toggle,
|
2196
|
+
},
|
2197
|
+
},
|
2198
|
+
visible: true,
|
2199
|
+
},
|
2200
|
+
{
|
2201
|
+
name: 'refreshInterval',
|
2202
|
+
title: 'Refresh Interval (seconds)',
|
2203
|
+
description: 'Interval in seconds between automatic refreshes',
|
2204
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2205
|
+
schema: {
|
2206
|
+
defaultValue: 60,
|
2207
|
+
dataType: 'number',
|
2208
|
+
interface: {
|
2209
|
+
name: 'refreshInterval',
|
2210
|
+
path: 'options.refreshInterval',
|
2211
|
+
type: AXPWidgetsCatalog.number,
|
2212
|
+
options: {
|
2213
|
+
minValue: 10,
|
2214
|
+
maxValue: 3600,
|
2215
|
+
},
|
2216
|
+
},
|
2217
|
+
},
|
2218
|
+
visible: true,
|
2219
|
+
},
|
2220
|
+
],
|
2221
|
+
components: {
|
2222
|
+
view: {
|
2223
|
+
component: () => Promise.resolve().then(function () { return notificationWidget_component; }).then((c) => c.AXPNotificationWidgetViewComponent),
|
2224
|
+
},
|
2225
|
+
},
|
2226
|
+
meta: {
|
2227
|
+
dimensions: {
|
2228
|
+
width: 3,
|
2229
|
+
height: 5,
|
2230
|
+
minWidth: 2,
|
2231
|
+
minHeight: 4,
|
2232
|
+
maxWidth: 4,
|
2233
|
+
maxHeight: 7,
|
2234
|
+
},
|
2235
|
+
},
|
2236
|
+
};
|
2237
|
+
|
1679
2238
|
class AXMNotificationManagementModule {
|
1680
2239
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
1681
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationManagementModule, imports: [i1$2.AXPComponentSlotModule] }); }
|
2240
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationManagementModule, imports: [i1$2.AXPComponentSlotModule, i2$1.AXPLayoutBuilderModule] }); }
|
1682
2241
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationManagementModule, providers: [
|
1683
2242
|
{
|
1684
2243
|
provide: AXMNotificationManagementTemplateEntityService,
|
@@ -1718,6 +2277,11 @@ class AXMNotificationManagementModule {
|
|
1718
2277
|
component: AXMAdminNotificationSlotComponent,
|
1719
2278
|
},
|
1720
2279
|
],
|
2280
|
+
}),
|
2281
|
+
AXPLayoutBuilderModule.forChild({
|
2282
|
+
widgets: [
|
2283
|
+
AXPMyNotificationDashboardWidget,
|
2284
|
+
],
|
1721
2285
|
})] }); }
|
1722
2286
|
}
|
1723
2287
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMNotificationManagementModule, decorators: [{
|
@@ -1732,6 +2296,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
|
|
1732
2296
|
},
|
1733
2297
|
],
|
1734
2298
|
}),
|
2299
|
+
AXPLayoutBuilderModule.forChild({
|
2300
|
+
widgets: [
|
2301
|
+
AXPMyNotificationDashboardWidget,
|
2302
|
+
],
|
2303
|
+
}),
|
1735
2304
|
],
|
1736
2305
|
exports: [],
|
1737
2306
|
declarations: [],
|
@@ -2398,5 +2967,5 @@ async function notificationLogEntityFactory(injector) {
|
|
2398
2967
|
* Generated bundle index. Do not edit.
|
2399
2968
|
*/
|
2400
2969
|
|
2401
|
-
export { AXMNotificationEntityService, AXMNotificationEntityServiceImpl, AXMNotificationManagementChannelEntityService, AXMNotificationManagementChannelEntityServiceImpl, AXMNotificationManagementModule, AXMNotificationManagementTemplateEntityModule, AXMNotificationManagementTemplateEntityService, AXMNotificationManagementTemplateEntityServiceImpl, AXMNotificationManagmentModuleMenuProvider, AXMSettingProvider, RootConfig, myNotificationEntityFactory, notificationChannelEntityFactory, notificationEntityFactory, notificationLogEntityFactory, notificationTemplateEntityFactory };
|
2970
|
+
export { AXMNotificationEntityService, AXMNotificationEntityServiceImpl, AXMNotificationManagementChannelEntityService, AXMNotificationManagementChannelEntityServiceImpl, AXMNotificationManagementModule, AXMNotificationManagementTemplateEntityModule, AXMNotificationManagementTemplateEntityService, AXMNotificationManagementTemplateEntityServiceImpl, AXMNotificationManagmentModuleMenuProvider, AXMSettingProvider, AXPMyNotificationDashboardWidget, AXPNotificationWidgetViewComponent, RootConfig, myNotificationEntityFactory, notificationChannelEntityFactory, notificationEntityFactory, notificationLogEntityFactory, notificationTemplateEntityFactory };
|
2402
2971
|
//# sourceMappingURL=acorex-modules-notification-management.mjs.map
|