@acorex/modules 19.4.14 → 19.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/assets/images/weather/cloudy-day-1.svg +175 -0
  2. package/assets/images/weather/cloudy-day-2.svg +176 -0
  3. package/assets/images/weather/cloudy-day-3.svg +175 -0
  4. package/assets/images/weather/cloudy-night-1.svg +198 -0
  5. package/assets/images/weather/cloudy-night-2.svg +198 -0
  6. package/assets/images/weather/cloudy-night-3.svg +198 -0
  7. package/assets/images/weather/cloudy.svg +500 -0
  8. package/assets/images/weather/day.svg +521 -0
  9. package/assets/images/weather/night.svg +503 -0
  10. package/assets/images/weather/rainy-1.svg +157 -0
  11. package/assets/images/weather/rainy-2.svg +133 -0
  12. package/assets/images/weather/rainy-3.svg +157 -0
  13. package/assets/images/weather/rainy-4.svg +66 -0
  14. package/assets/images/weather/rainy-5.svg +90 -0
  15. package/assets/images/weather/rainy-6.svg +91 -0
  16. package/assets/images/weather/rainy-7.svg +91 -0
  17. package/assets/images/weather/snowy-1.svg +230 -0
  18. package/assets/images/weather/snowy-2.svg +237 -0
  19. package/assets/images/weather/snowy-3.svg +268 -0
  20. package/assets/images/weather/snowy-4.svg +94 -0
  21. package/assets/images/weather/snowy-5.svg +166 -0
  22. package/assets/images/weather/snowy-6.svg +225 -0
  23. package/assets/images/weather/thunder.svg +268 -0
  24. package/assets/images/weather/weather-sprite.svg +1245 -0
  25. package/assets/images/weather/weather.svg +1245 -0
  26. package/assets/images/weather/weather_sagittarius.svg +9 -0
  27. package/assets/images/weather/weather_sunset.svg +14 -0
  28. package/conversation/lib/features/chat/components/chat-preview/chat-preview.component.d.ts +0 -1
  29. package/conversation/lib/features/index.d.ts +1 -0
  30. package/conversation/lib/features/widget/share/comment/comment-widget-view.component.d.ts +66 -0
  31. package/conversation/lib/features/widget/share/comment/comment-widget.config.d.ts +2 -0
  32. package/conversation/lib/features/widget/share/comment/index.d.ts +2 -0
  33. package/dashboard-management/lib/features/home-dashboard/dashboard-popups/index.d.ts +3 -0
  34. package/dashboard-management/lib/features/home-dashboard/index.d.ts +3 -0
  35. package/dashboard-management/lib/features/home-dashboard/setrting.keys.d.ts +3 -0
  36. package/dashboard-management/lib/features/home-dashboard/widget-wrapper/index.d.ts +1 -0
  37. package/dashboard-management/lib/features/shared/widgets/analog-clock/analog-clock-widget-view.component.d.ts +9 -0
  38. package/dashboard-management/lib/features/shared/widgets/analog-clock/analog-clock-widget.config.d.ts +7 -0
  39. package/dashboard-management/lib/features/shared/widgets/analog-clock/analog-clock.component.d.ts +28 -0
  40. package/dashboard-management/lib/features/shared/widgets/analog-clock/index.d.ts +3 -0
  41. package/dashboard-management/lib/features/shared/widgets/index.d.ts +1 -0
  42. package/dashboard-management/lib/features/shared/widgets/weather/advanced-weather/advanced-weather.component.d.ts +32 -0
  43. package/dashboard-management/lib/features/shared/widgets/weather/advanced-weather/advanced-weather.config.d.ts +14 -0
  44. package/dashboard-management/lib/features/shared/widgets/weather/advanced-weather/index.d.ts +2 -0
  45. package/dashboard-management/lib/features/shared/widgets/weather/index.d.ts +2 -0
  46. package/dashboard-management/lib/features/shared/widgets/weather/minimal-weather/index.d.ts +2 -0
  47. package/dashboard-management/lib/features/shared/widgets/weather/minimal-weather/minimal-weather.component.d.ts +22 -0
  48. package/dashboard-management/lib/features/shared/widgets/weather/minimal-weather/minimal-weather.config.d.ts +14 -0
  49. package/dashboard-management/lib/features/shared/widgets/weather/weather-services/weather-api.abstract.d.ts +19 -0
  50. package/dashboard-management/lib/features/shared/widgets/weather/weather-widget.component.d.ts +5 -5
  51. package/fesm2022/{acorex-modules-application-management-module-designer.component-BJp8imYd.mjs → acorex-modules-application-management-module-designer.component-ZKzHxJ0D.mjs} +2 -2
  52. package/fesm2022/{acorex-modules-application-management-module-designer.component-BJp8imYd.mjs.map → acorex-modules-application-management-module-designer.component-ZKzHxJ0D.mjs.map} +1 -1
  53. package/fesm2022/acorex-modules-application-management.mjs +1 -1
  54. package/fesm2022/acorex-modules-conversation.mjs +476 -15
  55. package/fesm2022/acorex-modules-conversation.mjs.map +1 -1
  56. package/fesm2022/acorex-modules-dashboard-management.mjs +1224 -30
  57. package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
  58. package/fesm2022/acorex-modules-notification-management.mjs +7 -7
  59. package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
  60. package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-CzMi7CBH.mjs → acorex-modules-platform-management-acorex-modules-platform-management-CGGoHpYi.mjs} +119 -27
  61. package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-CGGoHpYi.mjs.map +1 -0
  62. package/fesm2022/{acorex-modules-platform-management-list-version.component-DfbMc2hn.mjs → acorex-modules-platform-management-list-version.component-CGxYFnd9.mjs} +2 -2
  63. package/fesm2022/{acorex-modules-platform-management-list-version.component-DfbMc2hn.mjs.map → acorex-modules-platform-management-list-version.component-CGxYFnd9.mjs.map} +1 -1
  64. package/fesm2022/{acorex-modules-platform-management-settings.provider-B-19OJn0.mjs → acorex-modules-platform-management-settings.provider-CHAI3QHV.mjs} +2 -2
  65. package/fesm2022/{acorex-modules-platform-management-settings.provider-B-19OJn0.mjs.map → acorex-modules-platform-management-settings.provider-CHAI3QHV.mjs.map} +1 -1
  66. package/fesm2022/acorex-modules-platform-management.mjs +1 -1
  67. package/fesm2022/acorex-modules-project-management.mjs +95 -21
  68. package/fesm2022/acorex-modules-project-management.mjs.map +1 -1
  69. package/fesm2022/{acorex-modules-security-management-permissions-editor.component-Ccx0_9L_.mjs → acorex-modules-security-management-permissions-editor.component-B2OIvMs7.mjs} +2 -2
  70. package/fesm2022/{acorex-modules-security-management-permissions-editor.component-Ccx0_9L_.mjs.map → acorex-modules-security-management-permissions-editor.component-B2OIvMs7.mjs.map} +1 -1
  71. package/fesm2022/acorex-modules-security-management.mjs +1 -1
  72. package/package.json +1 -1
  73. package/platform-management/lib/features/common/regional/data-source.provider.d.ts +1 -0
  74. package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-CzMi7CBH.mjs.map +0 -1
@@ -9,7 +9,7 @@ import { AXButtonModule } from '@acorex/components/button';
9
9
  import * as i2$4 from '@acorex/components/comment';
10
10
  import { AXCommentModule } from '@acorex/components/comment';
11
11
  import * as i2$2 from '@acorex/components/conversation';
12
- import { AXConversationService, AXConversationModule } from '@acorex/components/conversation';
12
+ import { AXConversationModule } from '@acorex/components/conversation';
13
13
  import * as i5 from '@acorex/components/decorators';
14
14
  import { AXDecoratorModule } from '@acorex/components/decorators';
15
15
  import * as i11$1 from '@acorex/components/dropdown';
@@ -34,7 +34,7 @@ import { AXTextBoxModule } from '@acorex/components/text-box';
34
34
  import * as i12 from '@acorex/components/toolbar';
35
35
  import { AXToolBarModule } from '@acorex/components/toolbar';
36
36
  import * as i8 from '@acorex/components/wysiwyg';
37
- import { AXWysiwygModule } from '@acorex/components/wysiwyg';
37
+ import { AXWysiwygContainerComponent, AXWysiwygModule } from '@acorex/components/wysiwyg';
38
38
  import * as i15 from '@acorex/core/format';
39
39
  import { AXFormatModule } from '@acorex/core/format';
40
40
  import { AXTranslationModule } from '@acorex/core/translation';
@@ -45,7 +45,7 @@ import * as i10 from '@acorex/platform/layout/views';
45
45
  import { AXPPageLayoutComponent } from '@acorex/platform/layout/views';
46
46
  import { AXPRootLayoutComponent } from '@acorex/platform/themes/default';
47
47
  import * as i14 from '@angular/common';
48
- import { CommonModule } from '@angular/common';
48
+ import { AsyncPipe, CommonModule } from '@angular/common';
49
49
  import * as i0 from '@angular/core';
50
50
  import { Injectable, inject, input, output, computed, ChangeDetectionStrategy, Component, viewChild, signal, afterNextRender, importProvidersFrom, NgModule } from '@angular/core';
51
51
  import * as i1$1 from '@angular/forms';
@@ -54,7 +54,7 @@ import * as i2$1 from '@angular/router';
54
54
  import { Router, ActivatedRoute, RouterModule } from '@angular/router';
55
55
  import { createAllQueryView, AXPEntityCommandScope, AXPEntityQueryType } from '@acorex/platform/common';
56
56
  import * as i2$3 from '@acorex/platform/layout/builder';
57
- import { AXPWidgetsCatalog, AXPLayoutBuilderModule } from '@acorex/platform/layout/builder';
57
+ import { AXPWidgetsCatalog, AXPLayoutBuilderModule, AXPLayoutWidgetComponent, AXPWidgetGroupEnum } from '@acorex/platform/layout/builder';
58
58
  import { AXMUsersEntityService } from '@acorex/modules/security-management';
59
59
  import { AXPSessionService } from '@acorex/platform/auth';
60
60
  import { AXFileService } from '@acorex/core/file';
@@ -64,6 +64,7 @@ import { AXToastService } from '@acorex/components/toast';
64
64
  import { AXPlatform } from '@acorex/core/platform';
65
65
  import { DomSanitizer } from '@angular/platform-browser';
66
66
  import { AXBasePageComponent } from '@acorex/components/page';
67
+ import { AXValidationModule } from '@acorex/core/validation';
67
68
 
