@acorex/modules 20.1.0 → 20.2.0-next.1
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/auth/index.d.ts +4 -57
- package/calendar-management/index.d.ts +47 -26
- package/conversation/index.d.ts +69 -9
- package/dashboard-management/index.d.ts +2 -0
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-5TIjp5UG.mjs → acorex-modules-auth-acorex-modules-auth-y6rICHrT.mjs} +84 -201
- package/fesm2022/acorex-modules-auth-acorex-modules-auth-y6rICHrT.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-app-chooser.component-B0w1Xzx7.mjs → acorex-modules-auth-app-chooser.component-Cpy0VN6n.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-app-chooser.component-B0w1Xzx7.mjs.map → acorex-modules-auth-app-chooser.component-Cpy0VN6n.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-login.module-B8sVVZHV.mjs → acorex-modules-auth-login.module-ZEX4NMuJ.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-login.module-B8sVVZHV.mjs.map → acorex-modules-auth-login.module-ZEX4NMuJ.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-master.layout-CMKxj1Qo.mjs → acorex-modules-auth-master.layout-D-lIn4Pl.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-master.layout-CMKxj1Qo.mjs.map → acorex-modules-auth-master.layout-D-lIn4Pl.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-DH0qKunk.mjs → acorex-modules-auth-password.component-CafZfqKe.mjs} +7 -7
- package/fesm2022/{acorex-modules-auth-password.component-DH0qKunk.mjs.map → acorex-modules-auth-password.component-CafZfqKe.mjs.map} +1 -1
- package/fesm2022/acorex-modules-auth-password.component-DLCb0_6e.mjs +134 -0
- package/fesm2022/acorex-modules-auth-password.component-DLCb0_6e.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-routes-Q9zaIiBS.mjs → acorex-modules-auth-routes-D9-qfC3V.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-routes-Q9zaIiBS.mjs.map → acorex-modules-auth-routes-D9-qfC3V.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-tenant-chooser.component-wp7OOLsH.mjs → acorex-modules-auth-tenant-chooser.component-B1aE-TOD.mjs} +10 -13
- package/fesm2022/acorex-modules-auth-tenant-chooser.component-B1aE-TOD.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-two-factor-code.component-DSWd06bn.mjs → acorex-modules-auth-two-factor-code.component-BglerlU-.mjs} +6 -6
- package/fesm2022/{acorex-modules-auth-two-factor-code.component-DSWd06bn.mjs.map → acorex-modules-auth-two-factor-code.component-BglerlU-.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-two-factor.module-oRixkeAn.mjs → acorex-modules-auth-two-factor.module-D3N2XyOH.mjs} +3 -3
- package/fesm2022/{acorex-modules-auth-two-factor.module-oRixkeAn.mjs.map → acorex-modules-auth-two-factor.module-D3N2XyOH.mjs.map} +1 -1
- package/fesm2022/acorex-modules-auth.mjs +1 -1
- package/fesm2022/acorex-modules-calendar-management.mjs +353 -315
- package/fesm2022/acorex-modules-calendar-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-common-acorex-modules-common-DQESb8jf.mjs → acorex-modules-common-acorex-modules-common-D06CT4CO.mjs} +6 -16
- package/fesm2022/acorex-modules-common-acorex-modules-common-D06CT4CO.mjs.map +1 -0
- package/fesm2022/{acorex-modules-common-search-popup.component-CpFvcrxw.mjs → acorex-modules-common-search-popup.component-DbTj01Wz.mjs} +2 -2
- package/fesm2022/{acorex-modules-common-search-popup.component-CpFvcrxw.mjs.map → acorex-modules-common-search-popup.component-DbTj01Wz.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-common-settings.provider-ha75F6g5.mjs → acorex-modules-common-settings.provider-DPVsF4c9.mjs} +2 -2
- package/fesm2022/{acorex-modules-common-settings.provider-ha75F6g5.mjs.map → acorex-modules-common-settings.provider-DPVsF4c9.mjs.map} +1 -1
- package/fesm2022/acorex-modules-common.mjs +1 -1
- package/fesm2022/acorex-modules-conversation.mjs +487 -57
- package/fesm2022/acorex-modules-conversation.mjs.map +1 -1
- package/fesm2022/acorex-modules-dashboard-management.mjs +1 -1
- package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-data-management.mjs +3 -3
- package/fesm2022/acorex-modules-data-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-document-management-acorex-modules-document-management-B4Jd-KGV.mjs → acorex-modules-document-management-acorex-modules-document-management-C7ot6PfT.mjs} +411 -51
- package/fesm2022/acorex-modules-document-management-acorex-modules-document-management-C7ot6PfT.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-attachment-widget.component-Bp4kKjC4.mjs → acorex-modules-document-management-attachment-widget.component-C6pop0RM.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-attachment-widget.component-Bp4kKjC4.mjs.map → acorex-modules-document-management-attachment-widget.component-C6pop0RM.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-create-folder-dialog.component-12aUAucS.mjs → acorex-modules-document-management-create-folder-dialog.component-ga7fuY4H.mjs} +4 -4
- package/fesm2022/acorex-modules-document-management-create-folder-dialog.component-ga7fuY4H.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-details-view.component-bzA7fJZW.mjs → acorex-modules-document-management-details-view.component-CzTg3hha.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-details-view.component-bzA7fJZW.mjs.map → acorex-modules-document-management-details-view.component-CzTg3hha.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-drive-choose.component-DLJdJzp1.mjs → acorex-modules-document-management-drive-choose.component-BB5d32EI.mjs} +5 -5
- package/fesm2022/{acorex-modules-document-management-drive-choose.component-DLJdJzp1.mjs.map → acorex-modules-document-management-drive-choose.component-BB5d32EI.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-drive.component-DrkSd6Rv.mjs → acorex-modules-document-management-drive.component-TzRLr7rb.mjs} +7 -7
- package/fesm2022/{acorex-modules-document-management-drive.component-DrkSd6Rv.mjs.map → acorex-modules-document-management-drive.component-TzRLr7rb.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-large-icons-view.component-DV8oWdDh.mjs → acorex-modules-document-management-large-icons-view.component-BeKFvgYU.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-large-icons-view.component-DV8oWdDh.mjs.map → acorex-modules-document-management-large-icons-view.component-BeKFvgYU.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-large-tiles-view.component-Bgr9s_zf.mjs → acorex-modules-document-management-large-tiles-view.component-CQyiGE99.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-large-tiles-view.component-Bgr9s_zf.mjs.map → acorex-modules-document-management-large-tiles-view.component-CQyiGE99.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-link-dialog.component-CSEIhT4P.mjs → acorex-modules-document-management-link-dialog.component-CPuOuvu-.mjs} +2 -2
- package/fesm2022/acorex-modules-document-management-link-dialog.component-CPuOuvu-.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-list-view.component-Dz6ymqrq.mjs → acorex-modules-document-management-list-view.component-CWGGArxw.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-list-view.component-Dz6ymqrq.mjs.map → acorex-modules-document-management-list-view.component-CWGGArxw.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-meta-choose-popup.component-DYJN-4Pe.mjs → acorex-modules-document-management-meta-choose-popup.component-C7ounW6N.mjs} +8 -9
- package/fesm2022/acorex-modules-document-management-meta-choose-popup.component-C7ounW6N.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-permission-definition.provider-CN7HVQLu.mjs → acorex-modules-document-management-permission-definition.provider-s0P0M8p2.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-permission-definition.provider-CN7HVQLu.mjs.map → acorex-modules-document-management-permission-definition.provider-s0P0M8p2.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-rename-node-dialog.component-C_dsLLMb.mjs → acorex-modules-document-management-rename-node-dialog.component-MPkYZl2p.mjs} +4 -4
- package/fesm2022/{acorex-modules-document-management-rename-node-dialog.component-C_dsLLMb.mjs.map → acorex-modules-document-management-rename-node-dialog.component-MPkYZl2p.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-share-dialog.component-CBrf7hjZ.mjs → acorex-modules-document-management-share-dialog.component-CLF6b1Io.mjs} +2 -2
- package/fesm2022/acorex-modules-document-management-share-dialog.component-CLF6b1Io.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-share-email-dialog.component-D3WcHAOf.mjs → acorex-modules-document-management-share-email-dialog.component-B8zNvOUv.mjs} +2 -2
- package/fesm2022/acorex-modules-document-management-share-email-dialog.component-B8zNvOUv.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-small-icons-view.component-wvFkjOqg.mjs → acorex-modules-document-management-small-icons-view.component-DRVLlW1e.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-small-icons-view.component-wvFkjOqg.mjs.map → acorex-modules-document-management-small-icons-view.component-DRVLlW1e.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-small-tiles-view.component-C4ARGOZR.mjs → acorex-modules-document-management-small-tiles-view.component-C1E8RKYM.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-small-tiles-view.component-C4ARGOZR.mjs.map → acorex-modules-document-management-small-tiles-view.component-C1E8RKYM.mjs.map} +1 -1
- package/fesm2022/acorex-modules-document-management.mjs +1 -1
- package/fesm2022/{acorex-modules-issue-management-acorex-modules-issue-management-B8ZVc-0b.mjs → acorex-modules-issue-management-acorex-modules-issue-management-ITP4K-tZ.mjs} +3 -3
- package/fesm2022/{acorex-modules-issue-management-acorex-modules-issue-management-B8ZVc-0b.mjs.map → acorex-modules-issue-management-acorex-modules-issue-management-ITP4K-tZ.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-issue-management-capture-screen.component-D1vapaJC.mjs → acorex-modules-issue-management-capture-screen.component-C1USFJeP.mjs} +2 -2
- package/fesm2022/{acorex-modules-issue-management-capture-screen.component-D1vapaJC.mjs.map → acorex-modules-issue-management-capture-screen.component-C1USFJeP.mjs.map} +1 -1
- package/fesm2022/acorex-modules-issue-management.mjs +1 -1
- package/fesm2022/acorex-modules-notification-management.mjs +109 -3
- package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-organization-management-add-item.component-DsDk5cyO.mjs → acorex-modules-organization-management-add-item.component-Dr-bwC4K.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-add-item.component-Dr-bwC4K.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-org-chart.page-DWQ-5NF_.mjs → acorex-modules-organization-management-org-chart.page-CXhtYrCS.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-org-chart.page-DWQ-5NF_.mjs.map → acorex-modules-organization-management-org-chart.page-CXhtYrCS.mjs.map} +1 -1
- package/fesm2022/acorex-modules-organization-management.mjs +2 -2
- package/fesm2022/acorex-modules-platform-management.mjs +43 -19
- package/fesm2022/acorex-modules-platform-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-project-management.mjs +48 -38
- package/fesm2022/acorex-modules-project-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-report-management-report-create-root.component-DgouOz2M.mjs → acorex-modules-report-management-report-create-root.component-Cv88TDx7.mjs} +2 -2
- package/fesm2022/acorex-modules-report-management-report-create-root.component-Cv88TDx7.mjs.map +1 -0
- package/fesm2022/acorex-modules-report-management.mjs +1 -1
- package/fesm2022/acorex-modules-security-management.mjs +301 -837
- package/fesm2022/acorex-modules-security-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-workflow-management-acorex-modules-workflow-management-enYapFRb.mjs +213 -0
- package/fesm2022/acorex-modules-workflow-management-acorex-modules-workflow-management-enYapFRb.mjs.map +1 -0
- package/fesm2022/{acorex-modules-workflow-management-task-board.page-BoG_tFGn.mjs → acorex-modules-workflow-management-task-board.page-CPL7HwN4.mjs} +21 -20
- package/fesm2022/acorex-modules-workflow-management-task-board.page-CPL7HwN4.mjs.map +1 -0
- package/fesm2022/acorex-modules-workflow-management.mjs +1 -143
- package/fesm2022/acorex-modules-workflow-management.mjs.map +1 -1
- package/notification-management/index.d.ts +125 -29
- package/package.json +9 -9
- package/report-management/index.d.ts +2 -0
- package/security-management/index.d.ts +4 -13
- package/workflow-management/index.d.ts +11 -2
- package/fesm2022/acorex-modules-auth-acorex-modules-auth-5TIjp5UG.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-oauth-callback.component-C95YLpI_.mjs +0 -101
- package/fesm2022/acorex-modules-auth-oauth-callback.component-C95YLpI_.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-password.component-Du0EBIiw.mjs +0 -239
- package/fesm2022/acorex-modules-auth-password.component-Du0EBIiw.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-tenant-chooser.component-wp7OOLsH.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-user-sessions.component-8wwWI0cQ.mjs +0 -135
- package/fesm2022/acorex-modules-auth-user-sessions.component-8wwWI0cQ.mjs.map +0 -1
- package/fesm2022/acorex-modules-common-acorex-modules-common-DQESb8jf.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-acorex-modules-document-management-B4Jd-KGV.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-create-folder-dialog.component-12aUAucS.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-link-dialog.component-CSEIhT4P.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-meta-choose-popup.component-DYJN-4Pe.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-share-dialog.component-CBrf7hjZ.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-share-email-dialog.component-D3WcHAOf.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-add-item.component-DsDk5cyO.mjs.map +0 -1
- package/fesm2022/acorex-modules-report-management-report-create-root.component-DgouOz2M.mjs.map +0 -1
- package/fesm2022/acorex-modules-workflow-management-task-board.page-BoG_tFGn.mjs.map +0 -1
@@ -6,7 +6,7 @@ import { AXPRootLayoutComponent } from '@acorex/platform/themes/default';
|
|
6
6
|
import * as i1$2 from '@angular/common';
|
7
7
|
import { AsyncPipe, CommonModule, DatePipe } from '@angular/common';
|
8
8
|
import * as i0 from '@angular/core';
|
9
|
-
import { Injectable, inject, input, signal, viewChild, DestroyRef, ChangeDetectionStrategy, Component, ViewEncapsulation, computed, output, effect,
|
9
|
+
import { Injectable, inject, input, signal, viewChild, DestroyRef, ChangeDetectionStrategy, Component, ViewEncapsulation, computed, output, effect, HostListener, afterNextRender, importProvidersFrom, NgModule } from '@angular/core';
|
10
10
|
import * as i2$3 from '@angular/router';
|
11
11
|
import { ActivatedRoute, Router, NavigationEnd, RouterModule, ROUTES } from '@angular/router';
|
12
12
|
import { createAllQueryView, AXPEntityCommandScope, AXPEntityQueryType, AXPFilterOperatorMiddlewareService, AXP_MENU_PROVIDER } from '@acorex/platform/common';
|
@@ -53,6 +53,7 @@ import { AXFormatModule } from '@acorex/core/format';
|
|
53
53
|
import * as i4$1 from '@acorex/core/translation';
|
54
54
|
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
|
55
55
|
import { AXUnsubscriber } from '@acorex/core/utils';
|
56
|
+
import { AXMOsNotificationService, AXMNotificationConnectorService } from '@acorex/modules/notification-management';
|
56
57
|
import { AXPUserAvatarComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutToolbarComponent } from '@acorex/platform/layout/components';
|
57
58
|
import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex/platform/layout/views';
|
58
59
|
import { trigger, transition, style, animate } from '@angular/animations';
|
@@ -93,6 +94,12 @@ const RootConfig = {
|
|
93
94
|
source: `${config.module}.Message`,
|
94
95
|
icon: 'fa-light fa-message',
|
95
96
|
},
|
97
|
+
tab: {
|
98
|
+
name: 'tab',
|
99
|
+
title: `t("tab.plural-title", { scope: "${config.i18n}" })`,
|
100
|
+
source: `${config.module}.Tab`,
|
101
|
+
icon: 'fa-light fa-folder',
|
102
|
+
},
|
96
103
|
},
|
97
104
|
};
|
98
105
|
|
@@ -650,6 +657,234 @@ async function roomFactory(injector) {
|
|
650
657
|
return entityDef;
|
651
658
|
}
|
652
659
|
|
660
|
+
class AXMConversationTabService extends AXMEntityCrudServiceImpl {
|
661
|
+
}
|
662
|
+
class AXMConversationTabServiceImpl extends AXMConversationTabService {
|
663
|
+
constructor() {
|
664
|
+
super(`${RootConfig.module.name}.${RootConfig.entities.tab.name}`);
|
665
|
+
}
|
666
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConversationTabServiceImpl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
667
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConversationTabServiceImpl }); }
|
668
|
+
}
|
669
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMConversationTabServiceImpl, decorators: [{
|
670
|
+
type: Injectable
|
671
|
+
}], ctorParameters: () => [] });
|
672
|
+
|
673
|
+
async function tabFactory(injector) {
|
674
|
+
const dataService = injector.get(AXMConversationTabService);
|
675
|
+
const i18n = RootConfig.config.i18n;
|
676
|
+
const entityDef = {
|
677
|
+
module: RootConfig.module.name,
|
678
|
+
name: RootConfig.entities.tab.name,
|
679
|
+
source: '',
|
680
|
+
title: RootConfig.entities.tab.title,
|
681
|
+
formats: {
|
682
|
+
individual: `t("tab.individual-title", { scope: "${i18n}" })`,
|
683
|
+
plural: RootConfig.entities.tab.title,
|
684
|
+
searchResult: {
|
685
|
+
title: '{{ title }}',
|
686
|
+
description: RootConfig.module.title,
|
687
|
+
},
|
688
|
+
},
|
689
|
+
relatedEntities: [],
|
690
|
+
groups: [
|
691
|
+
{
|
692
|
+
id: 'section',
|
693
|
+
title: `t("tab.basic-info", { scope: "${i18n}" })`,
|
694
|
+
},
|
695
|
+
],
|
696
|
+
properties: [
|
697
|
+
{
|
698
|
+
name: 'name',
|
699
|
+
title: `t("tab.props.name", { scope: "${i18n}" })`,
|
700
|
+
groupId: 'section',
|
701
|
+
schema: {
|
702
|
+
dataType: 'string',
|
703
|
+
interface: {
|
704
|
+
type: AXPWidgetsCatalog.text,
|
705
|
+
},
|
706
|
+
},
|
707
|
+
validations: [{ rule: 'required' }],
|
708
|
+
},
|
709
|
+
{
|
710
|
+
name: 'title',
|
711
|
+
title: `t("tab.props.title", { scope: "${i18n}" })`,
|
712
|
+
groupId: 'section',
|
713
|
+
schema: {
|
714
|
+
dataType: 'string',
|
715
|
+
interface: {
|
716
|
+
type: AXPWidgetsCatalog.text,
|
717
|
+
},
|
718
|
+
},
|
719
|
+
validations: [{ rule: 'required' }],
|
720
|
+
},
|
721
|
+
{
|
722
|
+
name: 'color',
|
723
|
+
title: `t("tab.props.color", { scope: "${i18n}" })`,
|
724
|
+
groupId: 'section',
|
725
|
+
schema: {
|
726
|
+
dataType: 'string',
|
727
|
+
interface: {
|
728
|
+
type: AXPWidgetsCatalog.color,
|
729
|
+
},
|
730
|
+
},
|
731
|
+
},
|
732
|
+
{
|
733
|
+
name: 'rooms',
|
734
|
+
title: `t("tab.props.rooms", { scope: "${i18n}" })`,
|
735
|
+
groupId: 'section',
|
736
|
+
schema: {
|
737
|
+
dataType: 'string',
|
738
|
+
interface: {
|
739
|
+
type: AXPWidgetsCatalog.lookup,
|
740
|
+
options: {
|
741
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.room.name}`,
|
742
|
+
multiple: true,
|
743
|
+
},
|
744
|
+
},
|
745
|
+
},
|
746
|
+
},
|
747
|
+
{
|
748
|
+
name: 'excludeRooms',
|
749
|
+
title: `t("tab.props.excludeRooms", { scope: "${i18n}" })`,
|
750
|
+
groupId: 'section',
|
751
|
+
schema: {
|
752
|
+
dataType: 'string',
|
753
|
+
interface: {
|
754
|
+
type: AXPWidgetsCatalog.lookup,
|
755
|
+
options: {
|
756
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.room.name}`,
|
757
|
+
multiple: true,
|
758
|
+
},
|
759
|
+
},
|
760
|
+
},
|
761
|
+
},
|
762
|
+
{
|
763
|
+
name: 'includeRooms',
|
764
|
+
title: `t("tab.props.includeRooms", { scope: "${i18n}" })`,
|
765
|
+
groupId: 'section',
|
766
|
+
schema: {
|
767
|
+
dataType: 'string',
|
768
|
+
interface: {
|
769
|
+
type: AXPWidgetsCatalog.lookup,
|
770
|
+
options: {
|
771
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.room.name}`,
|
772
|
+
multiple: true,
|
773
|
+
},
|
774
|
+
},
|
775
|
+
},
|
776
|
+
},
|
777
|
+
],
|
778
|
+
columns: [{ name: 'name' }, { name: 'title' }],
|
779
|
+
commands: {
|
780
|
+
create: {
|
781
|
+
execute: async (data) => {
|
782
|
+
const res = await dataService.insertOne(data);
|
783
|
+
return { id: res };
|
784
|
+
},
|
785
|
+
},
|
786
|
+
delete: {
|
787
|
+
execute: async (id) => {
|
788
|
+
return await dataService.deleteOne(id);
|
789
|
+
},
|
790
|
+
},
|
791
|
+
update: {
|
792
|
+
execute: async (data) => {
|
793
|
+
return await dataService.updateOne(data.id, data);
|
794
|
+
},
|
795
|
+
},
|
796
|
+
},
|
797
|
+
queries: {
|
798
|
+
byKey: {
|
799
|
+
execute: async (id) => {
|
800
|
+
return await dataService.getOne(id);
|
801
|
+
},
|
802
|
+
type: AXPEntityQueryType.Single,
|
803
|
+
},
|
804
|
+
list: {
|
805
|
+
execute: async (e) => {
|
806
|
+
return await dataService.query({ skip: e.skip, take: e.take, filter: e.filter });
|
807
|
+
},
|
808
|
+
type: AXPEntityQueryType.List,
|
809
|
+
},
|
810
|
+
},
|
811
|
+
interfaces: {
|
812
|
+
master: {
|
813
|
+
create: {
|
814
|
+
sections: [{ id: 'section' }],
|
815
|
+
properties: [
|
816
|
+
{ name: 'name', layout: { positions: { lg: { colSpan: 6 } } } },
|
817
|
+
{ name: 'title', layout: { positions: { lg: { colSpan: 6 } } } },
|
818
|
+
{ name: 'color', layout: { positions: { lg: { colSpan: 12 } } } },
|
819
|
+
{ name: 'rooms', layout: { positions: { lg: { colSpan: 12 } } } },
|
820
|
+
{ name: 'excludeRooms', layout: { positions: { lg: { colSpan: 12 } } } },
|
821
|
+
{ name: 'includeRooms', layout: { positions: { lg: { colSpan: 12 } } } },
|
822
|
+
],
|
823
|
+
},
|
824
|
+
update: {
|
825
|
+
sections: [{ id: 'section' }],
|
826
|
+
properties: [
|
827
|
+
{ name: 'name', layout: { positions: { lg: { colSpan: 6 } } } },
|
828
|
+
{ name: 'title', layout: { positions: { lg: { colSpan: 6 } } } },
|
829
|
+
{ name: 'color', layout: { positions: { lg: { colSpan: 12 } } } },
|
830
|
+
{ name: 'rooms', layout: { positions: { lg: { colSpan: 12 } } } },
|
831
|
+
{ name: 'excludeRooms', layout: { positions: { lg: { colSpan: 12 } } } },
|
832
|
+
{ name: 'includeRooms', layout: { positions: { lg: { colSpan: 12 } } } },
|
833
|
+
],
|
834
|
+
},
|
835
|
+
single: {
|
836
|
+
title: '{{title}}',
|
837
|
+
sections: [{ id: 'section' }],
|
838
|
+
properties: [
|
839
|
+
{ name: 'name', layout: { positions: { lg: { colSpan: 6 } } } },
|
840
|
+
{ name: 'title', layout: { positions: { lg: { colSpan: 6 } } } },
|
841
|
+
],
|
842
|
+
actions: [],
|
843
|
+
},
|
844
|
+
list: {
|
845
|
+
actions: [
|
846
|
+
{
|
847
|
+
title: `t("create", { scope: "common" })`,
|
848
|
+
command: 'create-entity',
|
849
|
+
priority: 'primary',
|
850
|
+
type: 'create',
|
851
|
+
scope: AXPEntityCommandScope.TypeLevel,
|
852
|
+
},
|
853
|
+
{
|
854
|
+
title: 't("deleteItems", { scope: "common" })',
|
855
|
+
command: 'delete-entity',
|
856
|
+
priority: 'primary',
|
857
|
+
type: 'delete',
|
858
|
+
scope: AXPEntityCommandScope.Selected,
|
859
|
+
},
|
860
|
+
{
|
861
|
+
title: 't("detail", { scope: "common" })',
|
862
|
+
command: 'open-entity',
|
863
|
+
priority: 'secondary',
|
864
|
+
type: 'view',
|
865
|
+
scope: AXPEntityCommandScope.Individual,
|
866
|
+
},
|
867
|
+
{
|
868
|
+
title: 't("delete", { scope: "common" })',
|
869
|
+
command: 'delete-entity',
|
870
|
+
priority: 'secondary',
|
871
|
+
type: 'delete',
|
872
|
+
scope: AXPEntityCommandScope.Individual,
|
873
|
+
},
|
874
|
+
],
|
875
|
+
views: [
|
876
|
+
createAllQueryView({
|
877
|
+
columns: ['name', 'title'],
|
878
|
+
sorts: [{ name: 'name', dir: 'asc' }],
|
879
|
+
}),
|
880
|
+
],
|
881
|
+
},
|
882
|
+
},
|
883
|
+
},
|
884
|
+
};
|
885
|
+
return entityDef;
|
886
|
+
}
|
887
|
+
|
653
888
|
class AXMConversationModuleEntityProvider {
|
654
889
|
constructor(injector) {
|
655
890
|
this.injector = injector;
|
@@ -667,6 +902,8 @@ class AXMConversationModuleEntityProvider {
|
|
667
902
|
return roomFactory(this.injector);
|
668
903
|
case 'message':
|
669
904
|
return messageFactory(this.injector);
|
905
|
+
case 'tab':
|
906
|
+
return tabFactory(this.injector);
|
670
907
|
default:
|
671
908
|
return null;
|
672
909
|
}
|
@@ -1465,7 +1702,7 @@ class AXMUserLookupPopup extends AXBasePageComponent {
|
|
1465
1702
|
<ax-button
|
1466
1703
|
text="Accept & Send"
|
1467
1704
|
color="primary"
|
1468
|
-
[disabled]="context()?.lookup?.length > 1 && !context()?.title"
|
1705
|
+
[disabled]="(context()?.lookup?.length > 1 && !context()?.title) || !context()?.lookup?.length"
|
1469
1706
|
(onClick)="handleClose()"
|
1470
1707
|
></ax-button>
|
1471
1708
|
</ax-suffix>
|
@@ -1488,7 +1725,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
1488
1725
|
<ax-button
|
1489
1726
|
text="Accept & Send"
|
1490
1727
|
color="primary"
|
1491
|
-
[disabled]="context()?.lookup?.length > 1 && !context()?.title"
|
1728
|
+
[disabled]="(context()?.lookup?.length > 1 && !context()?.title) || !context()?.lookup?.length"
|
1492
1729
|
(onClick)="handleClose()"
|
1493
1730
|
></ax-button>
|
1494
1731
|
</ax-suffix>
|
@@ -1574,6 +1811,38 @@ const AXMCommentPopupWorkflow = {
|
|
1574
1811
|
},
|
1575
1812
|
};
|
1576
1813
|
|
1814
|
+
function convertChatMessageToNotification(room, message, currentUser) {
|
1815
|
+
const mapToNotificationUser = (user) => {
|
1816
|
+
return {
|
1817
|
+
id: user.id,
|
1818
|
+
name: user.fullName || '',
|
1819
|
+
image: '', // You might want to add an avatar URL here if available
|
1820
|
+
username: user.username || '',
|
1821
|
+
firstName: user.fullName?.split(' ')[0] || '',
|
1822
|
+
lastName: user.fullName?.split(' ')[1] || '',
|
1823
|
+
};
|
1824
|
+
};
|
1825
|
+
return {
|
1826
|
+
channel: 'InApp',
|
1827
|
+
template: {
|
1828
|
+
category: 'Inbox',
|
1829
|
+
prority: 'Notice',
|
1830
|
+
icon: 'fa-light fa-comment',
|
1831
|
+
isPinned: false,
|
1832
|
+
},
|
1833
|
+
title: room.title || 'New Message',
|
1834
|
+
body: message.message.content,
|
1835
|
+
user: mapToNotificationUser(message.author),
|
1836
|
+
content: {
|
1837
|
+
type: 'Notification',
|
1838
|
+
data: {
|
1839
|
+
roomId: room.id,
|
1840
|
+
},
|
1841
|
+
},
|
1842
|
+
readAt: null,
|
1843
|
+
};
|
1844
|
+
}
|
1845
|
+
|
1577
1846
|
//#region ---- Abstract Chat Service ----
|
1578
1847
|
class AXMChatService {
|
1579
1848
|
}
|
@@ -1582,6 +1851,7 @@ class AXMChatServiceImpl {
|
|
1582
1851
|
constructor() {
|
1583
1852
|
this.roomService = inject(AXMRoomService);
|
1584
1853
|
this.messageService = inject(AXMMessageService);
|
1854
|
+
this.tabService = inject(AXMConversationTabService);
|
1585
1855
|
this.sessionService = inject(AXPSessionService);
|
1586
1856
|
this.usersService = inject(AXMUsersEntityService);
|
1587
1857
|
this._messageSent$ = new Subject();
|
@@ -1598,6 +1868,10 @@ class AXMChatServiceImpl {
|
|
1598
1868
|
this.roomSeen$ = this._roomSeen$.asObservable();
|
1599
1869
|
this._messageReacted$ = new Subject();
|
1600
1870
|
this.messageReacted$ = this._messageReacted$.asObservable();
|
1871
|
+
this._tabAdded$ = new Subject();
|
1872
|
+
this.tabAdded$ = this._tabAdded$.asObservable();
|
1873
|
+
this._tabRemoved$ = new Subject();
|
1874
|
+
this.tabRemoved$ = this._tabRemoved$.asObservable();
|
1601
1875
|
this._typingStatus$ = new Subject();
|
1602
1876
|
this.typingStatus$ = this._typingStatus$.asObservable();
|
1603
1877
|
}
|
@@ -1755,6 +2029,88 @@ class AXMChatServiceImpl {
|
|
1755
2029
|
});
|
1756
2030
|
}
|
1757
2031
|
//#endregion
|
2032
|
+
//#region ---- ChatTabService Implementations ----
|
2033
|
+
async createTab(data) {
|
2034
|
+
const tabId = await this.tabService.insertOne(data);
|
2035
|
+
const newTab = await this.getTab(tabId);
|
2036
|
+
this._tabAdded$.next(newTab);
|
2037
|
+
return newTab;
|
2038
|
+
}
|
2039
|
+
async getTab(tabId) {
|
2040
|
+
return this.tabService.getOne(tabId);
|
2041
|
+
}
|
2042
|
+
async listTabs(skip = 0, take = 100) {
|
2043
|
+
return this.tabService.query({ skip, take });
|
2044
|
+
}
|
2045
|
+
async updateTab(tabId, data) {
|
2046
|
+
return this.tabService.updateOne(tabId, data);
|
2047
|
+
}
|
2048
|
+
async deleteTab(tabId) {
|
2049
|
+
try {
|
2050
|
+
await this.tabService.deleteOne(tabId);
|
2051
|
+
this._tabRemoved$.next(tabId);
|
2052
|
+
return true;
|
2053
|
+
}
|
2054
|
+
catch (error) {
|
2055
|
+
console.error(`Error deleting tab ${tabId}:`, error);
|
2056
|
+
return false;
|
2057
|
+
}
|
2058
|
+
}
|
2059
|
+
async addIncludeRoomToTab(tabId, roomId) {
|
2060
|
+
const tab = await this.getTab(tabId);
|
2061
|
+
const room = await this.getRoom(roomId);
|
2062
|
+
if (tab && room) {
|
2063
|
+
const updatedRooms = [...tab.includeRooms, room];
|
2064
|
+
return this.updateTab(tabId, { includeRooms: updatedRooms });
|
2065
|
+
}
|
2066
|
+
else {
|
2067
|
+
throw new Error(`Tab with ID ${tabId} or room with ID ${roomId} not found.`);
|
2068
|
+
}
|
2069
|
+
}
|
2070
|
+
async removeIncludeRoomFromTab(tabId, roomId) {
|
2071
|
+
const tab = await this.getTab(tabId);
|
2072
|
+
const room = await this.getRoom(roomId);
|
2073
|
+
if (tab && room) {
|
2074
|
+
if (tab.includeRooms.some((r) => r.id === roomId)) {
|
2075
|
+
const updatedRooms = tab.includeRooms.filter((r) => r.id !== roomId);
|
2076
|
+
return this.updateTab(tabId, { includeRooms: updatedRooms });
|
2077
|
+
}
|
2078
|
+
else {
|
2079
|
+
throw new Error(`${tabId} tab does not include room with ID ${roomId}.`);
|
2080
|
+
}
|
2081
|
+
}
|
2082
|
+
else {
|
2083
|
+
throw new Error(`Tab with ID ${tabId} or room with ID ${roomId} not found.`);
|
2084
|
+
}
|
2085
|
+
}
|
2086
|
+
async addExcludeRoomToTab(tabId, roomId) {
|
2087
|
+
const tab = await this.getTab(tabId);
|
2088
|
+
const room = await this.getRoom(roomId);
|
2089
|
+
if (tab && room) {
|
2090
|
+
const updatedRooms = [...tab.excludeRooms, room];
|
2091
|
+
return this.updateTab(tabId, { excludeRooms: updatedRooms });
|
2092
|
+
}
|
2093
|
+
else {
|
2094
|
+
throw new Error(`Tab with ID ${tabId} or room with ID ${roomId} not found.`);
|
2095
|
+
}
|
2096
|
+
}
|
2097
|
+
async removeExcludeRoomFromTab(tabId, roomId) {
|
2098
|
+
const tab = await this.getTab(tabId);
|
2099
|
+
const room = await this.getRoom(roomId);
|
2100
|
+
if (tab && room) {
|
2101
|
+
if (tab.excludeRooms.some((r) => r.id === roomId)) {
|
2102
|
+
const updatedRooms = tab.excludeRooms.filter((r) => r.id !== roomId);
|
2103
|
+
return this.updateTab(tabId, { excludeRooms: updatedRooms });
|
2104
|
+
}
|
2105
|
+
else {
|
2106
|
+
throw new Error(`${tabId} tab does not exclude room with ID ${roomId}.`);
|
2107
|
+
}
|
2108
|
+
}
|
2109
|
+
else {
|
2110
|
+
throw new Error(`Tab with ID ${tabId} or room with ID ${roomId} not found.`);
|
2111
|
+
}
|
2112
|
+
}
|
2113
|
+
//#endregion
|
1758
2114
|
//#region ---- ChatMessageService Implementations ----
|
1759
2115
|
async sendMessage(roomId, content, contentType = 'text', replyId, userId) {
|
1760
2116
|
const author = userId ? await this.getUserInfo(userId) : this.getCurrentUser();
|
@@ -2034,47 +2390,57 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2034
2390
|
this.dialogService = inject(AXDialogService);
|
2035
2391
|
this.router = inject(Router);
|
2036
2392
|
this.unsubscribe = inject(AXUnsubscriber);
|
2393
|
+
this.osNotificationService = inject(AXMOsNotificationService);
|
2394
|
+
this.notificationConnectorService = inject(AXMNotificationConnectorService);
|
2037
2395
|
// View Children
|
2038
2396
|
this.tab = viewChild('tab', ...(ngDevMode ? [{ debugName: "tab" }] : []));
|
2039
2397
|
this.container = viewChild('container', ...(ngDevMode ? [{ debugName: "container" }] : []));
|
2040
2398
|
// State signals
|
2041
2399
|
this.rooms = signal([], ...(ngDevMode ? [{ debugName: "rooms" }] : []));
|
2042
2400
|
this.allRooms = signal([], ...(ngDevMode ? [{ debugName: "allRooms" }] : []));
|
2401
|
+
this.tabs = signal([], ...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
2043
2402
|
this.selectedRoom = signal(null, ...(ngDevMode ? [{ debugName: "selectedRoom" }] : []));
|
2044
2403
|
this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
2045
2404
|
this.typingStatus = signal({}, ...(ngDevMode ? [{ debugName: "typingStatus" }] : []));
|
2046
2405
|
this.error = signal(null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
2047
|
-
this.
|
2406
|
+
this.activeTabIndex = signal(0, ...(ngDevMode ? [{ debugName: "activeTabIndex" }] : []));
|
2048
2407
|
this.isSearching = signal(false, ...(ngDevMode ? [{ debugName: "isSearching" }] : []));
|
2049
2408
|
this.searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
|
2050
2409
|
this.showSearch = signal(true, ...(ngDevMode ? [{ debugName: "showSearch" }] : []));
|
2051
2410
|
this.placeholder = signal('Search chats...', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
2052
2411
|
// Computed signals
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
// const lastMessage = room.lastMessage?.message?.content || '';
|
2062
|
-
// return roomName.toLowerCase().includes(searchText) || lastMessage.toLowerCase().includes(searchText);
|
2063
|
-
// });
|
2064
|
-
// }
|
2065
|
-
// // Apply tab filter
|
2066
|
-
// if (this.activeTab() === 1) {
|
2067
|
-
// return chatRooms.filter((room) => room.unreadCount > 0);
|
2068
|
-
// }
|
2069
|
-
// return chatRooms;
|
2070
|
-
// });
|
2412
|
+
this.activeTab = computed(() => {
|
2413
|
+
const tabs = this.tabs();
|
2414
|
+
const index = this.activeTabIndex();
|
2415
|
+
if (tabs.length > 0 && index >= 0 && index < tabs.length) {
|
2416
|
+
return tabs[index];
|
2417
|
+
}
|
2418
|
+
return undefined;
|
2419
|
+
}, ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
|
2071
2420
|
this.filteredRooms = signal([], ...(ngDevMode ? [{ debugName: "filteredRooms" }] : []));
|
2072
|
-
this.searchEffect = effect(
|
2073
|
-
|
2074
|
-
//
|
2421
|
+
this.searchEffect = effect(() => {
|
2422
|
+
const allRooms = this.allRooms();
|
2423
|
+
let chatRooms = [...allRooms]; // Start with all rooms
|
2424
|
+
// Tab filter
|
2425
|
+
const activeTab = this.activeTab();
|
2426
|
+
if (activeTab) {
|
2427
|
+
if (activeTab.name === 'unread') {
|
2428
|
+
// Special local state for unread
|
2429
|
+
chatRooms = allRooms.filter((room) => room.unreadCount > 0);
|
2430
|
+
}
|
2431
|
+
else if (activeTab.name === 'all') {
|
2432
|
+
// Local state for all
|
2433
|
+
chatRooms = allRooms;
|
2434
|
+
}
|
2435
|
+
else {
|
2436
|
+
// For other tabs defined by the service
|
2437
|
+
const includedIds = new Set(activeTab.includeRooms.map((r) => r.id));
|
2438
|
+
chatRooms = allRooms.filter((room) => includedIds.has(room.id));
|
2439
|
+
}
|
2440
|
+
}
|
2441
|
+
// Search filter (applies on top of tab filter)
|
2075
2442
|
const query = (this.searchQuery() || '').toLowerCase();
|
2076
2443
|
if (query) {
|
2077
|
-
// Perform async enrichment for names
|
2078
2444
|
const filtered = [];
|
2079
2445
|
for (const room of chatRooms) {
|
2080
2446
|
try {
|
@@ -2100,40 +2466,25 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2100
2466
|
}
|
2101
2467
|
chatRooms = filtered;
|
2102
2468
|
}
|
2103
|
-
// Tab filter
|
2104
|
-
if (this.activeTab() === 1) {
|
2105
|
-
chatRooms = chatRooms.filter((room) => room.unreadCount > 0);
|
2106
|
-
}
|
2107
2469
|
this.filteredRooms.set(chatRooms);
|
2108
2470
|
}, ...(ngDevMode ? [{ debugName: "searchEffect" }] : []));
|
2109
2471
|
this.unreadCount = computed(() => this.allRooms().filter((i) => i.unreadCount > 0).length, ...(ngDevMode ? [{ debugName: "unreadCount" }] : []));
|
2110
2472
|
this.allCount = computed(() => this.allRooms().length, ...(ngDevMode ? [{ debugName: "allCount" }] : []));
|
2111
2473
|
this.hasUnread = computed(() => this.allRooms().filter((i) => i.unreadCount > 0).length > 0, ...(ngDevMode ? [{ debugName: "hasUnread" }] : []));
|
2112
2474
|
this.totalCount = computed(() => this.allRooms().length || 0, ...(ngDevMode ? [{ debugName: "totalCount" }] : []));
|
2113
|
-
//switch tab to unread if there is no unread
|
2114
|
-
this.autoSwitchTab = effect(() => {
|
2115
|
-
if (this.activeTab() === 1 && !this.hasUnread()) {
|
2116
|
-
this.activeTab.set(0);
|
2117
|
-
}
|
2118
|
-
}, ...(ngDevMode ? [{ debugName: "autoSwitchTab" }] : []));
|
2119
|
-
this.af = afterNextRender(() => {
|
2120
|
-
const tabComponent = this.tab();
|
2121
|
-
if (tabComponent) {
|
2122
|
-
tabComponent.onActiveTabChanged.subscribe((i) => {
|
2123
|
-
this.activeTab.set(i.index);
|
2124
|
-
});
|
2125
|
-
}
|
2126
|
-
//(window as any).a = this.container()?.startSideDrawer();
|
2127
|
-
});
|
2128
2475
|
}
|
2129
|
-
|
2130
|
-
this.
|
2476
|
+
async deleteTab(tab) {
|
2477
|
+
const result = await this.dialogService.confirm('Delete Tab', `Are you sure you want to delete the "${tab.title}" tab?`);
|
2478
|
+
if (result) {
|
2479
|
+
await this.chatService.deleteTab(tab.id);
|
2480
|
+
await this.loadTabs();
|
2481
|
+
}
|
2131
2482
|
}
|
2132
2483
|
async ngOnInit() {
|
2133
2484
|
super.ngOnInit();
|
2134
2485
|
this.isLoading.set(true);
|
2135
2486
|
this.error.set(null);
|
2136
|
-
await this.loadChats();
|
2487
|
+
await Promise.all([this.loadChats(), this.loadTabs(), this.osNotificationService.requestPermission()]);
|
2137
2488
|
this.isLoading.set(false);
|
2138
2489
|
//
|
2139
2490
|
this.router.events
|
@@ -2191,15 +2542,38 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2191
2542
|
const roomIndex = rooms.findIndex((r) => r.id === message.roomId);
|
2192
2543
|
if (roomIndex > -1) {
|
2193
2544
|
const roomToUpdate = rooms[roomIndex];
|
2545
|
+
const isCurrentUser = message.author.id === this.sessionService.user?.id;
|
2194
2546
|
const updatedRoom = {
|
2195
2547
|
...roomToUpdate,
|
2196
2548
|
lastMessage: message,
|
2197
|
-
unreadCount:
|
2198
|
-
? (roomToUpdate.unreadCount || 0) + 1
|
2199
|
-
: roomToUpdate.unreadCount,
|
2549
|
+
unreadCount: !isCurrentUser ? (roomToUpdate.unreadCount || 0) + 1 : roomToUpdate.unreadCount,
|
2200
2550
|
};
|
2201
2551
|
const newRooms = [updatedRoom, ...rooms.filter((r) => r.id !== message.roomId)];
|
2202
2552
|
this.allRooms.set(newRooms);
|
2553
|
+
//
|
2554
|
+
if (!isCurrentUser && this.selectedRoom()?.id !== message.roomId) {
|
2555
|
+
const notification = convertChatMessageToNotification(roomToUpdate, message, this.sessionService.user);
|
2556
|
+
this.notificationConnectorService.create({
|
2557
|
+
...notification,
|
2558
|
+
id: message.id,
|
2559
|
+
entityName: 'notifications',
|
2560
|
+
createAt: new Date(),
|
2561
|
+
}, {
|
2562
|
+
onClick: () => {
|
2563
|
+
this.router.navigate([roomToUpdate.id], { relativeTo: this.activatedRoute });
|
2564
|
+
},
|
2565
|
+
activeWindow: true,
|
2566
|
+
});
|
2567
|
+
// this.osNotificationService.show(notification.title || 'Notification', {
|
2568
|
+
// body: notification.body || 'No body',
|
2569
|
+
// icon: notification.user.image || '',
|
2570
|
+
// onClick: () => {
|
2571
|
+
// this.router.navigate([roomToUpdate.id], { relativeTo: this.activatedRoute });
|
2572
|
+
// },
|
2573
|
+
// activeWindow: true,
|
2574
|
+
// });
|
2575
|
+
}
|
2576
|
+
//
|
2203
2577
|
}
|
2204
2578
|
else {
|
2205
2579
|
// New room, fetch it and add it to the top.
|
@@ -2291,8 +2665,8 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2291
2665
|
async execute(command) {
|
2292
2666
|
switch (command.name) {
|
2293
2667
|
case 'remove-chat':
|
2294
|
-
const
|
2295
|
-
if (result) {
|
2668
|
+
const response = await this.dialogService.confirm('Remove Chat', 'Are you sure you want to remove this chat?');
|
2669
|
+
if (response.result) {
|
2296
2670
|
await this.chatService.deleteRoom(this.selectedRoom()?.id);
|
2297
2671
|
this.router.navigate(['./'], { relativeTo: this.activatedRoute });
|
2298
2672
|
}
|
@@ -2313,6 +2687,43 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2313
2687
|
}
|
2314
2688
|
}
|
2315
2689
|
// Methods
|
2690
|
+
getRoomCountForTab(tab) {
|
2691
|
+
const allRooms = this.allRooms();
|
2692
|
+
if (tab.name === 'all') {
|
2693
|
+
return allRooms.length;
|
2694
|
+
}
|
2695
|
+
if (tab.name === 'unread') {
|
2696
|
+
return allRooms.filter((room) => room.unreadCount > 0).length;
|
2697
|
+
}
|
2698
|
+
const includedIds = new Set(tab.includeRooms.map((r) => r.id));
|
2699
|
+
return allRooms.filter((room) => includedIds.has(room.id)).length;
|
2700
|
+
}
|
2701
|
+
async loadTabs() {
|
2702
|
+
const localTabs = [
|
2703
|
+
{
|
2704
|
+
id: 'all-local',
|
2705
|
+
name: 'all',
|
2706
|
+
title: 'All',
|
2707
|
+
excludeRooms: [],
|
2708
|
+
includeRooms: [],
|
2709
|
+
},
|
2710
|
+
{
|
2711
|
+
id: 'unread-local',
|
2712
|
+
name: 'unread',
|
2713
|
+
title: 'Unread',
|
2714
|
+
excludeRooms: [],
|
2715
|
+
includeRooms: [],
|
2716
|
+
},
|
2717
|
+
];
|
2718
|
+
try {
|
2719
|
+
const result = await this.chatService.listTabs();
|
2720
|
+
this.tabs.set([...localTabs, ...result.items]);
|
2721
|
+
}
|
2722
|
+
catch (error) {
|
2723
|
+
console.error('Failed to load tabs:', error);
|
2724
|
+
this.tabs.set(localTabs);
|
2725
|
+
}
|
2726
|
+
}
|
2316
2727
|
async loadChats() {
|
2317
2728
|
try {
|
2318
2729
|
// Use the updated service method to get rooms with last messages
|
@@ -2380,6 +2791,7 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2380
2791
|
async onNewConversation() {
|
2381
2792
|
const popupConfig = {
|
2382
2793
|
header: true,
|
2794
|
+
title: 'New Conversation',
|
2383
2795
|
size: 'sm',
|
2384
2796
|
draggable: true,
|
2385
2797
|
hasBackdrop: true,
|
@@ -2399,7 +2811,6 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2399
2811
|
this.toastService.danger('Failed to create room');
|
2400
2812
|
}
|
2401
2813
|
}
|
2402
|
-
ngOnDestroy() { }
|
2403
2814
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXMChatComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
2404
2815
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: AXMChatComponent, isStandalone: true, selector: "axm-chat", host: { listeners: { "document:keydown.escape": "onKeydownHandler($event)" } }, providers: [
|
2405
2816
|
{
|
@@ -2407,7 +2818,7 @@ class AXMChatComponent extends AXPPageLayoutBaseComponent {
|
|
2407
2818
|
useExisting: AXMChatComponent,
|
2408
2819
|
},
|
2409
2820
|
AXUnsubscriber,
|
2410
|
-
], viewQueries: [{ propertyName: "tab", first: true, predicate: ["tab"], descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout #container>\n <axp-layout-start-side class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header>\n <axp-layout-title>{{ 'module-name' | translate: { scope: 'conversation' } | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content class=\"ax-flex ax-flex-col ax-min-h-0 ax-max-w-80\">\n @if (!layoutService.isMobileDevice()) {\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content style=\"height: calc(100vh - 22rem)\">\n @if (selectedRoom()) {\n <router-outlet></router-outlet>\n } @else if (layoutService.isMobileDevice()) {\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-page-content>\n</axp-page-layout>\n
|
2821
|
+
], viewQueries: [{ propertyName: "tab", first: true, predicate: ["tab"], descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: ["container"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout #container>\n <axp-layout-start-side class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header>\n <axp-layout-title>{{ 'module-name' | translate: { scope: 'conversation' } | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content class=\"ax-flex ax-flex-col ax-min-h-0 ax-max-w-80\">\n @if (!layoutService.isMobileDevice()) {\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content style=\"height: calc(100vh - 22rem)\">\n @if (selectedRoom()) {\n <router-outlet></router-outlet>\n } @else if (layoutService.isMobileDevice()) {\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full ax-mb-2\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-page-content>\n</axp-page-layout>\n<ng-template #template>\n <!-- Tabs -->\n <div [class]=\"!layoutService.isMobileDevice() ? 'ax-px-4': ''\">\n <ax-tabs\n #tab\n class=\"ax-text-neutral-400\"\n [look]=\"'with-line'\"\n [location]=\"'bottom'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"activeTabIndex.set($event.index)\"\n >\n @for (tab of tabs(); track tab.id; let i = $index) {\n <ax-tab-item [text]=\"tab.title\" [active]=\"activeTabIndex() === i\">\n <ax-suffix>\n <ax-badge\n [text]=\"getRoomCountForTab(tab).toString()\"\n [color]=\"activeTabIndex() === i ? 'primary' : 'secondary'\"\n class=\"ax-min-w-[1.5rem] ax-justify-center\"\n ></ax-badge>\n </ax-suffix>\n </ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n <!-- Chat List Content -->\n <div\n class=\"ax-flex-1 ax-overflow-hidden ax-flex ax-flex-col ax-justify-between ax-min-w-80\"\n [class.ax-border-t]=\"tabs().length > 0\"\n >\n <!-- Loading State -->\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-space-y-4\">\n @for (_ of [1, 2, 3, 4, 5, 6]; track $index) {\n <div class=\"ax-flex ax-items-center ax-space-x-3\">\n <ax-skeleton [animated]=\"true\" class=\"ax-w-12 ax-h-12 ax-rounded-full\"></ax-skeleton>\n <div class=\"ax-flex-1 ax-space-y-2\">\n <ax-skeleton [animated]=\"true\" class=\"ax-w-3/4 ax-h-4 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"ax-w-1/2 ax-h-3 ax-rounded-md\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n } @else if (error()) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4 ax-text-center\">\n <ax-icon class=\"ax-text-danger ax-text-5xl ax-mb-3\">\n <i class=\"fa-light fa-circle-exclamation\"></i>\n </ax-icon>\n <p class=\"ax-font-semibold ax-text-lg\">\n {{ 'chat-error' | translate: { scope: 'conversation' } | async }}\n </p>\n <p class=\"ax-font-semibold ax-text-lg\">\n {{ 'chat-try-again' | translate: { scope: 'conversation' } | async }}\n </p>\n <p class=\"ax-text-secondary ax-mb-4\">{{ error() }}</p>\n <ax-button\n [text]=\"'try-again' | translate: { scope: 'conversation' } | async\"\n color=\"primary\"\n (onClick)=\"refreshChat()\"\n ></ax-button>\n </div>\n } @else {\n <div class=\"ax-flex-1 ax-overflow-y-auto\">\n @for (i of filteredRooms(); track i.id) {\n <axm-chat-item\n [data]=\"i\"\n [typing]=\"$any(typingStatus()[i.id])\"\n [lastMessageReaction]=\"i.lastMessage?.reactions?.[0]?.type ?? null\"\n [attr.data-id]=\"i.id\"\n (click)=\"openChat(i.id)\"\n [class.ax-bg-dark]=\"selectedRoom()?.id === i.id\"\n class=\"ax-transition-all ax-duration-100 hover:ax-bg-surface\"\n [@fadeIn]\n tabindex=\"0\"\n (keydown.enter)=\"openChat(i.id)\"\n role=\"button\"\n ></axm-chat-item>\n } @empty {\n <div class=\"ax-p-4 ax-font-medium ax-text-center ax-text-secondary\">\n @if (isSearching()) {\n No chats found matching your search.\n } @else {\n There are no conversations in this tab.\n }\n </div>\n }\n </div>\n }\n\n <!-- Footer Content -->\n @if (!layoutService.isMobileDevice()) {\n <div class=\"ax-border-t ax-border-divider ax-bg-lightest ax-p-4\">\n <ax-button class=\"ax-w-full\" color=\"primary\" text=\"New Conversation\" (onClick)=\"onNewConversation()\">\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-plus\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n } @else {\n <ax-button\n class=\"ax-fixed ax-bottom-16 ax-right-8 !ax-rounded-full !ax-w-14 !ax-h-14 ax-shadow-lg\"\n color=\"primary\"\n (onClick)=\"onNewConversation()\"\n >\n <ax-icon class=\"ax-text-2xl\">\n <i class=\"fa-solid fa-plus\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "component", type: AXMChatItemComponent, selector: "axm-chat-item", inputs: ["data", "typing", "lastMessageReaction"], outputs: ["pressChatItem"] }, { kind: "ngmodule", type:
|
2411
2822
|
// Common Modules
|
2412
2823
|
CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2$3.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type:
|
2413
2824
|
// Acorex Core Modules
|
@@ -2473,7 +2884,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
2473
2884
|
animate('300ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })),
|
2474
2885
|
]),
|
2475
2886
|
]),
|
2476
|
-
], template: "<axp-page-layout #container>\n <axp-layout-start-side class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header>\n <axp-layout-title>{{ 'module-name' | translate: { scope: 'conversation' } | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content class=\"ax-flex ax-flex-col ax-min-h-0 ax-max-w-80\">\n @if (!layoutService.isMobileDevice()) {\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content style=\"height: calc(100vh - 22rem)\">\n @if (selectedRoom()) {\n <router-outlet></router-outlet>\n } @else if (layoutService.isMobileDevice()) {\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-page-content>\n</axp-page-layout>\n
|
2887
|
+
], template: "<axp-page-layout #container>\n <axp-layout-start-side class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header>\n <axp-layout-title>{{ 'module-name' | translate: { scope: 'conversation' } | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content class=\"ax-flex ax-flex-col ax-min-h-0 ax-max-w-80\">\n @if (!layoutService.isMobileDevice()) {\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content style=\"height: calc(100vh - 22rem)\">\n @if (selectedRoom()) {\n <router-outlet></router-outlet>\n } @else if (layoutService.isMobileDevice()) {\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [value]=\"searchQuery()\"\n (onValueChanged)=\"onSearch($event.value)\"\n class=\"ax-w-full ax-mb-2\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n <ng-container [ngTemplateOutlet]=\"template\"></ng-container>\n }\n </axp-page-content>\n</axp-page-layout>\n<ng-template #template>\n <!-- Tabs -->\n <div [class]=\"!layoutService.isMobileDevice() ? 'ax-px-4': ''\">\n <ax-tabs\n #tab\n class=\"ax-text-neutral-400\"\n [look]=\"'with-line'\"\n [location]=\"'bottom'\"\n [fitParent]=\"true\"\n (onActiveTabChanged)=\"activeTabIndex.set($event.index)\"\n >\n @for (tab of tabs(); track tab.id; let i = $index) {\n <ax-tab-item [text]=\"tab.title\" [active]=\"activeTabIndex() === i\">\n <ax-suffix>\n <ax-badge\n [text]=\"getRoomCountForTab(tab).toString()\"\n [color]=\"activeTabIndex() === i ? 'primary' : 'secondary'\"\n class=\"ax-min-w-[1.5rem] ax-justify-center\"\n ></ax-badge>\n </ax-suffix>\n </ax-tab-item>\n }\n </ax-tabs>\n </div>\n\n <!-- Chat List Content -->\n <div\n class=\"ax-flex-1 ax-overflow-hidden ax-flex ax-flex-col ax-justify-between ax-min-w-80\"\n [class.ax-border-t]=\"tabs().length > 0\"\n >\n <!-- Loading State -->\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-space-y-4\">\n @for (_ of [1, 2, 3, 4, 5, 6]; track $index) {\n <div class=\"ax-flex ax-items-center ax-space-x-3\">\n <ax-skeleton [animated]=\"true\" class=\"ax-w-12 ax-h-12 ax-rounded-full\"></ax-skeleton>\n <div class=\"ax-flex-1 ax-space-y-2\">\n <ax-skeleton [animated]=\"true\" class=\"ax-w-3/4 ax-h-4 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"ax-w-1/2 ax-h-3 ax-rounded-md\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n } @else if (error()) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4 ax-text-center\">\n <ax-icon class=\"ax-text-danger ax-text-5xl ax-mb-3\">\n <i class=\"fa-light fa-circle-exclamation\"></i>\n </ax-icon>\n <p class=\"ax-font-semibold ax-text-lg\">\n {{ 'chat-error' | translate: { scope: 'conversation' } | async }}\n </p>\n <p class=\"ax-font-semibold ax-text-lg\">\n {{ 'chat-try-again' | translate: { scope: 'conversation' } | async }}\n </p>\n <p class=\"ax-text-secondary ax-mb-4\">{{ error() }}</p>\n <ax-button\n [text]=\"'try-again' | translate: { scope: 'conversation' } | async\"\n color=\"primary\"\n (onClick)=\"refreshChat()\"\n ></ax-button>\n </div>\n } @else {\n <div class=\"ax-flex-1 ax-overflow-y-auto\">\n @for (i of filteredRooms(); track i.id) {\n <axm-chat-item\n [data]=\"i\"\n [typing]=\"$any(typingStatus()[i.id])\"\n [lastMessageReaction]=\"i.lastMessage?.reactions?.[0]?.type ?? null\"\n [attr.data-id]=\"i.id\"\n (click)=\"openChat(i.id)\"\n [class.ax-bg-dark]=\"selectedRoom()?.id === i.id\"\n class=\"ax-transition-all ax-duration-100 hover:ax-bg-surface\"\n [@fadeIn]\n tabindex=\"0\"\n (keydown.enter)=\"openChat(i.id)\"\n role=\"button\"\n ></axm-chat-item>\n } @empty {\n <div class=\"ax-p-4 ax-font-medium ax-text-center ax-text-secondary\">\n @if (isSearching()) {\n No chats found matching your search.\n } @else {\n There are no conversations in this tab.\n }\n </div>\n }\n </div>\n }\n\n <!-- Footer Content -->\n @if (!layoutService.isMobileDevice()) {\n <div class=\"ax-border-t ax-border-divider ax-bg-lightest ax-p-4\">\n <ax-button class=\"ax-w-full\" color=\"primary\" text=\"New Conversation\" (onClick)=\"onNewConversation()\">\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-plus\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n } @else {\n <ax-button\n class=\"ax-fixed ax-bottom-16 ax-right-8 !ax-rounded-full !ax-w-14 !ax-h-14 ax-shadow-lg\"\n color=\"primary\"\n (onClick)=\"onNewConversation()\"\n >\n <ax-icon class=\"ax-text-2xl\">\n <i class=\"fa-solid fa-plus\"></i>\n </ax-icon>\n </ax-button>\n }\n </div>\n</ng-template>\n" }]
|
2477
2888
|
}], propDecorators: { onKeydownHandler: [{
|
2478
2889
|
type: HostListener,
|
2479
2890
|
args: ['document:keydown.escape', ['$event']]
|
@@ -2782,6 +3193,15 @@ class AXMChatPreviewComponent {
|
|
2782
3193
|
value: '',
|
2783
3194
|
}, ...(ngDevMode ? [{ debugName: "options" }] : []));
|
2784
3195
|
this.roomId = '';
|
3196
|
+
//GO TO LAST MESSAGE EFFECT.
|
3197
|
+
this.#af = afterNextRender(() => {
|
3198
|
+
setTimeout(() => {
|
3199
|
+
const div = document.querySelector('ax-conversation-view > div');
|
3200
|
+
if (div) {
|
3201
|
+
div.scrollTo({ top: div.scrollHeight, behavior: 'smooth' });
|
3202
|
+
}
|
3203
|
+
}, 500);
|
3204
|
+
});
|
2785
3205
|
}
|
2786
3206
|
setHeight(height) {
|
2787
3207
|
this.height.set(height);
|
@@ -2813,6 +3233,8 @@ class AXMChatPreviewComponent {
|
|
2813
3233
|
// }
|
2814
3234
|
// });
|
2815
3235
|
}
|
3236
|
+
//GO TO LAST MESSAGE EFFECT.
|
3237
|
+
#af;
|
2816
3238
|
ngOnDestroy() {
|
2817
3239
|
this.typingSubscription?.unsubscribe();
|
2818
3240
|
}
|
@@ -3070,6 +3492,10 @@ class AXMConversationModule {
|
|
3070
3492
|
provide: AXMRoomService,
|
3071
3493
|
useClass: AXMRoomServiceImpl,
|
3072
3494
|
},
|
3495
|
+
{
|
3496
|
+
provide: AXMConversationTabService,
|
3497
|
+
useClass: AXMConversationTabServiceImpl,
|
3498
|
+
},
|
3073
3499
|
// Chat and Comment Services
|
3074
3500
|
{
|
3075
3501
|
provide: AXMChatService,
|
@@ -3149,6 +3575,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
3149
3575
|
provide: AXMRoomService,
|
3150
3576
|
useClass: AXMRoomServiceImpl,
|
3151
3577
|
},
|
3578
|
+
{
|
3579
|
+
provide: AXMConversationTabService,
|
3580
|
+
useClass: AXMConversationTabServiceImpl,
|
3581
|
+
},
|
3152
3582
|
// Chat and Comment Services
|
3153
3583
|
{
|
3154
3584
|
provide: AXMChatService,
|
@@ -3191,5 +3621,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
|
|
3191
3621
|
* Generated bundle index. Do not edit.
|
3192
3622
|
*/
|
3193
3623
|
|
3194
|
-
export { AXMChatComponent, AXMChatItemComponent, AXMChatPreviewComponent, AXMChatService, AXMChatServiceImpl, AXMCommentComponent, AXMCommentPopupComponent, AXMCommentPopupStartAction, AXMCommentPopupWorkflow, AXMCommentService, AXMCommentServiceImpl, AXMCommentWidgetViewComponent, AXMConversationModule, AXMMessageService, AXMMessageServiceImpl, AXMRoomService, AXMRoomServiceImpl, AXMUserLookupPopup, AXPCommentWidget, RootConfig, messageFactory, roomFactory };
|
3624
|
+
export { AXMChatComponent, AXMChatItemComponent, AXMChatPreviewComponent, AXMChatService, AXMChatServiceImpl, AXMCommentComponent, AXMCommentPopupComponent, AXMCommentPopupStartAction, AXMCommentPopupWorkflow, AXMCommentService, AXMCommentServiceImpl, AXMCommentWidgetViewComponent, AXMConversationModule, AXMConversationTabService, AXMConversationTabServiceImpl, AXMMessageService, AXMMessageServiceImpl, AXMRoomService, AXMRoomServiceImpl, AXMUserLookupPopup, AXPCommentWidget, RootConfig, messageFactory, roomFactory, tabFactory };
|
3195
3625
|
//# sourceMappingURL=acorex-modules-conversation.mjs.map
|