68
69
  const config = {
69
70
  i18n: 'conversation',
@@ -1017,7 +1018,7 @@ class AXMChatItemComponent {
1017
1018
  return '';
1018
1019
  }
1019
1020
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMChatItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1020
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMChatItemComponent, isStandalone: false, selector: "axm-chat-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { pressChatItem: "pressChatItem" }, ngImport: i0, template: "<div\n [id]=\"data().id\"\n class=\"ax-cursor-pointer ax-p-4 ax-flex ax-items-center ax-justify-between ax-gap-4 ax-transition-all ax-duration-200 hover:ax-bg-surface-hover ax-rounded-lg ax-border-b ax-border-divider\"\n (click)=\"onPressChatItem(data().id)\"\n>\n <!-- Avatar and User Info Section -->\n <div class=\"ax-flex ax-min-w-0 ax-gap-4 ax-flex-1\">\n <!-- Avatar with Online Status -->\n <div class=\"ax-flex-shrink-0\">\n <ax-avatar class=\"ax-relative\" color=\"primary\" shape=\"rounded\" [size]=\"48\">\n @if (data().roomMembers && data().roomMembers.length > 0 && data().roomMembers[0].avatar) {\n <ax-image [src]=\"data().roomMembers[0].avatar\" class=\"ax-rounded-lg\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-font-medium\">{{ extractInitials(fullName()) }}</span>\n </ax-text>\n }\n\n <!-- Online Status Indicator -->\n @if (isOnline()) {\n <ax-badge class=\"ax-absolute ax-bottom-1 ax-end-1 !ax-size-3 !ax-border-2 !ax-border-surface\" color=\"success\">\n </ax-badge>\n }\n </ax-avatar>\n </div>\n\n <!-- User Details and Last Message -->\n <div class=\"ax-flex ax-flex-col ax-min-w-0 ax-flex-1\">\n <div class=\"ax-flex ax-items-center ax-justify-between ax-gap-2\">\n <p class=\"ax-font-semibold ax-text-on-surface ax-truncate\">{{ fullName() }}</p>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n @if (messageSeenStatus()) {\n <ax-icon class=\"ax-icon ax-text-success ax-size-5\" [class]=\"messageSeenStatus()\"></ax-icon>\n }\n @if (lastMessageDate()) {\n <span class=\"ax-text-xs ax-text-on-surface-variant ax-whitespace-nowrap\">\n {{ lastMessageDate() }}\n </span>\n }\n </div>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-mt-1\">\n <p class=\"ax-text-sm ax-text-on-surface-variant ax-truncate\">\n {{ lastMessage() }}\n </p>\n @if (hasUnread()) {\n <ax-badge color=\"primary\" [text]=\"unreadCount()\" class=\"ax-flex-shrink-0 ax-ml-auto\"></ax-badge>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i1.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "component", type: i2.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "component", type: i3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.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: "component", type: i5$1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1021
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMChatItemComponent, isStandalone: false, selector: "axm-chat-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { pressChatItem: "pressChatItem" }, ngImport: i0, template: "<div\n [id]=\"data().id\"\n class=\"ax-cursor-pointer ax-p-4 ax-flex ax-items-center ax-justify-between ax-gap-4 ax-transition-all ax-duration-200 hover:ax-bg-surface-hover ax-rounded-lg ax-border-b ax-border-divider\"\n (click)=\"onPressChatItem(data().id)\"\n>\n <!-- Avatar and User Info Section -->\n <div class=\"ax-flex ax-min-w-0 ax-gap-4 ax-flex-1\">\n <!-- Avatar with Online Status -->\n <div class=\"ax-flex-shrink-0\">\n <ax-avatar class=\"ax-relative\" color=\"primary\" shape=\"rounded\" [size]=\"48\">\n @if (data().roomMembers && data().roomMembers.length > 0 && data().roomMembers[0].avatar) {\n <ax-image [src]=\"data().roomMembers[0].avatar\" class=\"ax-rounded-lg\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-font-medium\">{{ extractInitials(fullName()) }}</span>\n </ax-text>\n }\n\n <!-- Online Status Indicator -->\n @if (isOnline()) {\n <ax-badge class=\"ax-absolute ax-bottom-1 ax-end-1 !ax-size-3 !ax-border-2 !ax-border-surface\" color=\"success\">\n </ax-badge>\n }\n </ax-avatar>\n </div>\n\n <!-- User Details and Last Message -->\n <div class=\"ax-flex ax-flex-col ax-min-w-0 ax-flex-1\">\n <div class=\"ax-flex ax-items-center ax-justify-between ax-gap-2\">\n <p class=\"ax-font-semibold ax-text-on-surface ax-truncate\">{{ fullName() }}</p>\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n @if (messageSeenStatus()) {\n <ax-icon class=\"ax-icon ax-text-success ax-size-5\" [class]=\"messageSeenStatus()\"></ax-icon>\n }\n @if (lastMessageDate()) {\n <span class=\"ax-text-xs ax-text-on-surface-variant ax-whitespace-nowrap\">\n {{ lastMessageDate() }}\n </span>\n }\n </div>\n </div>\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-mt-1\">\n <p class=\"ax-text-sm ax-text-on-surface-variant ax-truncate\">\n {{ lastMessage() }}\n </p>\n @if (hasUnread()) {\n <ax-badge color=\"primary\" [text]=\"unreadCount()\" class=\"ax-flex-shrink-0 ax-ml-auto\"></ax-badge>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i1.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "component", type: i2.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "component", type: i3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "text", "look"] }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.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: "component", type: i5$1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1021
1022
  }
1022
1023
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMChatItemComponent, decorators: [{
1023
1024
  type: Component,
@@ -1163,7 +1164,7 @@ class AXMChatComponent {
1163
1164
  console.log('ngOnDestroy');
1164
1165
  }
1165
1166
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1166
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMChatComponent, isStandalone: false, selector: "axm-chat", viewQueries: [{ propertyName: "tab", first: true, predicate: ["tab"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-page-layout>\n <axp-layout-start-side [axResizable]=\"true\" class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header>\n <axp-layout-title>Conversations</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [ngModel]=\"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\">\n <!-- Tabs -->\n <div class=\"ax-px-4\">\n <ax-tabs #tab class=\"ax-text-neutral-400\" [look]=\"'with-line'\" [location]=\"'bottom'\" [fitParent]=\"true\">\n <ax-tab-item text=\"All\" [active]=\"activeTab() === 0\">\n <ax-suffix>\n <ax-badge\n [text]=\"totalCount().toString()\"\n [color]=\"activeTab() === 0 ? 'primary' : 'secondary'\"\n class=\"ax-min-w-[1.5rem] ax-justify-center\"\n ></ax-badge>\n </ax-suffix>\n </ax-tab-item>\n @if (hasUnread()) {\n <ax-tab-item text=\"Unread\" [active]=\"activeTab() === 1\">\n <ax-suffix>\n <ax-badge\n [text]=\"unreadCount().toString()\"\n [color]=\"activeTab() === 1 ? '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 class=\"ax-flex-1 ax-overflow-hidden ax-flex ax-flex-col\">\n <!-- Loading State -->\n @if (isLoading()) {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-p-4\">\n <ax-loading></ax-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error()) {\n <div class=\"ax-p-4 ax-text-error ax-text-center\">\n {{ error() }}\n <button (click)=\"refreshChat()\" class=\"ax-mt-2 ax-text-primary hover:ax-text-primary-dark\">\n Try Again\n </button>\n </div>\n }\n\n <!-- Chat List -->\n @if (!isLoading() && !error()) {\n <div\n class=\"ax-flex-1 ax-overflow-y-auto ax-space-y-2 ax-scrollbar-thin ax-scrollbar-thumb-gray-300 ax-scrollbar-track-transparent\"\n >\n @for (i of filteredRooms(); track i.id) {\n <axm-chat-item\n [data]=\"i\"\n (click)=\"markChatAsRead(i.id)\"\n [class.ax-bg-surface]=\"selectedRoom()?.id === i.id\"\n class=\"ax-transition-all ax-duration-200 hover:ax-bg-surface ax-rounded-lg\"\n ></axm-chat-item>\n }\n\n <!-- Empty State -->\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 No chats available\n }\n </div>\n }\n </div>\n }\n\n <!-- Footer Content -->\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 </div>\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content>\n <!-- Chat Content -->\n <div class=\"ax-flex-1 ax-overflow-hidden\">\n <router-outlet></router-outlet>\n </div>\n </axp-page-content>\n</axp-page-layout>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i3$1.AXResizableDirective, selector: "[axResizable]", inputs: ["axResizable", "minWidth", "maxWidth", "dblClickAction", "width", "defaultWidth"], outputs: ["axResizableChange", "minWidthChange", "maxWidthChange", "dblClickActionChange", "widthChange", "defaultWidthChange", "onResizingStarted", "onResizingEnded", "onResizingDblClick"] }, { kind: "component", type: i3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i5.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: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: i7.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i7.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "component", type: i6$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: "component", type: i5$1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "component", type: i10.AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: i11.AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: i11.AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: i11.AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: i11.AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "component", type: AXMChatItemComponent, selector: "axm-chat-item", inputs: ["data"], outputs: ["pressChatItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1167
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMChatComponent, isStandalone: false, selector: "axm-chat", viewQueries: [{ propertyName: "tab", first: true, predicate: ["tab"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-page-layout>\n <axp-layout-start-side [axResizable]=\"true\" class=\"ax-border-e ax-lightest-surface ax-h-full\">\n <axp-layout-header>\n <axp-layout-title>Conversations</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n #searchInput\n look=\"solid\"\n [placeholder]=\"placeholder()\"\n [ngModel]=\"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\">\n <!-- Tabs -->\n <div class=\"ax-px-4\">\n <ax-tabs #tab class=\"ax-text-neutral-400\" [look]=\"'with-line'\" [location]=\"'bottom'\" [fitParent]=\"true\">\n <ax-tab-item text=\"All\" [active]=\"activeTab() === 0\">\n <ax-suffix>\n <ax-badge\n [text]=\"totalCount().toString()\"\n [color]=\"activeTab() === 0 ? 'primary' : 'secondary'\"\n class=\"ax-min-w-[1.5rem] ax-justify-center\"\n ></ax-badge>\n </ax-suffix>\n </ax-tab-item>\n @if (hasUnread()) {\n <ax-tab-item text=\"Unread\" [active]=\"activeTab() === 1\">\n <ax-suffix>\n <ax-badge\n [text]=\"unreadCount().toString()\"\n [color]=\"activeTab() === 1 ? '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 class=\"ax-flex-1 ax-overflow-hidden ax-flex ax-flex-col\">\n <!-- Loading State -->\n @if (isLoading()) {\n <div class=\"ax-flex ax-items-center ax-justify-center ax-p-4\">\n <ax-loading></ax-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error()) {\n <div class=\"ax-p-4 ax-text-error ax-text-center\">\n {{ error() }}\n <button (click)=\"refreshChat()\" class=\"ax-mt-2 ax-text-primary hover:ax-text-primary-dark\">\n Try Again\n </button>\n </div>\n }\n\n <!-- Chat List -->\n @if (!isLoading() && !error()) {\n <div\n class=\"ax-flex-1 ax-overflow-y-auto ax-space-y-2 ax-scrollbar-thin ax-scrollbar-thumb-gray-300 ax-scrollbar-track-transparent\"\n >\n @for (i of filteredRooms(); track i.id) {\n <axm-chat-item\n [data]=\"i\"\n (click)=\"markChatAsRead(i.id)\"\n [class.ax-bg-surface]=\"selectedRoom()?.id === i.id\"\n class=\"ax-transition-all ax-duration-200 hover:ax-bg-surface ax-rounded-lg\"\n ></axm-chat-item>\n }\n\n <!-- Empty State -->\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 No chats available\n }\n </div>\n }\n </div>\n }\n\n <!-- Footer Content -->\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 </div>\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-content>\n <!-- Chat Content -->\n <div class=\"ax-flex-1 ax-overflow-hidden\">\n <router-outlet></router-outlet>\n </div>\n </axp-page-content>\n</axp-page-layout>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i3$1.AXResizableDirective, selector: "[axResizable]", inputs: ["axResizable", "minWidth", "maxWidth", "dblClickAction", "width", "defaultWidth"], outputs: ["axResizableChange", "minWidthChange", "maxWidthChange", "dblClickActionChange", "widthChange", "defaultWidthChange", "onResizingStarted", "onResizingEnded", "onResizingDblClick"] }, { kind: "component", type: i3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "text", "look"] }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i5.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: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: i7.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i7.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "component", type: i6$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: "component", type: i5$1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "component", type: i10.AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: i11.AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: i11.AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: i11.AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: i11.AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "component", type: AXMChatItemComponent, selector: "axm-chat-item", inputs: ["data"], outputs: ["pressChatItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1167
1168
  }
1168
1169
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMChatComponent, decorators: [{
1169
1170
  type: Component,
@@ -1444,7 +1445,7 @@ class AXMChatPreviewComponent {
1444
1445
  // Signal for dynamic max-height (using computed logic for real-time updates)
1445
1446
  this.activatedRoute = inject(ActivatedRoute);
1446
1447
  this.fileService = inject(AXFileService);
1447
- this.conversationService = inject(AXConversationService);
1448
+ // private conversationService = inject(AXConversationService);
1448
1449
  this.chatService = inject(AXMChatService);
1449
1450
  this.options = signal({
1450
1451
  disabled: false,
@@ -1506,7 +1507,7 @@ class AXMChatPreviewComponent {
1506
1507
  type: 'voice',
1507
1508
  name: 'test name',
1508
1509
  };
1509
- this.conversationService.chats.update((values) => [...values, newVoiceMessage]);
1510
+ // this.conversationService.chats.update((values: any) => [...values, newVoiceMessage]);
1510
1511
  });
1511
1512
  }
1512
1513
  handleOnSend(e) {
@@ -1533,7 +1534,7 @@ class AXMChatPreviewComponent {
1533
1534
  };
1534
1535
  }
1535
1536
  }
1536
- this.conversationService.chats.update((values) => [...values, newMessage]);
1537
+ // this.conversationService.chats.update((values: any) => [...values, newMessage]);
1537
1538
  }
1538
1539
  this.scrollToEnd();
1539
1540
  }
@@ -1557,19 +1558,19 @@ class AXMChatPreviewComponent {
1557
1558
  // Convert to chat preview format
1558
1559
  const chatPreviewMessages = convertToChatPreview(messageResponse);
1559
1560
  // Set the messages in the conversation service
1560
- this.conversationService.chats.set(chatPreviewMessages);
1561
+ // this.conversationService.chats.set(chatPreviewMessages);
1561
1562
  }
1562
1563
  catch (error) {
1563
1564
  console.error('Failed to load messages:', error);
1564
1565
  // Fallback to demo data if there's an error
1565
- this.conversationService.chats.set(generateDemoChatPreview());
1566
+ // this.conversationService.chats.set(generateDemoChatPreview());
1566
1567
  }
1567
1568
  }
1568
1569
  loadDemoMessages() {
1569
- this.conversationService.chats.set(generateDemoChatPreview());
1570
+ // this.conversationService.chats.set(generateDemoChatPreview());
1570
1571
  }
1571
1572
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMChatPreviewComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1572
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: AXMChatPreviewComponent, isStandalone: false, selector: "axm-chat-preview", ngImport: i0, template: "<div class=\"ax-flex ax-flex-col ax-bg-surface-container\">\n <!-- Messages Container -->\n <ax-conversation-container class=\"ax-flex-1 ax-overflow-hidden\">\n <ax-conversation-view (onAction)=\"handleOnAction($event)\" [style.height]=\"dynamicHeight()\"></ax-conversation-view>\n </ax-conversation-container>\n\n <!-- Input Area -->\n <div class=\"ax-p-2\">\n <ax-conversation-input\n placeholder=\"Type a message...\"\n [(ngModel)]=\"options().value\"\n (onSendClick)=\"handleOnSend($event)\"\n (onFileChange)=\"handleFileChange($event)\"\n (onStopRecording)=\"handleEndRecord($event)\"\n (onCancelRecording)=\"handleCancelRecord($event)\"\n ></ax-conversation-input>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;background-color:var(--ax-surface-container)}:host::ng-deep ax-conversation-view>div{height:50rem!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$2.AXConversationViewComponent, selector: "ax-conversation-view", inputs: ["height", "isReply"], outputs: ["onScrollEnd", "onAction"] }, { kind: "component", type: i2$2.AXConversationInputComponent, selector: "ax-conversation-input", inputs: ["look", "placeholder", "maxLength", "hasAttachment", "hasVoice", "hasEmoji", "isLoading", "acceptFileType"], outputs: ["onSendClick", "onStartRecording", "onCancelRecording", "onEnterPressed"] }, { kind: "component", type: i2$2.AXConversationContainerComponent, selector: "ax-conversation-container" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1573
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: AXMChatPreviewComponent, isStandalone: false, selector: "axm-chat-preview", ngImport: i0, template: "<div class=\"ax-flex ax-flex-col ax-bg-surface-container\">\n <!-- Messages Container -->\n <ax-conversation-container class=\"ax-flex-1 ax-overflow-hidden\">\n <ax-conversation-view (onAction)=\"handleOnAction($event)\" [style.height]=\"dynamicHeight()\"></ax-conversation-view>\n </ax-conversation-container>\n\n <!-- Input Area -->\n <div class=\"ax-p-2\">\n <ax-conversation-input\n placeholder=\"Type a message...\"\n [(ngModel)]=\"options().value\"\n (onSendClick)=\"handleOnSend($event)\"\n (onFileChange)=\"handleFileChange($event)\"\n (onStopRecording)=\"handleEndRecord($event)\"\n (onCancelRecording)=\"handleCancelRecord($event)\"\n ></ax-conversation-input>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;background-color:var(--ax-surface-container)}:host::ng-deep ax-conversation-view>div{height:50rem!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$2.AXConversationViewComponent, selector: "ax-conversation-view", inputs: ["chatBoxHeight", "isReplyArrowShown"], outputs: ["onScrollEnd", "onAction"] }, { kind: "component", type: i2$2.AXConversationInputComponent, selector: "ax-conversation-input", inputs: ["look", "placeholder", "maxLength", "hasAttachment", "hasVoice", "hasEmoji", "isLoading", "acceptFileType"], outputs: ["onSendClick", "onStartRecording", "onCancelRecording", "onEnterPressed"] }, { kind: "component", type: i2$2.AXConversationContainerComponent, selector: "ax-conversation-container", inputs: ["chatData"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1573
1574
  }
1574
1575
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMChatPreviewComponent, decorators: [{
1575
1576
  type: Component,
@@ -2335,6 +2336,466 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
2335
2336
  args: [{ selector: 'axm-comment-list-view', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-mt-2\">\n <ax-comment-container>\n @if (isLoading()) {\n <div class=\"ax-flex ax-items-center ax-py-12 ax-bg-lightest ax-px-5\">\n <ax-skeleton class=\"ax-min-w-16 ax-h-16 ax-rounded-full ax-me-4\"></ax-skeleton>\n <div class=\"ax-flex ax-flex-col ax-gap-2 ax-w-full\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-2 ax-rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-2 ax-rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-8/12 ax-h-2 ax-rounded-full\"></ax-skeleton>\n </div>\n </div>\n } @else if (!isLoading() && comments().length > 0) {\n <ax-comment-view class=\"ax-bg-lightest\">\n @for (comment of comments(); track comment.id) {\n <ax-comment-item [id]=\"comment.id!\" [replyCount]=\"comment.replies?.length ?? 0\">\n <ax-avatar [color]=\"avatarConfig().color\" [shape]=\"avatarConfig().look\">\n @if (checkImageExists(comment.id!) && comment.author && extractInitials(comment.author) !== '?') {\n <ax-image (onError)=\"handleImageError(comment.id!)\" [src]=\"''\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-overflow-hidden\">{{ extractInitials(comment.author) }}</span>\n </ax-text>\n }\n </ax-avatar>\n <ax-title>{{ extractInitials(comment.author) }}</ax-title>\n <ax-comment-date>{{ calcDefrenetTime(comment.createdAt) | format: 'timeleft' | async }} </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button class=\"ax-sm\" look=\"blank\" color=\"neutral\">\n <ax-icon icon=\"ax-icon ax-icon-solid ax-icon-more-horizontal\"></ax-icon>\n </ax-button>\n\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item text=\"Edit\" color=\"neutral\" (click)=\"editMessage(comment)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-edit\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n\n <ax-button-item text=\"Delete\" color=\"danger\" (click)=\"deleteComment(comment)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content [innerHTML]=\"sanitizeHtml(comment.message.content)\"></ax-content>\n <ax-comment-like (click)=\"toggleLike(comment)\" [liked]=\"comment.isLiked!\">\n {{ comment.reactionsCount }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"replyMessage(comment)\"></ax-comment-reply-text>\n @for (reply of comment.replies; track reply.id) {\n <ax-comment-item [id]=\"reply.id\">\n <ax-avatar [color]=\"avatarConfig().color\" [shape]=\"avatarConfig().look\">\n @if (reply && checkImageExists(reply.id!) && reply.author && extractInitials(reply.author) !== '?') {\n <ax-image (onError)=\"handleImageError(reply.id!)\" [src]=\"''\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-overflow-hidden\">{{ extractInitials(reply.author) }}</span>\n </ax-text>\n }\n </ax-avatar>\n <ax-title>{{ extractInitials(reply.author) }}</ax-title>\n <ax-comment-date>{{ calcDefrenetTime(reply.createdAt) | format: 'timeleft' | async }} </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button class=\"ax-sm\" look=\"blank\" color=\"neutral\">\n <ax-icon icon=\"ax-icon ax-icon-solid ax-icon-more-horizontal\"></ax-icon>\n </ax-button>\n\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item text=\"Edit\" color=\"neutral\" (click)=\"editMessage(comment, reply)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-edit\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item text=\"Delete\" color=\"danger\" (click)=\"deleteReply(comment, reply)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content [innerHTML]=\"sanitizeHtml(reply.message.content)\"></ax-content>\n <ax-comment-like (click)=\"toggleLike(comment, reply)\" [liked]=\"reply.isLiked!\">\n {{ reply.reactionsCount }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"replyMessage(comment, reply)\"></ax-comment-reply-text>\n </ax-comment-item>\n }\n </ax-comment-item>\n }\n </ax-comment-view>\n } @else {\n <div>\n <div class=\"ax-flex ax-flex-col ax-gap-4 ax-justify-center ax-items-center ax-p-10\">\n <svg\n class=\"ax-mx-auto\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"154\"\n height=\"161\"\n viewBox=\"0 0 154 161\"\n fill=\"none\"\n >\n <path\n d=\"M0.0616455 84.4268C0.0616455 42.0213 34.435 7.83765 76.6507 7.83765C118.803 7.83765 153.224 42.0055 153.224 84.4268C153.224 102.42 147.026 118.974 136.622 132.034C122.282 150.138 100.367 161 76.6507 161C52.7759 161 30.9882 150.059 16.6633 132.034C6.25961 118.974 0.0616455 102.42 0.0616455 84.4268Z\"\n fill=\"#EEF2FF\"\n />\n <path\n d=\"M96.8189 0.632498L96.8189 0.632384L96.8083 0.630954C96.2034 0.549581 95.5931 0.5 94.9787 0.5H29.338C22.7112 0.5 17.3394 5.84455 17.3394 12.4473V142.715C17.3394 149.318 22.7112 154.662 29.338 154.662H123.948C130.591 154.662 135.946 149.317 135.946 142.715V38.9309C135.946 38.0244 135.847 37.1334 135.648 36.2586L135.648 36.2584C135.117 33.9309 133.874 31.7686 132.066 30.1333C132.066 30.1331 132.065 30.1329 132.065 30.1327L103.068 3.65203C103.068 3.6519 103.067 3.65177 103.067 3.65164C101.311 2.03526 99.1396 0.995552 96.8189 0.632498Z\"\n fill=\"white\"\n stroke=\"#E5E7EB\"\n />\n <ellipse cx=\"80.0618\" cy=\"81\" rx=\"28.0342\" ry=\"28.0342\" fill=\"#EEF2FF\" />\n <path\n d=\"M99.2393 61.3061L99.2391 61.3058C88.498 50.5808 71.1092 50.5804 60.3835 61.3061C49.6423 72.0316 49.6422 89.4361 60.3832 100.162C71.109 110.903 88.4982 110.903 99.2393 100.162C109.965 89.4363 109.965 72.0317 99.2393 61.3061ZM105.863 54.6832C120.249 69.0695 120.249 92.3985 105.863 106.785C91.4605 121.171 68.1468 121.171 53.7446 106.785C39.3582 92.3987 39.3582 69.0693 53.7446 54.683C68.1468 40.2965 91.4605 40.2966 105.863 54.6832Z\"\n stroke=\"#E5E7EB\"\n />\n <path\n d=\"M110.782 119.267L102.016 110.492C104.888 108.267 107.476 105.651 109.564 102.955L118.329 111.729L110.782 119.267Z\"\n stroke=\"#E5E7EB\"\n />\n <path\n d=\"M139.122 125.781L139.122 125.78L123.313 109.988C123.313 109.987 123.313 109.987 123.312 109.986C121.996 108.653 119.849 108.657 118.521 109.985L118.871 110.335L118.521 109.985L109.047 119.459C107.731 120.775 107.735 122.918 109.044 124.247L109.047 124.249L124.858 140.06C128.789 143.992 135.191 143.992 139.122 140.06C143.069 136.113 143.069 129.728 139.122 125.781Z\"\n fill=\"#A5B4FC\"\n stroke=\"#818CF8\"\n />\n <path\n d=\"M83.185 87.2285C82.5387 87.2285 82.0027 86.6926 82.0027 86.0305C82.0027 83.3821 77.9987 83.3821 77.9987 86.0305C77.9987 86.6926 77.4627 87.2285 76.8006 87.2285C76.1543 87.2285 75.6183 86.6926 75.6183 86.0305C75.6183 80.2294 84.3831 80.2451 84.3831 86.0305C84.3831 86.6926 83.8471 87.2285 83.185 87.2285Z\"\n fill=\"#4F46E5\"\n />\n <path\n d=\"M93.3528 77.0926H88.403C87.7409 77.0926 87.2049 76.5567 87.2049 75.8946C87.2049 75.2483 87.7409 74.7123 88.403 74.7123H93.3528C94.0149 74.7123 94.5509 75.2483 94.5509 75.8946C94.5509 76.5567 94.0149 77.0926 93.3528 77.0926Z\"\n fill=\"#4F46E5\"\n />\n <path\n d=\"M71.5987 77.0925H66.6488C65.9867 77.0925 65.4507 76.5565 65.4507 75.8945C65.4507 75.2481 65.9867 74.7122 66.6488 74.7122H71.5987C72.245 74.7122 72.781 75.2481 72.781 75.8945C72.781 76.5565 72.245 77.0925 71.5987 77.0925Z\"\n fill=\"#4F46E5\"\n />\n <rect x=\"38.3522\" y=\"21.5128\" width=\"41.0256\" height=\"2.73504\" rx=\"1.36752\" fill=\"#4F46E5\" />\n <rect x=\"38.3522\" y=\"133.65\" width=\"54.7009\" height=\"5.47009\" rx=\"2.73504\" fill=\"#A5B4FC\" />\n <rect x=\"38.3522\" y=\"29.7179\" width=\"13.6752\" height=\"2.73504\" rx=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"56.13\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"61.6001\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"67.0702\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n </svg>\n <div>\n <h2 class=\"ax-text-center ax-text-neutral-600 ax-font-semibold ax-leading-loose ax-pb-2\">\n There is no Comment!\n </h2>\n </div>\n </div>\n </div>\n }\n </ax-comment-container>\n <ax-form>\n <ax-form-field>\n <div>\n @if (isReplyingMode() || isEditingMode()) {\n <div\n class=\"ax-flex ax-justify-between ax-rounded-b-none ax-border ax-border-b-0 ax-rounded-lg ax-bg-on-surface ax-px-6 ax-py-3 ax-w-full ax-items-center ax-overflow-hidden ax-text-sm ax-leading-none\"\n >\n <div (click)=\"scrollMain()\" class=\"ax-flex ax-justify-start ax-items-center ax-cursor-pointer\">\n <i\n [class]=\"isReplyingMode() ? 'fa-reply' : 'fa-pen'\"\n class=\"fa-solid ax-text-primary-500 dark:ax-text-primary-300 ax-text-2xl ax-me-4\"\n ></i>\n <div\n class=\"ax-flex ax-flex-col ax-gap-2 ax-justify-between ax-align-middle ax-leading-4 ax-overflow-hidden\"\n >\n <p class=\"ax-text-primary-500 dark:ax-text-primary-300\">\n {{ isReplyingMode() ? 'Reply to ' : 'Edit Message' }}\n <span class=\"ax-font-bold\">\n {{ isReplyingMode() ? extractInitials(activeReplyComment()?.author) : '' }}\n </span>\n </p>\n <div\n class=\"ax-truncate\"\n [innerHTML]=\"\n isReplyingMode()\n ? sanitizeHtml(activeReplyComment()?.message?.content ?? '')\n : sanitizeHtml(activeEditComment()?.message?.content ?? '')\n \"\n ></div>\n </div>\n </div>\n <div><i (click)=\"resetReplyEditState()\" class=\"fa-solid ax-text-2xl fa-xmark ax-cursor-pointer\"></i></div>\n </div>\n }\n <ax-wysiwyg-container #w [look]=\"wysiwygOptions().look\" [(ngModel)]=\"commentContent\">\n <ax-wysiwyg-view class=\"ax-min-h-28\"></ax-wysiwyg-view>\n <ax-toolbar>\n <ax-content>\n <ax-wysiwyg-history></ax-wysiwyg-history>\n <ax-wysiwyg-font-style></ax-wysiwyg-font-style>\n <ax-wysiwyg-colors></ax-wysiwyg-colors>\n <ax-wysiwyg-list></ax-wysiwyg-list>\n <ax-wysiwyg-alignment></ax-wysiwyg-alignment>\n </ax-content>\n <ax-suffix>\n <ax-dropdown-button\n [disabled]=\"hasCooldown()\"\n type=\"submit\"\n color=\"primary\"\n mode=\"split\"\n text=\"Send\"\n (onClick)=\"submitComment()\"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n }\n <ax-button-item-list>\n <ax-button-item (click)=\"submitComment(true)\" text=\"Send Private ...\" name=\"private\" data=\"private\">\n <ax-prefix>\n <ax-icon icon=\"fa-regular fa-user-secret\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n </ax-suffix>\n </ax-toolbar>\n <ax-validation-rule rule=\"callback\" [options]=\"{ validate: validateContent }\"></ax-validation-rule>\n </ax-wysiwyg-container>\n </div>\n </ax-form-field>\n </ax-form>\n</div>\n", styles: ["ax-wysiwyg-container .ax-editor-container{border-top-left-radius:0!important;border-top-right-radius:0!important}ax-wysiwyg-container .ax-error-message{padding-left:.5rem}\n"] }]
2336
2337
  }] });
2337
2338
 
2339
+ class AXMCommentWidgetViewComponent extends AXPLayoutWidgetComponent {
2340
+ constructor() {
2341
+ super(...arguments);
2342
+ this.hasCooldown = signal(false);
2343
+ this.commentContent = signal('');
2344
+ this.isSubmitting = signal(false);
2345
+ this.isReplyingMode = signal(false);
2346
+ this.isEditingMode = signal(false);
2347
+ this.isLoading = signal(true);
2348
+ this.failedImageIds = signal([]);
2349
+ this.activeReplyComment = signal(undefined);
2350
+ this.activeEditComment = signal(undefined);
2351
+ this.wysiwygEditor = viewChild.required('w');
2352
+ this.commentService = inject(AXMCommentService);
2353
+ this.platform = inject(AXPlatform);
2354
+ this.popupService = inject(AXPopupService);
2355
+ this.toastService = inject(AXToastService);
2356
+ this.dialogService = inject(AXDialogService);
2357
+ this.sanitize = inject(DomSanitizer);
2358
+ this.getPayload = computed(() => ({
2359
+ params: this.payload(),
2360
+ skip: 0,
2361
+ take: 10,
2362
+ }));
2363
+ this.payload = computed(() => ({
2364
+ roomType: 'default',
2365
+ entityId: this.options().entityId,
2366
+ instanceId: this.options().instanceId,
2367
+ }));
2368
+ this.comments = signal([]);
2369
+ this.wysiwyg = viewChild('w');
2370
+ this.wysiwygOptions = signal({
2371
+ look: 'solid',
2372
+ });
2373
+ this.avatarConfig = signal({
2374
+ color: 'primary',
2375
+ look: 'rounded',
2376
+ type: 'solid', // 'image' | 'text' | 'icon' | 'default'
2377
+ });
2378
+ this.validateContent = (content) => {
2379
+ let isValid = true;
2380
+ if (!content || content === '<p><br></p>') {
2381
+ isValid = false;
2382
+ }
2383
+ return {
2384
+ rule: 'callback',
2385
+ result: isValid,
2386
+ message: isValid ? '' : 'Please fill the content',
2387
+ value: content,
2388
+ };
2389
+ };
2390
+ }
2391
+ ngOnInit() {
2392
+ super.ngOnInit();
2393
+ this.loadComments();
2394
+ }
2395
+ sanitizeHtml(htmlContent) {
2396
+ if (!htmlContent)
2397
+ return this.sanitize.bypassSecurityTrustHtml('');
2398
+ return this.sanitize.bypassSecurityTrustHtml(htmlContent);
2399
+ }
2400
+ handleImageError(imageId) {
2401
+ this.failedImageIds.update((ids) => [...ids, imageId]);
2402
+ }
2403
+ checkImageExists(imageId) {
2404
+ return !this.failedImageIds().includes(imageId);
2405
+ }
2406
+ extractInitials(name) {
2407
+ if (!name)
2408
+ return '?';
2409
+ // Handle the case where name is an object with fullName property
2410
+ const nameStr = typeof name === 'object' && name.fullName ? name.fullName : String(name);
2411
+ const words = nameStr.split(' ');
2412
+ const initials = words.map((word) => word.charAt(0).toUpperCase());
2413
+ return initials.join('');
2414
+ }
2415
+ async loadComments() {
2416
+ this.isLoading.set(true);
2417
+ try {
2418
+ const response = await this.commentService.query(this.getPayload());
2419
+ this.comments.set(response.items);
2420
+ }
2421
+ catch (error) {
2422
+ console.error('Failed to load comments:', error);
2423
+ this.toastService.show({
2424
+ content: 'Failed to load comments. Please try again.',
2425
+ color: 'danger',
2426
+ location: 'bottom-center',
2427
+ closeButton: true,
2428
+ timeOut: 3000,
2429
+ timeOutProgress: true,
2430
+ });
2431
+ this.comments.set([]);
2432
+ }
2433
+ finally {
2434
+ setTimeout(() => {
2435
+ this.isLoading.set(false);
2436
+ }, 250);
2437
+ }
2438
+ }
2439
+ editMessage(comment, reply) {
2440
+ this.isReplyingMode.set(false);
2441
+ this.activeReplyComment.set(undefined);
2442
+ this.isEditingMode.set(true);
2443
+ this.activeEditComment.set(comment);
2444
+ const contentToEdit = reply ? reply.message?.content : comment.message?.content;
2445
+ this.commentContent.set(contentToEdit || '');
2446
+ this.wysiwygEditor().getHostElement().scrollIntoView({ behavior: 'smooth', block: 'start' });
2447
+ }
2448
+ replyMessage(comment, reply) {
2449
+ this.isEditingMode.set(false);
2450
+ this.activeEditComment.set(undefined);
2451
+ this.isReplyingMode.set(true);
2452
+ this.activeReplyComment.set(comment);
2453
+ if (reply) {
2454
+ const author = reply.author.fullName || reply.author.id;
2455
+ const mention = `<a data-id="${reply.id}">@${author}</a> `;
2456
+ this.commentContent.set(mention);
2457
+ this.wysiwyg()?.focus();
2458
+ document.getElementsByClassName('ql-editor')[0].innerHTML = mention;
2459
+ }
2460
+ this.wysiwygEditor().getHostElement().scrollIntoView({ behavior: 'smooth', block: 'start' });
2461
+ }
2462
+ async deleteComment(comment) {
2463
+ const dialog = this.dialogService.open({
2464
+ icon: 'fa-regular fa-warning',
2465
+ content: 'Are you sure you want to delete this comment?',
2466
+ title: 'Delete Comment',
2467
+ type: 'danger',
2468
+ orientation: 'horizontal',
2469
+ buttons: [
2470
+ {
2471
+ text: 'Delete',
2472
+ color: 'danger',
2473
+ onClick: async (e) => {
2474
+ e.handled = true;
2475
+ e.source.text = 'Deleting...';
2476
+ e.source.disabled = true;
2477
+ e.source.loading = true;
2478
+ try {
2479
+ if (comment.id) {
2480
+ await this.commentService.deleteOne(comment.id);
2481
+ this.removeMessageById(comment.id);
2482
+ this.toastService.show({
2483
+ content: 'Comment deleted successfully.',
2484
+ color: 'success',
2485
+ location: 'bottom-center',
2486
+ closeButton: true,
2487
+ timeOut: 3000,
2488
+ timeOutProgress: true,
2489
+ });
2490
+ if (this.isEditingMode() && this.activeEditComment()?.id === comment.id) {
2491
+ this.resetReplyEditState();
2492
+ }
2493
+ dialog.close();
2494
+ }
2495
+ }
2496
+ catch (error) {
2497
+ this.toastService.show({
2498
+ content: typeof error === 'string' ? error : 'Failed to delete comment!',
2499
+ color: 'danger',
2500
+ location: 'bottom-center',
2501
+ closeButton: true,
2502
+ timeOut: 3000,
2503
+ timeOutProgress: true,
2504
+ });
2505
+ }
2506
+ },
2507
+ },
2508
+ {
2509
+ text: 'Cancel',
2510
+ color: 'default',
2511
+ autofocus: true,
2512
+ onClick: (e) => {
2513
+ dialog.close();
2514
+ },
2515
+ },
2516
+ ],
2517
+ closeButton: false,
2518
+ });
2519
+ }
2520
+ async deleteReply(comment, reply) {
2521
+ const dialog = this.dialogService.open({
2522
+ icon: 'fa-regular fa-warning',
2523
+ content: 'Are you sure you want to delete this reply?',
2524
+ title: 'Delete Reply',
2525
+ type: 'danger',
2526
+ orientation: 'horizontal',
2527
+ buttons: [
2528
+ {
2529
+ text: 'Delete',
2530
+ color: 'danger',
2531
+ onClick: async (e) => {
2532
+ e.handled = true;
2533
+ e.source.text = 'Deleting...';
2534
+ e.source.disabled = true;
2535
+ e.source.loading = true;
2536
+ try {
2537
+ if (reply.id) {
2538
+ await this.commentService.deleteOne(reply.id);
2539
+ this.removeMessageById(comment.id, reply.id);
2540
+ this.toastService.show({
2541
+ content: 'Comment deleted successfully.',
2542
+ color: 'success',
2543
+ location: 'bottom-center',
2544
+ closeButton: true,
2545
+ timeOut: 3000,
2546
+ timeOutProgress: true,
2547
+ });
2548
+ dialog.close();
2549
+ }
2550
+ }
2551
+ catch (error) {
2552
+ this.toastService.show({
2553
+ content: typeof error === 'string' ? error : 'Failed to delete comment!',
2554
+ color: 'danger',
2555
+ location: 'bottom-center',
2556
+ closeButton: true,
2557
+ timeOut: 3000,
2558
+ timeOutProgress: true,
2559
+ });
2560
+ }
2561
+ },
2562
+ },
2563
+ {
2564
+ text: 'Cancel',
2565
+ color: 'default',
2566
+ autofocus: true,
2567
+ onClick: (e) => {
2568
+ dialog.close();
2569
+ },
2570
+ },
2571
+ ],
2572
+ closeButton: false,
2573
+ });
2574
+ }
2575
+ resetReplyEditState() {
2576
+ this.isEditingMode.set(false);
2577
+ this.activeEditComment.set(undefined);
2578
+ this.isReplyingMode.set(false);
2579
+ this.activeReplyComment.set(undefined);
2580
+ this.commentContent.set('');
2581
+ document.getElementsByClassName('ql-editor')[0].innerHTML = '';
2582
+ }
2583
+ async toggleLike(comment, reply) {
2584
+ try {
2585
+ if (reply) {
2586
+ if (reply.id) {
2587
+ this.updateLikeStatus(comment.id, reply.id);
2588
+ await this.commentService.like(reply.id);
2589
+ }
2590
+ }
2591
+ else {
2592
+ if (comment.id) {
2593
+ this.updateLikeStatus(comment.id);
2594
+ await this.commentService.like(comment.id);
2595
+ }
2596
+ }
2597
+ }
2598
+ catch (error) {
2599
+ console.error('Failed to toggle like:', error);
2600
+ // Revert the optimistic update if the server call fails
2601
+ if (reply && reply.id) {
2602
+ this.updateLikeStatus(comment.id, reply.id);
2603
+ }
2604
+ else if (comment.id) {
2605
+ this.updateLikeStatus(comment.id);
2606
+ }
2607
+ }
2608
+ }
2609
+ updateLikeStatus(commentId, replyId) {
2610
+ this.comments.update((commentsList) => {
2611
+ return commentsList.map((comment) => {
2612
+ if (comment.id === commentId) {
2613
+ if (replyId && comment.replies) {
2614
+ const updatedReplies = comment.replies.map((reply) => reply.id === replyId
2615
+ ? {
2616
+ ...reply,
2617
+ isLiked: !reply.isLiked,
2618
+ reactionsCount: reply.isLiked && reply.reactionsCount !== undefined
2619
+ ? reply.reactionsCount - 1
2620
+ : (reply.reactionsCount || 0) + 1,
2621
+ }
2622
+ : reply);
2623
+ return {
2624
+ ...comment,
2625
+ replies: updatedReplies,
2626
+ };
2627
+ }
2628
+ else {
2629
+ return {
2630
+ ...comment,
2631
+ isLiked: !comment.isLiked,
2632
+ reactionsCount: comment.isLiked && comment.reactionsCount !== undefined
2633
+ ? comment.reactionsCount - 1
2634
+ : (comment.reactionsCount || 0) + 1,
2635
+ };
2636
+ }
2637
+ }
2638
+ return comment;
2639
+ });
2640
+ });
2641
+ }
2642
+ removeMessageById(commentId, replyId) {
2643
+ if (replyId) {
2644
+ // Remove a reply from a comment
2645
+ this.comments.update((commentsList) => commentsList.map((comment) => {
2646
+ if (comment.id === commentId && comment.replies) {
2647
+ return {
2648
+ ...comment,
2649
+ replies: comment.replies.filter((reply) => reply.id !== replyId),
2650
+ };
2651
+ }
2652
+ return comment;
2653
+ }));
2654
+ }
2655
+ else {
2656
+ // Remove a whole comment
2657
+ this.comments.update((commentsList) => commentsList.filter((comment) => comment.id !== commentId));
2658
+ }
2659
+ }
2660
+ async submitComment(isPrivate = false) {
2661
+ if (!this.validateContent(this.commentContent()).result) {
2662
+ return;
2663
+ }
2664
+ this.isSubmitting.set(true);
2665
+ let memberLookup;
2666
+ if (isPrivate) {
2667
+ const popupConfig = {
2668
+ header: true,
2669
+ size: 'md',
2670
+ draggable: true,
2671
+ hasBackdrop: true,
2672
+ closeButton: true,
2673
+ closeOnBackdropClick: false,
2674
+ };
2675
+ const popup = await this.popupService.open(AXMCommentLookupPopup, popupConfig);
2676
+ memberLookup = popup.data?.data?.lookup;
2677
+ }
2678
+ try {
2679
+ if (this.isEditingMode() && this.activeEditComment()?.id) {
2680
+ const payload = {
2681
+ message: {
2682
+ content: this.commentContent(),
2683
+ contentType: 'text',
2684
+ },
2685
+ };
2686
+ await this.commentService.updateOne(this.activeEditComment().id, payload);
2687
+ this.hasCooldown.set(true);
2688
+ this.isEditingMode.set(false);
2689
+ this.activeEditComment.set(undefined);
2690
+ }
2691
+ else {
2692
+ const payload = {
2693
+ ...this.payload(),
2694
+ content: this.commentContent(),
2695
+ contentType: 'text',
2696
+ isPrivate: isPrivate,
2697
+ replyId: this.activeReplyComment()?.id ?? null,
2698
+ };
2699
+ await this.commentService.insertOne(payload);
2700
+ this.hasCooldown.set(true);
2701
+ this.isReplyingMode.set(false);
2702
+ this.activeReplyComment.set(undefined);
2703
+ }
2704
+ // Reload comments to get the updated list with proper hierarchy
2705
+ const response = await this.commentService.query(this.getPayload());
2706
+ this.comments.set(response.items);
2707
+ this.commentContent.set('');
2708
+ document.getElementsByClassName('ql-editor')[0].innerHTML = '';
2709
+ setTimeout(() => {
2710
+ this.hasCooldown.set(false);
2711
+ }, 1000);
2712
+ }
2713
+ catch (error) {
2714
+ console.error('Error submitting comment:', error);
2715
+ this.toastService.show({
2716
+ content: typeof error === 'string' ? error : 'Failed to submit comment. Please try again.',
2717
+ color: 'danger',
2718
+ location: 'bottom-center',
2719
+ closeButton: true,
2720
+ timeOut: 3000,
2721
+ timeOutProgress: true,
2722
+ });
2723
+ }
2724
+ finally {
2725
+ this.isSubmitting.set(false);
2726
+ }
2727
+ }
2728
+ scrollMain() {
2729
+ const comment = this.isReplyingMode() ? this.activeReplyComment() : this.activeEditComment();
2730
+ if (comment && comment.id) {
2731
+ const el = document.getElementById(comment.id);
2732
+ if (el) {
2733
+ el.scrollIntoView({ behavior: 'smooth', block: 'center' });
2734
+ const content = el?.firstElementChild?.children[1];
2735
+ if (content) {
2736
+ const prevBg = content.style.background;
2737
+ content.style.borderRadius = '0.25rem';
2738
+ content.style.transition = 'background 1s ease-in-out';
2739
+ content.style.background = `rgba(var(--ax-color-on-surface), var(--tw-bg-opacity))`;
2740
+ setTimeout(() => {
2741
+ content.style.background = prevBg || 'rgba(0, 0, 0, 0)';
2742
+ }, 1000);
2743
+ }
2744
+ }
2745
+ }
2746
+ }
2747
+ calcDefrenetTime(date) {
2748
+ return date ? Date.now() - date.getTime() : undefined;
2749
+ }
2750
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMCommentWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2751
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMCommentWidgetViewComponent, isStandalone: true, selector: "axm-comment-widget-view", viewQueries: [{ propertyName: "wysiwygEditor", first: true, predicate: ["w"], descendants: true, isSignal: true }, { propertyName: "wysiwyg", first: true, predicate: ["w"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-mt-2 ax-p-2\">\n <ax-comment-container>\n @if (isLoading()) {\n <div class=\"ax-flex ax-items-center ax-py-12 ax-bg-lightest ax-px-5\">\n <ax-skeleton class=\"ax-min-w-16 ax-h-16 ax-rounded-full ax-me-4\"></ax-skeleton>\n <div class=\"ax-flex ax-flex-col ax-gap-2 ax-w-full\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-2 ax-rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-2 ax-rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-8/12 ax-h-2 ax-rounded-full\"></ax-skeleton>\n </div>\n </div>\n } @else if (!isLoading() && comments().length > 0) {\n <ax-comment-view class=\"ax-bg-lightest\">\n @for (comment of comments(); track comment.id) {\n <ax-comment-item [id]=\"comment.id!\" [replyCount]=\"comment.replies?.length ?? 0\">\n <ax-avatar [color]=\"avatarConfig().color\" [shape]=\"avatarConfig().look\">\n @if (checkImageExists(comment.id!) && comment.author && extractInitials(comment.author) !== '?') {\n <ax-image (onError)=\"handleImageError(comment.id!)\" [src]=\"''\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-overflow-hidden\">{{ extractInitials(comment.author) }}</span>\n </ax-text>\n }\n </ax-avatar>\n <ax-title>{{ extractInitials(comment.author) }}</ax-title>\n <ax-comment-date>{{ calcDefrenetTime(comment.createdAt) | format: 'timeleft' | async }} </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button class=\"ax-sm\" look=\"blank\" color=\"neutral\">\n <ax-icon icon=\"ax-icon ax-icon-solid ax-icon-more-horizontal\"></ax-icon>\n </ax-button>\n\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item text=\"Edit\" color=\"neutral\" (click)=\"editMessage(comment)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-edit\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n\n <ax-button-item text=\"Delete\" color=\"danger\" (click)=\"deleteComment(comment)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content [innerHTML]=\"sanitizeHtml(comment.message.content)\"></ax-content>\n <ax-comment-like (click)=\"toggleLike(comment)\" [liked]=\"comment.isLiked!\">\n {{ comment.reactionsCount }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"replyMessage(comment)\"></ax-comment-reply-text>\n @for (reply of comment.replies; track reply.id) {\n <ax-comment-item [id]=\"reply.id\">\n <ax-avatar [color]=\"avatarConfig().color\" [shape]=\"avatarConfig().look\">\n @if (reply && checkImageExists(reply.id!) && reply.author && extractInitials(reply.author) !== '?') {\n <ax-image (onError)=\"handleImageError(reply.id!)\" [src]=\"''\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-overflow-hidden\">{{ extractInitials(reply.author) }}</span>\n </ax-text>\n }\n </ax-avatar>\n <ax-title>{{ extractInitials(reply.author) }}</ax-title>\n <ax-comment-date>{{ calcDefrenetTime(reply.createdAt) | format: 'timeleft' | async }} </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button class=\"ax-sm\" look=\"blank\" color=\"neutral\">\n <ax-icon icon=\"ax-icon ax-icon-solid ax-icon-more-horizontal\"></ax-icon>\n </ax-button>\n\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item text=\"Edit\" color=\"neutral\" (click)=\"editMessage(comment, reply)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-edit\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item text=\"Delete\" color=\"danger\" (click)=\"deleteReply(comment, reply)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content [innerHTML]=\"sanitizeHtml(reply.message.content)\"></ax-content>\n <ax-comment-like (click)=\"toggleLike(comment, reply)\" [liked]=\"reply.isLiked!\">\n {{ reply.reactionsCount }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"replyMessage(comment, reply)\"></ax-comment-reply-text>\n </ax-comment-item>\n }\n </ax-comment-item>\n }\n </ax-comment-view>\n } @else {\n <div>\n <div class=\"ax-flex ax-flex-col ax-gap-4 ax-justify-center ax-items-center ax-p-10\">\n <svg\n class=\"ax-mx-auto\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"154\"\n height=\"161\"\n viewBox=\"0 0 154 161\"\n fill=\"none\"\n >\n <path\n d=\"M0.0616455 84.4268C0.0616455 42.0213 34.435 7.83765 76.6507 7.83765C118.803 7.83765 153.224 42.0055 153.224 84.4268C153.224 102.42 147.026 118.974 136.622 132.034C122.282 150.138 100.367 161 76.6507 161C52.7759 161 30.9882 150.059 16.6633 132.034C6.25961 118.974 0.0616455 102.42 0.0616455 84.4268Z\"\n fill=\"#EEF2FF\"\n />\n <path\n d=\"M96.8189 0.632498L96.8189 0.632384L96.8083 0.630954C96.2034 0.549581 95.5931 0.5 94.9787 0.5H29.338C22.7112 0.5 17.3394 5.84455 17.3394 12.4473V142.715C17.3394 149.318 22.7112 154.662 29.338 154.662H123.948C130.591 154.662 135.946 149.317 135.946 142.715V38.9309C135.946 38.0244 135.847 37.1334 135.648 36.2586L135.648 36.2584C135.117 33.9309 133.874 31.7686 132.066 30.1333C132.066 30.1331 132.065 30.1329 132.065 30.1327L103.068 3.65203C103.068 3.6519 103.067 3.65177 103.067 3.65164C101.311 2.03526 99.1396 0.995552 96.8189 0.632498Z\"\n fill=\"white\"\n stroke=\"#E5E7EB\"\n />\n <ellipse cx=\"80.0618\" cy=\"81\" rx=\"28.0342\" ry=\"28.0342\" fill=\"#EEF2FF\" />\n <path\n d=\"M99.2393 61.3061L99.2391 61.3058C88.498 50.5808 71.1092 50.5804 60.3835 61.3061C49.6423 72.0316 49.6422 89.4361 60.3832 100.162C71.109 110.903 88.4982 110.903 99.2393 100.162C109.965 89.4363 109.965 72.0317 99.2393 61.3061ZM105.863 54.6832C120.249 69.0695 120.249 92.3985 105.863 106.785C91.4605 121.171 68.1468 121.171 53.7446 106.785C39.3582 92.3987 39.3582 69.0693 53.7446 54.683C68.1468 40.2965 91.4605 40.2966 105.863 54.6832Z\"\n stroke=\"#E5E7EB\"\n />\n <path\n d=\"M110.782 119.267L102.016 110.492C104.888 108.267 107.476 105.651 109.564 102.955L118.329 111.729L110.782 119.267Z\"\n stroke=\"#E5E7EB\"\n />\n <path\n d=\"M139.122 125.781L139.122 125.78L123.313 109.988C123.313 109.987 123.313 109.987 123.312 109.986C121.996 108.653 119.849 108.657 118.521 109.985L118.871 110.335L118.521 109.985L109.047 119.459C107.731 120.775 107.735 122.918 109.044 124.247L109.047 124.249L124.858 140.06C128.789 143.992 135.191 143.992 139.122 140.06C143.069 136.113 143.069 129.728 139.122 125.781Z\"\n fill=\"#A5B4FC\"\n stroke=\"#818CF8\"\n />\n <path\n d=\"M83.185 87.2285C82.5387 87.2285 82.0027 86.6926 82.0027 86.0305C82.0027 83.3821 77.9987 83.3821 77.9987 86.0305C77.9987 86.6926 77.4627 87.2285 76.8006 87.2285C76.1543 87.2285 75.6183 86.6926 75.6183 86.0305C75.6183 80.2294 84.3831 80.2451 84.3831 86.0305C84.3831 86.6926 83.8471 87.2285 83.185 87.2285Z\"\n fill=\"#4F46E5\"\n />\n <path\n d=\"M93.3528 77.0926H88.403C87.7409 77.0926 87.2049 76.5567 87.2049 75.8946C87.2049 75.2483 87.7409 74.7123 88.403 74.7123H93.3528C94.0149 74.7123 94.5509 75.2483 94.5509 75.8946C94.5509 76.5567 94.0149 77.0926 93.3528 77.0926Z\"\n fill=\"#4F46E5\"\n />\n <path\n d=\"M71.5987 77.0925H66.6488C65.9867 77.0925 65.4507 76.5565 65.4507 75.8945C65.4507 75.2481 65.9867 74.7122 66.6488 74.7122H71.5987C72.245 74.7122 72.781 75.2481 72.781 75.8945C72.781 76.5565 72.245 77.0925 71.5987 77.0925Z\"\n fill=\"#4F46E5\"\n />\n <rect x=\"38.3522\" y=\"21.5128\" width=\"41.0256\" height=\"2.73504\" rx=\"1.36752\" fill=\"#4F46E5\" />\n <rect x=\"38.3522\" y=\"133.65\" width=\"54.7009\" height=\"5.47009\" rx=\"2.73504\" fill=\"#A5B4FC\" />\n <rect x=\"38.3522\" y=\"29.7179\" width=\"13.6752\" height=\"2.73504\" rx=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"56.13\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"61.6001\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"67.0702\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n </svg>\n <div>\n <h2 class=\"ax-text-center ax-text-neutral-600 ax-font-semibold ax-leading-loose ax-pb-2\">\n There is no Comment!\n </h2>\n </div>\n </div>\n </div>\n }\n </ax-comment-container>\n <ax-form>\n <ax-form-field>\n <div>\n @if (isReplyingMode() || isEditingMode()) {\n <div\n class=\"ax-flex ax-justify-between ax-rounded-b-none ax-border ax-border-b-0 ax-rounded-lg ax-bg-on-surface ax-px-6 ax-py-3 ax-w-full ax-items-center ax-overflow-hidden ax-text-sm ax-leading-none\"\n >\n <div (click)=\"scrollMain()\" class=\"ax-flex ax-justify-start ax-items-center ax-cursor-pointer\">\n <i\n [class]=\"isReplyingMode() ? 'fa-reply' : 'fa-pen'\"\n class=\"fa-solid ax-text-primary-500 dark:ax-text-primary-300 ax-text-2xl ax-me-4\"\n ></i>\n <div\n class=\"ax-flex ax-flex-col ax-gap-2 ax-justify-between ax-align-middle ax-leading-4 ax-overflow-hidden\"\n >\n <p class=\"ax-text-primary-500 dark:ax-text-primary-300\">\n {{ isReplyingMode() ? 'Reply to ' : 'Edit Message' }}\n <span class=\"ax-font-bold\">\n {{ isReplyingMode() ? extractInitials(activeReplyComment()?.author) : '' }}\n </span>\n </p>\n <div\n class=\"ax-truncate\"\n [innerHTML]=\"\n isReplyingMode()\n ? sanitizeHtml(activeReplyComment()?.message?.content ?? '')\n : sanitizeHtml(activeEditComment()?.message?.content ?? '')\n \"\n ></div>\n </div>\n </div>\n <div><i (click)=\"resetReplyEditState()\" class=\"fa-solid ax-text-2xl fa-xmark ax-cursor-pointer\"></i></div>\n </div>\n }\n <ax-wysiwyg-container #w [look]=\"wysiwygOptions().look\" [(ngModel)]=\"commentContent\">\n <ax-wysiwyg-view class=\"ax-min-h-28\"></ax-wysiwyg-view>\n <ax-toolbar>\n <ax-content>\n <ax-wysiwyg-history></ax-wysiwyg-history>\n <ax-wysiwyg-font-style></ax-wysiwyg-font-style>\n <ax-wysiwyg-colors></ax-wysiwyg-colors>\n <ax-wysiwyg-list></ax-wysiwyg-list>\n <ax-wysiwyg-alignment></ax-wysiwyg-alignment>\n </ax-content>\n <ax-suffix>\n <ax-dropdown-button\n [disabled]=\"hasCooldown()\"\n type=\"submit\"\n color=\"primary\"\n mode=\"split\"\n text=\"Send\"\n (onClick)=\"submitComment()\"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n }\n <ax-button-item-list>\n <ax-button-item (click)=\"submitComment(true)\" text=\"Send Private ...\" name=\"private\" data=\"private\">\n <ax-prefix>\n <ax-icon icon=\"fa-regular fa-user-secret\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n </ax-suffix>\n </ax-toolbar>\n <ax-validation-rule rule=\"callback\" [options]=\"{ validate: validateContent }\"></ax-validation-rule>\n </ax-wysiwyg-container>\n </div>\n </ax-form-field>\n </ax-form>\n</div>\n", styles: ["ax-wysiwyg-container .ax-editor-container{border-top-left-radius:0!important;border-top-right-radius:0!important}ax-wysiwyg-container .ax-error-message{padding-left:.5rem}\n"], dependencies: [{ kind: "component", type: AXWysiwygContainerComponent, selector: "ax-wysiwyg-container", inputs: ["look", "placeHolder"], outputs: ["onValueChanged"] }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i2.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXConversationModule }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i13.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXCommentModule }, { kind: "component", type: i2$4.AXCommentViewComponent, selector: "ax-comment-view" }, { kind: "component", type: i2$4.AXCommentContainerComponent, selector: "ax-comment-container" }, { kind: "component", type: i2$4.AxCommentItemComponent, selector: "ax-comment-item", inputs: ["replyCount"] }, { kind: "component", type: i2$4.AXCommentLikeComponent, selector: "ax-comment-like", inputs: ["liked"], outputs: ["likedChange", "onLiked"] }, { kind: "component", type: i2$4.AXMenuOptionsComponent, selector: "ax-comment-menu-options" }, { kind: "component", type: i2$4.AXCommentReplyTextComponent, selector: "ax-comment-reply-text" }, { kind: "component", type: i2$4.AXCommentDateComponent, selector: "ax-comment-date" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i6$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: "component", type: i6$1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i6$1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i1.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i5$1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i11$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.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: AXWysiwygModule }, { kind: "component", type: i8.AXWysiwygViewComponent, selector: "ax-wysiwyg-view", inputs: ["class"] }, { kind: "component", type: i8.AXWysiwygAlignmentComponent, selector: "ax-wysiwyg-alignment" }, { kind: "component", type: i8.AXWysiwygColorsComponent, selector: "ax-wysiwyg-colors" }, { kind: "component", type: i8.AXWysiwygFontStyleComponent, selector: "ax-wysiwyg-font-style" }, { kind: "component", type: i8.AXWysiwygHistoryComponent, selector: "ax-wysiwyg-history" }, { kind: "component", type: i8.AXWysiwygListComponent, selector: "ax-wysiwyg-list" }, { kind: "ngmodule", type: AXToolBarModule }, { kind: "component", type: i12.AXToolBarComponent, selector: "ax-toolbar" }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i10$1.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "color", "look", "text", "type", "mode"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i9.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i9.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "directive", type: i9.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "pipe", type: i15.AXFormatPipe, name: "format" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2752
+ }
2753
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMCommentWidgetViewComponent, decorators: [{
2754
+ type: Component,
2755
+ args: [{ selector: 'axm-comment-widget-view', imports: [
2756
+ AXWysiwygContainerComponent,
2757
+ AXAvatarModule,
2758
+ AXConversationModule,
2759
+ AXSkeletonModule,
2760
+ AXCommentModule,
2761
+ AXButtonModule,
2762
+ AXImageModule,
2763
+ AXLoadingModule,
2764
+ AXDropdownModule,
2765
+ AXDecoratorModule,
2766
+ AXWysiwygModule,
2767
+ AXToolBarModule,
2768
+ AXDropdownModule,
2769
+ AXDropdownButtonModule,
2770
+ AXValidationModule,
2771
+ AsyncPipe,
2772
+ AXFormModule,
2773
+ FormsModule,
2774
+ AXFormatModule,
2775
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-mt-2 ax-p-2\">\n <ax-comment-container>\n @if (isLoading()) {\n <div class=\"ax-flex ax-items-center ax-py-12 ax-bg-lightest ax-px-5\">\n <ax-skeleton class=\"ax-min-w-16 ax-h-16 ax-rounded-full ax-me-4\"></ax-skeleton>\n <div class=\"ax-flex ax-flex-col ax-gap-2 ax-w-full\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-2 ax-rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-2 ax-rounded-full\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-8/12 ax-h-2 ax-rounded-full\"></ax-skeleton>\n </div>\n </div>\n } @else if (!isLoading() && comments().length > 0) {\n <ax-comment-view class=\"ax-bg-lightest\">\n @for (comment of comments(); track comment.id) {\n <ax-comment-item [id]=\"comment.id!\" [replyCount]=\"comment.replies?.length ?? 0\">\n <ax-avatar [color]=\"avatarConfig().color\" [shape]=\"avatarConfig().look\">\n @if (checkImageExists(comment.id!) && comment.author && extractInitials(comment.author) !== '?') {\n <ax-image (onError)=\"handleImageError(comment.id!)\" [src]=\"''\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-overflow-hidden\">{{ extractInitials(comment.author) }}</span>\n </ax-text>\n }\n </ax-avatar>\n <ax-title>{{ extractInitials(comment.author) }}</ax-title>\n <ax-comment-date>{{ calcDefrenetTime(comment.createdAt) | format: 'timeleft' | async }} </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button class=\"ax-sm\" look=\"blank\" color=\"neutral\">\n <ax-icon icon=\"ax-icon ax-icon-solid ax-icon-more-horizontal\"></ax-icon>\n </ax-button>\n\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item text=\"Edit\" color=\"neutral\" (click)=\"editMessage(comment)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-edit\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n\n <ax-button-item text=\"Delete\" color=\"danger\" (click)=\"deleteComment(comment)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content [innerHTML]=\"sanitizeHtml(comment.message.content)\"></ax-content>\n <ax-comment-like (click)=\"toggleLike(comment)\" [liked]=\"comment.isLiked!\">\n {{ comment.reactionsCount }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"replyMessage(comment)\"></ax-comment-reply-text>\n @for (reply of comment.replies; track reply.id) {\n <ax-comment-item [id]=\"reply.id\">\n <ax-avatar [color]=\"avatarConfig().color\" [shape]=\"avatarConfig().look\">\n @if (reply && checkImageExists(reply.id!) && reply.author && extractInitials(reply.author) !== '?') {\n <ax-image (onError)=\"handleImageError(reply.id!)\" [src]=\"''\">\n <ax-loading></ax-loading>\n </ax-image>\n } @else {\n <ax-text>\n <span class=\"ax-text-base ax-overflow-hidden\">{{ extractInitials(reply.author) }}</span>\n </ax-text>\n }\n </ax-avatar>\n <ax-title>{{ extractInitials(reply.author) }}</ax-title>\n <ax-comment-date>{{ calcDefrenetTime(reply.createdAt) | format: 'timeleft' | async }} </ax-comment-date>\n <ax-comment-menu-options>\n <ax-button class=\"ax-sm\" look=\"blank\" color=\"neutral\">\n <ax-icon icon=\"ax-icon ax-icon-solid ax-icon-more-horizontal\"></ax-icon>\n </ax-button>\n\n <ax-dropdown-panel>\n <ax-button-item-list>\n <ax-button-item text=\"Edit\" color=\"neutral\" (click)=\"editMessage(comment, reply)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-edit\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-button-item text=\"Delete\" color=\"danger\" (click)=\"deleteReply(comment, reply)\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-comment-menu-options>\n <ax-content [innerHTML]=\"sanitizeHtml(reply.message.content)\"></ax-content>\n <ax-comment-like (click)=\"toggleLike(comment, reply)\" [liked]=\"reply.isLiked!\">\n {{ reply.reactionsCount }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"replyMessage(comment, reply)\"></ax-comment-reply-text>\n </ax-comment-item>\n }\n </ax-comment-item>\n }\n </ax-comment-view>\n } @else {\n <div>\n <div class=\"ax-flex ax-flex-col ax-gap-4 ax-justify-center ax-items-center ax-p-10\">\n <svg\n class=\"ax-mx-auto\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"154\"\n height=\"161\"\n viewBox=\"0 0 154 161\"\n fill=\"none\"\n >\n <path\n d=\"M0.0616455 84.4268C0.0616455 42.0213 34.435 7.83765 76.6507 7.83765C118.803 7.83765 153.224 42.0055 153.224 84.4268C153.224 102.42 147.026 118.974 136.622 132.034C122.282 150.138 100.367 161 76.6507 161C52.7759 161 30.9882 150.059 16.6633 132.034C6.25961 118.974 0.0616455 102.42 0.0616455 84.4268Z\"\n fill=\"#EEF2FF\"\n />\n <path\n d=\"M96.8189 0.632498L96.8189 0.632384L96.8083 0.630954C96.2034 0.549581 95.5931 0.5 94.9787 0.5H29.338C22.7112 0.5 17.3394 5.84455 17.3394 12.4473V142.715C17.3394 149.318 22.7112 154.662 29.338 154.662H123.948C130.591 154.662 135.946 149.317 135.946 142.715V38.9309C135.946 38.0244 135.847 37.1334 135.648 36.2586L135.648 36.2584C135.117 33.9309 133.874 31.7686 132.066 30.1333C132.066 30.1331 132.065 30.1329 132.065 30.1327L103.068 3.65203C103.068 3.6519 103.067 3.65177 103.067 3.65164C101.311 2.03526 99.1396 0.995552 96.8189 0.632498Z\"\n fill=\"white\"\n stroke=\"#E5E7EB\"\n />\n <ellipse cx=\"80.0618\" cy=\"81\" rx=\"28.0342\" ry=\"28.0342\" fill=\"#EEF2FF\" />\n <path\n d=\"M99.2393 61.3061L99.2391 61.3058C88.498 50.5808 71.1092 50.5804 60.3835 61.3061C49.6423 72.0316 49.6422 89.4361 60.3832 100.162C71.109 110.903 88.4982 110.903 99.2393 100.162C109.965 89.4363 109.965 72.0317 99.2393 61.3061ZM105.863 54.6832C120.249 69.0695 120.249 92.3985 105.863 106.785C91.4605 121.171 68.1468 121.171 53.7446 106.785C39.3582 92.3987 39.3582 69.0693 53.7446 54.683C68.1468 40.2965 91.4605 40.2966 105.863 54.6832Z\"\n stroke=\"#E5E7EB\"\n />\n <path\n d=\"M110.782 119.267L102.016 110.492C104.888 108.267 107.476 105.651 109.564 102.955L118.329 111.729L110.782 119.267Z\"\n stroke=\"#E5E7EB\"\n />\n <path\n d=\"M139.122 125.781L139.122 125.78L123.313 109.988C123.313 109.987 123.313 109.987 123.312 109.986C121.996 108.653 119.849 108.657 118.521 109.985L118.871 110.335L118.521 109.985L109.047 119.459C107.731 120.775 107.735 122.918 109.044 124.247L109.047 124.249L124.858 140.06C128.789 143.992 135.191 143.992 139.122 140.06C143.069 136.113 143.069 129.728 139.122 125.781Z\"\n fill=\"#A5B4FC\"\n stroke=\"#818CF8\"\n />\n <path\n d=\"M83.185 87.2285C82.5387 87.2285 82.0027 86.6926 82.0027 86.0305C82.0027 83.3821 77.9987 83.3821 77.9987 86.0305C77.9987 86.6926 77.4627 87.2285 76.8006 87.2285C76.1543 87.2285 75.6183 86.6926 75.6183 86.0305C75.6183 80.2294 84.3831 80.2451 84.3831 86.0305C84.3831 86.6926 83.8471 87.2285 83.185 87.2285Z\"\n fill=\"#4F46E5\"\n />\n <path\n d=\"M93.3528 77.0926H88.403C87.7409 77.0926 87.2049 76.5567 87.2049 75.8946C87.2049 75.2483 87.7409 74.7123 88.403 74.7123H93.3528C94.0149 74.7123 94.5509 75.2483 94.5509 75.8946C94.5509 76.5567 94.0149 77.0926 93.3528 77.0926Z\"\n fill=\"#4F46E5\"\n />\n <path\n d=\"M71.5987 77.0925H66.6488C65.9867 77.0925 65.4507 76.5565 65.4507 75.8945C65.4507 75.2481 65.9867 74.7122 66.6488 74.7122H71.5987C72.245 74.7122 72.781 75.2481 72.781 75.8945C72.781 76.5565 72.245 77.0925 71.5987 77.0925Z\"\n fill=\"#4F46E5\"\n />\n <rect x=\"38.3522\" y=\"21.5128\" width=\"41.0256\" height=\"2.73504\" rx=\"1.36752\" fill=\"#4F46E5\" />\n <rect x=\"38.3522\" y=\"133.65\" width=\"54.7009\" height=\"5.47009\" rx=\"2.73504\" fill=\"#A5B4FC\" />\n <rect x=\"38.3522\" y=\"29.7179\" width=\"13.6752\" height=\"2.73504\" rx=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"56.13\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"61.6001\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n <circle cx=\"67.0702\" cy=\"31.0854\" r=\"1.36752\" fill=\"#4F46E5\" />\n </svg>\n <div>\n <h2 class=\"ax-text-center ax-text-neutral-600 ax-font-semibold ax-leading-loose ax-pb-2\">\n There is no Comment!\n </h2>\n </div>\n </div>\n </div>\n }\n </ax-comment-container>\n <ax-form>\n <ax-form-field>\n <div>\n @if (isReplyingMode() || isEditingMode()) {\n <div\n class=\"ax-flex ax-justify-between ax-rounded-b-none ax-border ax-border-b-0 ax-rounded-lg ax-bg-on-surface ax-px-6 ax-py-3 ax-w-full ax-items-center ax-overflow-hidden ax-text-sm ax-leading-none\"\n >\n <div (click)=\"scrollMain()\" class=\"ax-flex ax-justify-start ax-items-center ax-cursor-pointer\">\n <i\n [class]=\"isReplyingMode() ? 'fa-reply' : 'fa-pen'\"\n class=\"fa-solid ax-text-primary-500 dark:ax-text-primary-300 ax-text-2xl ax-me-4\"\n ></i>\n <div\n class=\"ax-flex ax-flex-col ax-gap-2 ax-justify-between ax-align-middle ax-leading-4 ax-overflow-hidden\"\n >\n <p class=\"ax-text-primary-500 dark:ax-text-primary-300\">\n {{ isReplyingMode() ? 'Reply to ' : 'Edit Message' }}\n <span class=\"ax-font-bold\">\n {{ isReplyingMode() ? extractInitials(activeReplyComment()?.author) : '' }}\n </span>\n </p>\n <div\n class=\"ax-truncate\"\n [innerHTML]=\"\n isReplyingMode()\n ? sanitizeHtml(activeReplyComment()?.message?.content ?? '')\n : sanitizeHtml(activeEditComment()?.message?.content ?? '')\n \"\n ></div>\n </div>\n </div>\n <div><i (click)=\"resetReplyEditState()\" class=\"fa-solid ax-text-2xl fa-xmark ax-cursor-pointer\"></i></div>\n </div>\n }\n <ax-wysiwyg-container #w [look]=\"wysiwygOptions().look\" [(ngModel)]=\"commentContent\">\n <ax-wysiwyg-view class=\"ax-min-h-28\"></ax-wysiwyg-view>\n <ax-toolbar>\n <ax-content>\n <ax-wysiwyg-history></ax-wysiwyg-history>\n <ax-wysiwyg-font-style></ax-wysiwyg-font-style>\n <ax-wysiwyg-colors></ax-wysiwyg-colors>\n <ax-wysiwyg-list></ax-wysiwyg-list>\n <ax-wysiwyg-alignment></ax-wysiwyg-alignment>\n </ax-content>\n <ax-suffix>\n <ax-dropdown-button\n [disabled]=\"hasCooldown()\"\n type=\"submit\"\n color=\"primary\"\n mode=\"split\"\n text=\"Send\"\n (onClick)=\"submitComment()\"\n >\n @if (isSubmitting()) {\n <ax-loading></ax-loading>\n }\n <ax-button-item-list>\n <ax-button-item (click)=\"submitComment(true)\" text=\"Send Private ...\" name=\"private\" data=\"private\">\n <ax-prefix>\n <ax-icon icon=\"fa-regular fa-user-secret\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n </ax-suffix>\n </ax-toolbar>\n <ax-validation-rule rule=\"callback\" [options]=\"{ validate: validateContent }\"></ax-validation-rule>\n </ax-wysiwyg-container>\n </div>\n </ax-form-field>\n </ax-form>\n</div>\n", styles: ["ax-wysiwyg-container .ax-editor-container{border-top-left-radius:0!important;border-top-right-radius:0!important}ax-wysiwyg-container .ax-error-message{padding-left:.5rem}\n"] }]
2776
+ }] });
2777
+
2778
+ var commentWidgetView_component = /*#__PURE__*/Object.freeze({
2779
+ __proto__: null,
2780
+ AXMCommentWidgetViewComponent: AXMCommentWidgetViewComponent
2781
+ });
2782
+
2783
+ const AXPCommentWidget = {
2784
+ name: 'comment',
2785
+ title: 'Comments',
2786
+ description: 'Display and manage comments for entities',
2787
+ type: 'view',
2788
+ categories: [],
2789
+ groups: [AXPWidgetGroupEnum.FormElement],
2790
+ icon: 'fa-solid fa-comments',
2791
+ properties: [],
2792
+ components: {
2793
+ view: {
2794
+ component: () => Promise.resolve().then(function () { return commentWidgetView_component; }).then((c) => c.AXMCommentWidgetViewComponent),
2795
+ },
2796
+ },
2797
+ };
2798
+
2338
2799
  const routes = [
2339
2800
  {
2340
2801
  path: 'platform',
@@ -2351,7 +2812,7 @@ const routes = [
2351
2812
  ],
2352
2813
  },
2353
2814
  {
2354
- path: 'comments',
2815
+ path: 'comments/m/:module/e/:id',
2355
2816
  component: AXMCommentListViewComponent,
2356
2817
  },
2357
2818
  ],
@@ -2570,5 +3031,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
2570
3031
  * Generated bundle index. Do not edit.
2571
3032
  */
2572
3033
 
2573
- export { AXMChatComponent, AXMChatItemComponent, AXMChatPreviewComponent, AXMChatService, AXMChatServiceImpl, AXMCommentListViewComponent, AXMCommentLookupPopup, AXMCommentService, AXMCommentServiceImpl, AXMConversationModule, AXMMessageService, AXMMessageServiceImpl, AXMRoomService, AXMRoomServiceImpl, RootConfig, messageFactory, roomFactory };
3034
+ export { AXMChatComponent, AXMChatItemComponent, AXMChatPreviewComponent, AXMChatService, AXMChatServiceImpl, AXMCommentListViewComponent, AXMCommentLookupPopup, AXMCommentService, AXMCommentServiceImpl, AXMCommentWidgetViewComponent, AXMConversationModule, AXMMessageService, AXMMessageServiceImpl, AXMRoomService, AXMRoomServiceImpl, AXPCommentWidget, RootConfig, messageFactory, roomFactory };
2574
3035
  //# sourceMappingURL=acorex-modules-conversation.mjs.map