@memberjunction/ng-explorer-core 6.2.0-edge.0 → 6.2.0-edge.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-routing.module.d.ts +23 -1
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +50 -14
- package/dist/app-routing.module.js.map +1 -1
- package/dist/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +12 -1
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/command-palette/command-palette.component.d.ts +7 -1
- package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
- package/dist/lib/command-palette/command-palette.component.js +28 -14
- package/dist/lib/command-palette/command-palette.component.js.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.d.ts +103 -13
- package/dist/lib/conversation-feedback/conversation-feedback.d.ts.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.js +219 -67
- package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts +64 -10
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +172 -66
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/generic/resource-container-component.d.ts +19 -5
- package/dist/lib/generic/resource-container-component.d.ts.map +1 -1
- package/dist/lib/generic/resource-container-component.js +43 -13
- package/dist/lib/generic/resource-container-component.js.map +1 -1
- package/dist/lib/guards/entities.guard.d.ts +4 -0
- package/dist/lib/guards/entities.guard.d.ts.map +1 -1
- package/dist/lib/guards/entities.guard.js +10 -2
- package/dist/lib/guards/entities.guard.js.map +1 -1
- package/dist/lib/identity-claims/claim-redeem.component.d.ts +4 -0
- package/dist/lib/identity-claims/claim-redeem.component.d.ts.map +1 -1
- package/dist/lib/identity-claims/claim-redeem.component.js +10 -2
- package/dist/lib/identity-claims/claim-redeem.component.js.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts +4 -0
- package/dist/lib/oauth/oauth-callback.component.d.ts.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.js +10 -2
- package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
- package/dist/lib/profile/profile-dialog.component.d.ts.map +1 -1
- package/dist/lib/profile/profile-dialog.component.js +194 -191
- package/dist/lib/profile/profile-dialog.component.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +20 -2
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.js +33 -9
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +80 -10
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +168 -56
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +199 -25
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +534 -182
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts +2 -0
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.js +5 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-search-routing.d.ts +25 -0
- package/dist/lib/resource-wrappers/chat-search-routing.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/chat-search-routing.js +24 -0
- package/dist/lib/resource-wrappers/chat-search-routing.js.map +1 -0
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +14 -2
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +32 -8
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts +46 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js +62 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js.map +1 -0
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +54 -8
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +138 -46
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts +223 -30
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js +438 -118
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +7 -3
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +23 -15
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +74 -11
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +214 -68
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/services/server-connectivity.service.d.ts +9 -4
- package/dist/lib/services/server-connectivity.service.d.ts.map +1 -1
- package/dist/lib/services/server-connectivity.service.js +56 -12
- package/dist/lib/services/server-connectivity.service.js.map +1 -1
- package/dist/lib/services/startup-validation.service.d.ts +4 -0
- package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
- package/dist/lib/services/startup-validation.service.js +10 -2
- package/dist/lib/services/startup-validation.service.js.map +1 -1
- package/dist/lib/services/system-validation.service.d.ts +13 -1
- package/dist/lib/services/system-validation.service.d.ts.map +1 -1
- package/dist/lib/services/system-validation.service.js +29 -5
- package/dist/lib/services/system-validation.service.js.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts +54 -4
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +130 -40
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts +29 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.js +56 -12
- package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.d.ts +33 -5
- package/dist/lib/shell/components/header/app-switcher.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.js +85 -29
- package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
- package/dist/lib/shell/components/record-open/record-origin-crumb.component.js +1 -1
- package/dist/lib/shell/components/record-open/record-origin-crumb.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +50 -6
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.js +95 -22
- package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +91 -9
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +257 -101
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/loading-themes.d.ts +16 -12
- package/dist/lib/shell/loading-themes.d.ts.map +1 -1
- package/dist/lib/shell/loading-themes.js +145 -137
- package/dist/lib/shell/loading-themes.js.map +1 -1
- package/dist/lib/shell/readiness-beacon.d.ts +2 -0
- package/dist/lib/shell/readiness-beacon.d.ts.map +1 -1
- package/dist/lib/shell/readiness-beacon.js +5 -1
- package/dist/lib/shell/readiness-beacon.js.map +1 -1
- package/dist/lib/shell/services/about-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/about-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/about-dialog.service.js +16 -4
- package/dist/lib/shell/services/about-dialog.service.js.map +1 -1
- package/dist/lib/shell/services/profile-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/profile-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/profile-dialog.service.js +16 -4
- package/dist/lib/shell/services/profile-dialog.service.js.map +1 -1
- package/dist/lib/shell/services/user-sharing-center-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/user-sharing-center-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/user-sharing-center-dialog.service.js +15 -3
- package/dist/lib/shell/services/user-sharing-center-dialog.service.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +264 -39
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +697 -294
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +64 -8
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +129 -37
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.d.ts +26 -2
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +48 -10
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts +84 -6
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +133 -29
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts +173 -23
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +383 -109
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +383 -55
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +962 -326
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-query/single-query.component.d.ts +22 -2
- package/dist/lib/single-query/single-query.component.d.ts.map +1 -1
- package/dist/lib/single-query/single-query.component.js +40 -10
- package/dist/lib/single-query/single-query.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +41 -3
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +71 -11
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts +23 -3
- package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +42 -12
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/system-validation/system-validation-banner.component.d.ts +12 -2
- package/dist/lib/system-validation/system-validation-banner.component.d.ts.map +1 -1
- package/dist/lib/system-validation/system-validation-banner.component.js +25 -5
- package/dist/lib/system-validation/system-validation-banner.component.js.map +1 -1
- package/dist/lib/user-menu/user-menu.types.d.ts +4 -0
- package/dist/lib/user-menu/user-menu.types.d.ts.map +1 -1
- package/dist/lib/user-menu/user-menu.types.js +10 -2
- package/dist/lib/user-menu/user-menu.types.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +59 -7
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +151 -47
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.d.ts +3 -2
- package/dist/lib/user-profile/user-profile.component.d.ts.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +5 -4
- package/dist/lib/user-profile/user-profile.component.js.map +1 -1
- package/package.json +52 -52
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-notifications.component.js","sourceRoot":"","sources":["../../../src/lib/user-notifications/user-notifications.component.ts","../../../src/lib/user-notifications/user-notifications.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, OnDestroy, OnInit, AfterViewInit, inject } from '@angular/core';\nimport { SharedService, NavigationService } from '@memberjunction/ng-shared';\nimport { MJUserNotificationEntity, MJUserNotificationTypeEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { CompositeKey, TransactionGroupBase } from '@memberjunction/core';\nimport { SafeJSONParse, UUIDsEqual } from '@memberjunction/global';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { ApplicationManager } from '@memberjunction/ng-base-application';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n/**\n * Radio button filter options for notification read status\n */\ntype ReadFilterOption = 'All' | 'Unread' | 'Read';\n\n/** How a notification's Message should be rendered. */\ntype MessageKind = 'html' | 'markdown' | 'text';\n\n/**\n * Render-ready view model for one notification. Built once per data/filter change\n * (never inside template bindings): the Message is classified (full HTML document /\n * HTML fragment / Markdown / plain text), reduced to a sanitary body + plain-text\n * preview, and the time-relative label is SNAPSHOT here — computing relative time in\n * the template throws NG0100 at minute boundaries.\n */\ninterface NotificationVM {\n N: MJUserNotificationEntity;\n Kind: MessageKind;\n /** Rich body: extracted+stripped HTML fragment (html) or the raw message (markdown). Empty for plain text. */\n Body: string;\n /** Plain-text excerpt for the collapsed card. */\n Preview: string;\n /** True when there is more to see than the collapsed preview. */\n Expandable: boolean;\n /** Snapshot \"2h ago\" label (refreshed on a timer, never computed in the template). */\n Relative: string;\n Clickable: boolean;\n}\n\n/** One day-bucket of notifications (\"Today\", \"Yesterday\", ...). */\ninterface NotificationGroup {\n Key: string;\n Label: string;\n Items: NotificationVM[];\n}\n\n/**\n * Configuration for record-type resource navigation\n */\ninterface RecordResourceConfig {\n Entity?: string;\n}\n\n/**\n * Configuration for conversation-type resource navigation\n */\ninterface ConversationResourceConfig {\n type: 'conversation';\n conversationId?: string;\n messageId?: string;\n artifactId?: string;\n versionNumber?: string;\n taskId?: string;\n}\n\n/**\n * Configuration for agent-request-type resource navigation\n */\ninterface AgentRequestResourceConfig {\n type: 'agent-request';\n requestId: string;\n}\n\n/**\n * Result of parsing a notification URL\n */\ninterface NotificationUrlInfo {\n urlParts: string[];\n queryString: string;\n}\n\n/** Collapsed-preview cap (characters of plain text). */\nconst PREVIEW_MAX_CHARS = 240;\n\n/** How often the snapshot relative-time labels refresh. */\nconst RELATIVE_REFRESH_MS = 60_000;\n\n@Component({\n standalone: false,\n selector: 'app-user-notifications',\n templateUrl: './user-notifications.component.html',\n styleUrls: ['./user-notifications.component.css']\n})\nexport class UserNotificationsComponent extends BaseAngularComponent implements OnInit, AfterViewInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n public radioSelected: ReadFilterOption = 'All';\n public currentFilter: string = '';\n public notificationTypes: MJUserNotificationTypeEntity[] = [];\n public selectedTypeFilter: string | null = null;\n public loadingTypes: boolean = true;\n\n /** IDs of cards currently expanded to their full rendered content. */\n public Expanded = new Set<string>();\n\n private groups: NotificationGroup[] = [];\n private groupsKey = '';\n private vmCache = new Map<string, NotificationVM>();\n private relativeTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor (\n public sharedService: SharedService,\n private navigationService: NavigationService,\n private appManager: ApplicationManager\n ) {\n super();\n }\n\n async ngOnInit() {\n this.loadNotificationTypes();\n // Refresh the snapshot relative-time labels between change-detection passes.\n this.relativeTimer = setInterval(() => {\n for (const vm of this.vmCache.values()) {\n vm.Relative = this.relativeTime(vm.N.__mj_CreatedAt);\n }\n this.groupsKey = ''; // day buckets can shift at midnight\n this.cdr.markForCheck();\n }, RELATIVE_REFRESH_MS);\n }\n\n ngAfterViewInit(): void {\n this.sharedService.InvokeManualResize(); // make sure the notifications component is sized correctly\n }\n\n ngOnDestroy(): void {\n if (this.relativeTimer != null) {\n clearInterval(this.relativeTimer);\n }\n }\n\n private loadNotificationTypes() {\n // Get notification types from UserInfoEngine cache, sorted client-side\n // UserInfoEngine is auto-configured via @RegisterForStartup()\n this.notificationTypes = [...UserInfoEngine.Instance.NotificationTypes].sort((a, b) => {\n const priorityA = a.Priority ?? 999;\n const priorityB = b.Priority ?? 999;\n if (priorityA !== priorityB) {\n return priorityA - priorityB;\n }\n return a.Name.localeCompare(b.Name);\n });\n this.loadingTypes = false;\n }\n\n // ========================================================================\n // Data shaping (filter → view models → day groups)\n // ========================================================================\n\n public get NotificationsToShow(): MJUserNotificationEntity[] {\n let temp: MJUserNotificationEntity[] = [];\n switch (this.radioSelected) {\n case 'All':\n temp = this.AllNotifications;\n break;\n case 'Unread':\n temp = this.AllNotifications.filter(n => n.Unread);\n break;\n case 'Read':\n temp = this.AllNotifications.filter(n => !n.Unread);\n break;\n }\n\n // Apply type filter if selected\n if (this.selectedTypeFilter) {\n temp = temp.filter(n => UUIDsEqual(n.NotificationTypeID, this.selectedTypeFilter));\n }\n\n // Apply text filter if it is not empty\n if (this.currentFilter.trim().length > 0) {\n // check for inclusion of filter value in title or message\n temp = temp.filter(n => n.Title?.toLowerCase().includes(this.currentFilter.trim().toLowerCase()) ||\n n.Message?.toLowerCase().includes(this.currentFilter.trim().toLowerCase())\n );\n }\n\n return temp;\n }\n\n /**\n * The filtered notifications as render-ready day groups. Memoized on a composite\n * key of the inputs so the getter stays cheap across change-detection passes and\n * the (time-sensitive) VM snapshots never rebuild mid-pass.\n */\n public get Groups(): NotificationGroup[] {\n const list = this.NotificationsToShow;\n const unread = list.filter(n => n.Unread).length;\n const key = `${list.length}|${unread}|${this.radioSelected}|${this.selectedTypeFilter}|${this.currentFilter}|${list[0]?.ID ?? ''}|${list[list.length - 1]?.ID ?? ''}`;\n if (key !== this.groupsKey) {\n this.groups = this.buildGroups(list);\n this.groupsKey = key;\n }\n return this.groups;\n }\n\n private buildGroups(list: MJUserNotificationEntity[]): NotificationGroup[] {\n const groups: NotificationGroup[] = [];\n let current: NotificationGroup | null = null;\n for (const n of list) {\n const label = this.dayLabel(n.__mj_CreatedAt);\n if (!current || current.Label !== label) {\n current = { Key: `${label}-${n.ID}`, Label: label, Items: [] };\n groups.push(current);\n }\n current.Items.push(this.vmFor(n));\n }\n return groups;\n }\n\n private vmFor(n: MJUserNotificationEntity): NotificationVM {\n const cached = this.vmCache.get(n.ID);\n if (cached) {\n cached.N = n;\n cached.Clickable = this.isNotificationClickable(n);\n return cached;\n }\n const { kind, body, preview, expandable } = this.classifyMessage(n.Message ?? '');\n const vm: NotificationVM = {\n N: n,\n Kind: kind,\n Body: body,\n Preview: preview,\n Expandable: expandable,\n Relative: this.relativeTime(n.__mj_CreatedAt),\n Clickable: this.isNotificationClickable(n),\n };\n this.vmCache.set(n.ID, vm);\n return vm;\n }\n\n /**\n * Classifies a notification Message for rendering:\n * - Full HTML documents (e.g. templated email bodies) and HTML fragments →\n * parsed with DOMParser, chrome elements (style/script/link/meta/title) removed,\n * and the body markup kept for a SANITIZED [innerHTML] binding (Angular's\n * default sanitizer strips scripts/event handlers on bind).\n * - Markdown-looking text → rendered through mj-markdown when expanded.\n * - Everything else → plain text.\n */\n private classifyMessage(message: string): { kind: MessageKind; body: string; preview: string; expandable: boolean } {\n const trimmed = (message ?? '').trim();\n const looksHtml = /^<!doctype\\s|^<html[\\s>]/i.test(trimmed) || /<\\/?[a-z][^>]*>/i.test(trimmed);\n if (looksHtml) {\n const doc = new DOMParser().parseFromString(trimmed, 'text/html');\n for (const el of Array.from(doc.querySelectorAll('style, script, link, meta, title'))) {\n el.remove();\n }\n const body = doc.body?.innerHTML?.trim() ?? '';\n const text = this.collapseWhitespace(doc.body?.textContent ?? '');\n return { kind: 'html', body, preview: this.excerpt(text), expandable: true };\n }\n const looksMarkdown = /(^|\\n)#{1,6}\\s|\\*\\*[^*]+\\*\\*|(^|\\n)\\s*[-*]\\s+|\\[[^\\]]+\\]\\([^)]+\\)|```/m.test(trimmed);\n const text = this.collapseWhitespace(trimmed);\n if (looksMarkdown) {\n return { kind: 'markdown', body: trimmed, preview: this.excerpt(this.stripMarkdown(text)), expandable: true };\n }\n return { kind: 'text', body: '', preview: text, expandable: text.length > PREVIEW_MAX_CHARS };\n }\n\n private collapseWhitespace(value: string): string {\n return value.replace(/\\s+/g, ' ').trim();\n }\n\n private excerpt(text: string): string {\n return text.length > PREVIEW_MAX_CHARS ? `${text.substring(0, PREVIEW_MAX_CHARS - 1)}…` : text;\n }\n\n /** Light de-noising of markdown syntax for the plain-text preview. */\n private stripMarkdown(text: string): string {\n return text\n .replace(/```[\\s\\S]*?```/g, ' ')\n .replace(/[#*_`>]+/g, '')\n .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, '$1')\n .replace(/\\s+/g, ' ')\n .trim();\n }\n\n /** Compact \"just now / 5m ago / 3h ago / 2d ago\" label. NEVER call from templates (NG0100) — snapshot only. */\n private relativeTime(value: Date | string | null | undefined): string {\n if (!value) {\n return '';\n }\n const ms = Date.now() - new Date(value).getTime();\n const minutes = Math.floor(ms / 60_000);\n if (minutes < 1) return 'just now';\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return days < 7 ? `${days}d ago` : '';\n }\n\n private dayLabel(value: Date | string | null | undefined): string {\n if (!value) {\n return 'Earlier';\n }\n const d = new Date(value);\n const now = new Date();\n const startOfDay = (x: Date) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();\n const diffDays = Math.round((startOfDay(now) - startOfDay(d)) / 86_400_000);\n if (diffDays <= 0) return 'Today';\n if (diffDays === 1) return 'Yesterday';\n if (diffDays < 7) return 'This Week';\n return 'Earlier';\n }\n\n // ========================================================================\n // Expand / collapse\n // ========================================================================\n\n public IsExpanded(vm: NotificationVM): boolean {\n return this.Expanded.has(vm.N.ID);\n }\n\n public ToggleExpanded(vm: NotificationVM, event: Event): void {\n event.stopPropagation();\n if (this.Expanded.has(vm.N.ID)) {\n this.Expanded.delete(vm.N.ID);\n } else {\n this.Expanded.add(vm.N.ID);\n // Reading the full content is reading — mark it as such.\n if (vm.N.Unread) {\n void this.markAsRead(vm.N, true, null);\n }\n }\n this.cdr.markForCheck();\n }\n\n // ========================================================================\n // Clickability + navigation (unchanged behavior)\n // ========================================================================\n\n public isNotificationClickable(notification: MJUserNotificationEntity): boolean {\n // Check for special types navigated via NavigationService (not a URL)\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'agent-request' && config.requestId) {\n return true;\n }\n const typeName = SafeJSONParse<{ type?: string }>(notification.ResourceConfiguration)?.type?.trim().toLowerCase();\n if (typeName === 'meet-room') {\n return true;\n }\n }\n\n const info = this.notificationUrl(notification);\n return (info !== null && info.urlParts && info.urlParts.length > 0);\n }\n\n public notificationUrl(notification: MJUserNotificationEntity): NotificationUrlInfo {\n const url: string[] = [];\n let queryString = '';\n if (notification.ResourceRecordID && notification.ResourceRecordID.length > 0 &&\n notification.ResourceTypeID && notification.ResourceTypeID.length > 0) {\n // we have a resource here, like a Report, Dashboard, etc\n // we can generate a url to navigate to it\n const rt = this.sharedService.ResourceTypeByID(notification.ResourceTypeID);\n let routeSegment: string | null | undefined;\n if (rt)\n routeSegment = this.sharedService.mapResourceTypeNameToRouteSegment(rt.Name);\n\n if (rt && routeSegment && routeSegment.trim().length > 0) {\n url.push('resource');\n url.push(routeSegment);\n url.push(notification.ResourceRecordID.toString());\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n if (rt.Name.trim().toLowerCase() === 'records') {\n // special handling for records\n const config = SafeJSONParse<RecordResourceConfig>(notification.ResourceConfiguration);\n if (config && config.Entity)\n queryString = `Entity=${config.Entity}`;\n }\n else\n queryString = notification.ResourceConfiguration;\n }\n }\n }\n else if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n // we do NOT have a resource type or resource record id, but we do have a ResourceConfiguration\n // string, which means we might have information on how to navigate to what we want if we parse the config\n // HOME screen stuff is done this way\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'conversation') {\n url.push('chat');\n // Build query string with conversation and artifact navigation\n const queryParams: string[] = [];\n if (config.conversationId) queryParams.push(`conversationId=${config.conversationId}`);\n if (config.messageId) queryParams.push(`messageId=${config.messageId}`);\n if (config.artifactId) queryParams.push(`artifactId=${config.artifactId}`);\n if (config.versionNumber) queryParams.push(`versionNumber=${config.versionNumber}`);\n if (config.taskId) queryParams.push(`taskId=${config.taskId}`);\n queryString = queryParams.join('&');\n }\n }\n\n return { urlParts: url, queryString };\n }\n\n public get AllNotifications(): MJUserNotificationEntity[] {\n return SharedService.UserNotifications;\n }\n\n public get UnreadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => n.Unread);\n }\n\n public get ReadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => !n.Unread);\n }\n\n selectReadOption(option: ReadFilterOption): void {\n this.radioSelected = option;\n }\n\n onFilterChanged(value: string): void {\n this.currentFilter = value;\n }\n\n async markAsRead(notification: MJUserNotificationEntity, bRead: boolean, transGroup: TransactionGroupBase | null): Promise<boolean> {\n if (notification) {\n const notificationId = notification.ID;\n notification.Unread = !bRead;\n let notificationEntity: MJUserNotificationEntity;\n if (notification instanceof MJUserNotificationEntity) {\n // the passed in param truly is a MJUserNotificationEntity or subclass, so just use it, saves a DB round trip\n notificationEntity = notification;\n }\n else {\n // the passed in param is just a plain object, so we need to load the entity\n const md = this.ProviderToUse;\n notificationEntity = await md.GetEntityObject<MJUserNotificationEntity>('MJ: User Notifications');\n await notificationEntity.Load(notificationId);\n notificationEntity.Unread = !bRead;\n }\n\n // part of a transaction group, if so, add it as that will defer the actual network traffic/save\n if (transGroup) {\n notificationEntity.TransactionGroup = transGroup;\n await notificationEntity.Save()\n return true;\n }\n else {\n // Save the notification (not part of transaction group)\n await notificationEntity.Save();\n // Update the observables so badge count refreshes immediately\n MJNotificationService.UpdateNotificationObservables();\n return true;\n }\n }\n else {\n return false;\n }\n }\n\n public async markAllAsRead() {\n await this.markAll(true);\n }\n\n public async markAllAsUnread() {\n await this.markAll(false);\n }\n\n public async markAll(bRead: boolean) {\n // Use transaction group for batching - all saves are queued and sent in one round-trip\n const md = this.ProviderToUse;\n const transGroup = await md.CreateTransactionGroup();\n\n // Queue all saves - no need to await individual saves since transaction group queues them\n for (const notification of this.AllNotifications) {\n if (notification.Unread && bRead || !notification.Unread && !bRead) {\n // Don't await - Save() with transaction group queues the operation immediately\n this.markAsRead(notification, bRead, transGroup);\n }\n }\n\n // Submit transaction group - this is where the actual network call happens\n if (!await transGroup.Submit())\n this.sharedService.CreateSimpleNotification('Unable to mark all notifications as read', 'error', 5000);\n else\n SharedService.RefreshUserNotifications();\n }\n\n notificationClicked(notification: MJUserNotificationEntity): void {\n if (this.isNotificationClickable(notification)) {\n // also mark this as read when we click it\n this.markAsRead(notification, true, null);\n\n // Check for special navigation types that use NavigationService (not router)\n if (this.navigateToAgentRequest(notification)) {\n return;\n }\n if (this.navigateToConversation(notification)) {\n return;\n }\n if (this.navigateToMeetRoom(notification)) {\n return;\n }\n\n this.navigateToResource(notification);\n }\n }\n\n /**\n * Opens the Meet app's Live Room in JOIN mode for a `meet-room` invite notification (the\n * `{ type:'meet-room', room }` ResourceConfiguration), mirroring {@link navigateToConversation}.\n * Returns `false` (not handled) when the config isn't a meet-room invite or the Meet app is absent.\n */\n private navigateToMeetRoom(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n const config = SafeJSONParse<{ type?: string; room?: string }>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'meet-room') {\n return false;\n }\n const meetApp = this.appManager.GetAppByName('Meet');\n if (!meetApp) {\n return false;\n }\n const navConfig: Record<string, string> = {};\n if (config.room) {\n navConfig['room'] = config.room;\n }\n this.navigationService.OpenNavItemByName('Live Room', navConfig, meetApp.ID);\n return true;\n }\n\n /**\n * Navigate to a resource-based notification using NavigationService methods.\n * Routes to the correct resource based on the notification's ResourceType.\n */\n private navigateToResource(notification: MJUserNotificationEntity): void {\n if (!notification.ResourceRecordID || !notification.ResourceTypeID) return;\n\n const rt = this.sharedService.ResourceTypeByID(notification.ResourceTypeID);\n if (!rt) return;\n\n const recordId = notification.ResourceRecordID.toString();\n const rtName = rt.Name.trim().toLowerCase();\n\n switch (rtName) {\n case 'records': {\n const config = SafeJSONParse<RecordResourceConfig>(notification.ResourceConfiguration || '');\n if (config?.Entity) {\n const key = new CompositeKey();\n key.SimpleLoadFromURLSegment(recordId);\n this.navigationService.OpenEntityRecord(config.Entity, key);\n }\n break;\n }\n case 'user views':\n case 'mj: user views':\n this.navigationService.OpenView(recordId, 'View');\n break;\n case 'dashboards':\n this.navigationService.OpenDashboard(recordId, 'Dashboard');\n break;\n default:\n console.warn(`[UserNotifications] Unhandled resource type for navigation: ${rt.Name}`);\n break;\n }\n }\n\n /**\n * Handle navigation to an agent request via NavigationService.\n * Returns true if the notification was an agent-request type and navigation was attempted.\n */\n private navigateToAgentRequest(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'agent-request' || !config.requestId) {\n return false;\n }\n\n // Try the AI app first (has dedicated Agent Requests nav item)\n const aiApp = this.appManager.GetAppByName('AI');\n if (aiApp) {\n this.navigationService.OpenNavItemByName(\n 'Agent Requests',\n { requestId: config.requestId },\n aiApp.ID\n );\n return true;\n }\n\n // Fallback: navigate to Chat app's Conversations with the request context\n const chatApp = this.appManager.GetAppByName('Chat');\n if (chatApp) {\n this.navigationService.OpenNavItemByName(\n 'Conversations',\n { requestId: config.requestId },\n chatApp.ID\n );\n return true;\n }\n\n return false;\n }\n\n /**\n * Handle navigation to a conversation via NavigationService.\n * Returns true if the notification was a conversation type and navigation was attempted.\n */\n private navigateToConversation(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'conversation') {\n return false;\n }\n\n const chatApp = this.appManager.GetAppByName('Chat');\n if (!chatApp) {\n return false;\n }\n\n const navConfig: Record<string, string> = {};\n if (config.conversationId) navConfig['conversationId'] = config.conversationId;\n if (config.messageId) navConfig['messageId'] = config.messageId;\n if (config.artifactId) navConfig['artifactId'] = config.artifactId;\n if (config.versionNumber) navConfig['versionNumber'] = config.versionNumber;\n if (config.taskId) navConfig['taskId'] = config.taskId;\n\n this.navigationService.OpenNavItemByName(\n 'Conversations',\n navConfig,\n chatApp.ID\n );\n return true;\n }\n\n public getNotificationType(typeId: string | null): MJUserNotificationTypeEntity | null {\n if (!typeId) return null;\n return this.notificationTypes.find(t => UUIDsEqual(t.ID, typeId)) || null;\n }\n\n public getTypeIcon(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type?.Icon || 'fa-bell';\n }\n\n public getTypeColor(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type?.Color || 'var(--mj-text-muted)';\n }\n\n public getTypeName(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type ? type.Name : 'Notification';\n }\n\n public onTypeFilterChange(typeId: string | null): void {\n this.selectedTypeFilter = typeId;\n }\n}\n","<div class=\"notifications-container\">\n <!-- Header Section -->\n <div class=\"notifications-header\">\n <div class=\"header-top\">\n <div class=\"header-title\">\n <div class=\"title-icon\">\n <i class=\"fa-solid fa-bell\"></i>\n </div>\n <div class=\"title-text\">\n <h1>Notifications</h1>\n @if (UnreadNotifications.length > 0) {\n <span class=\"title-subtitle\">{{UnreadNotifications.length}} unread</span>\n } @else if (AllNotifications.length > 0) {\n <span class=\"title-subtitle\">All caught up</span>\n }\n </div>\n </div>\n\n @if (AllNotifications.length > 0) {\n <div class=\"header-actions\">\n @if (UnreadNotifications.length > 0) {\n <button class=\"action-btn action-btn-ghost\"\n type=\"button\"\n (click)=\"markAllAsRead()\"\n aria-label=\"Mark all notifications as read\">\n <i class=\"fa-solid fa-check-double\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Read</span>\n </button>\n }\n @if (ReadNotifications.length > 0) {\n <button class=\"action-btn action-btn-secondary\"\n type=\"button\"\n (click)=\"markAllAsUnread()\"\n aria-label=\"Mark all notifications as unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Unread</span>\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Filters Section -->\n @if (AllNotifications.length > 0) {\n <div class=\"filters-section\">\n <div class=\"filters-slider\">\n <div class=\"slider-content\">\n <!-- Read-status pills -->\n <div class=\"header-stats\" role=\"group\" aria-label=\"Filter notifications by read status\">\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'All'\"\n (click)=\"selectReadOption('All')\"\n [attr.aria-pressed]=\"radioSelected === 'All'\"\n aria-label=\"Show all notifications\">\n <span class=\"stat-label\">All</span>\n <span class=\"stat-count\">{{AllNotifications.length}}</span>\n </button>\n\n @if (UnreadNotifications.length > 0 || ReadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Unread'\"\n [class.has-unread]=\"UnreadNotifications.length > 0\"\n (click)=\"selectReadOption('Unread')\"\n [attr.aria-pressed]=\"radioSelected === 'Unread'\"\n aria-label=\"Show unread notifications\">\n <span class=\"stat-label\">Unread</span>\n <span class=\"stat-count\" [class.unread-count]=\"UnreadNotifications.length > 0\">\n {{UnreadNotifications.length}}\n </span>\n </button>\n }\n\n @if (ReadNotifications.length > 0 || UnreadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Read'\"\n (click)=\"selectReadOption('Read')\"\n [attr.aria-pressed]=\"radioSelected === 'Read'\"\n aria-label=\"Show read notifications\">\n <span class=\"stat-label\">Read</span>\n <span class=\"stat-count\">{{ReadNotifications.length}}</span>\n </button>\n }\n </div>\n\n <!-- Type filter -->\n @if (notificationTypes.length > 0) {\n <div class=\"filter-item type-filter-slider\">\n <select class=\"type-select\"\n [(ngModel)]=\"selectedTypeFilter\"\n (change)=\"onTypeFilterChange(selectedTypeFilter)\"\n aria-label=\"Filter by notification type\">\n <option [value]=\"null\">All Types</option>\n @for (type of notificationTypes; track type.ID) {\n <option [value]=\"type.ID\">{{type.Name}}</option>\n }\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"search-section\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\" aria-hidden=\"true\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search notifications...\"\n [value]=\"currentFilter\"\n (input)=\"onFilterChanged($any($event.target).value)\"\n aria-label=\"Search notifications\" />\n </div>\n </div>\n\n @if (NotificationsToShow.length !== AllNotifications.length) {\n <div class=\"filter-info\">\n <span class=\"filter-badge\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n Showing {{NotificationsToShow.length}} of {{AllNotifications.length}}\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Notifications Content -->\n <div class=\"notifications-content\">\n @if (NotificationsToShow.length === 0 && AllNotifications.length === 0) {\n <mj-empty-state\n Variant=\"success\"\n Icon=\"fa-solid fa-bell-slash\"\n Title=\"No Notifications\"\n Message=\"You're all caught up! New notifications will appear here.\" />\n } @else if (NotificationsToShow.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-filter-circle-xmark\"\n Title=\"No Matching Notifications\"\n Message=\"Try adjusting your filters to see more notifications.\" />\n } @else {\n <!-- Day-grouped notification list -->\n <div class=\"notifications-list\">\n @for (group of Groups; track group.Key) {\n <div class=\"group-label\">{{group.Label}}</div>\n\n @for (vm of group.Items; track vm.N.ID) {\n <article class=\"notification-card\"\n [class.unread]=\"vm.N.Unread\"\n [class.expanded]=\"IsExpanded(vm)\"\n [class.clickable]=\"vm.Clickable\"\n role=\"article\"\n [attr.aria-label]=\"vm.N.Title\">\n\n <!-- Unread Indicator Bar -->\n <div class=\"card-indicator\" aria-hidden=\"true\"></div>\n\n <!-- Type Icon -->\n <div class=\"card-icon\" aria-hidden=\"true\">\n <i [class]=\"'fa-solid ' + getTypeIcon(vm.N)\"\n [style.color]=\"getTypeColor(vm.N)\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"card-content\" (click)=\"notificationClicked(vm.N)\">\n <div class=\"card-header\">\n <h3 class=\"card-title\" [class.card-title-unread]=\"vm.N.Unread\">\n {{vm.N.Title}}\n </h3>\n <span class=\"card-time\" [title]=\"(vm.N.__mj_CreatedAt | date:'medium') ?? ''\">\n @if (vm.Relative) {\n {{vm.Relative}}\n } @else {\n <time [attr.datetime]=\"vm.N.__mj_CreatedAt\">{{vm.N.__mj_CreatedAt | date:'MMM d, h:mm a'}}</time>\n }\n </span>\n </div>\n\n <div class=\"card-meta\">\n <span class=\"card-type\">{{getTypeName(vm.N)}}</span>\n @if (vm.Clickable) {\n <span class=\"card-open-hint\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i> Open\n </span>\n }\n </div>\n\n @if (!IsExpanded(vm)) {\n <p class=\"card-message\">{{vm.Preview}}</p>\n } @else {\n <div class=\"card-rich\" (click)=\"$event.stopPropagation()\">\n @switch (vm.Kind) {\n @case ('html') {\n <!-- Angular sanitizes on [innerHTML] bind; chrome tags were stripped at classification -->\n <div class=\"card-rich-html\" [innerHTML]=\"vm.Body\"></div>\n }\n @case ('markdown') {\n <mj-markdown class=\"card-rich-md\" [data]=\"vm.Body\" [enableMermaid]=\"false\"></mj-markdown>\n }\n @default {\n <p class=\"card-message card-message-full\">{{vm.N.Message}}</p>\n }\n }\n </div>\n }\n\n @if (vm.Expandable) {\n <button class=\"card-expand-btn\" type=\"button\"\n (click)=\"ToggleExpanded(vm, $event)\"\n [attr.aria-expanded]=\"IsExpanded(vm)\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsExpanded(vm)\" [class.fa-chevron-up]=\"IsExpanded(vm)\" aria-hidden=\"true\"></i>\n {{ IsExpanded(vm) ? 'Show less' : 'Show more' }}\n </button>\n }\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\">\n @if (vm.N.Unread) {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(vm.N, true, null)\"\n [attr.aria-label]=\"'Mark ' + vm.N.Title + ' as read'\"\n title=\"Mark as Read\">\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Read</span>\n </button>\n } @else {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(vm.N, false, null)\"\n [attr.aria-label]=\"'Mark ' + vm.N.Title + ' as unread'\"\n title=\"Mark as Unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Unread</span>\n </button>\n }\n </div>\n </article>\n }\n }\n </div>\n }\n </div>\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"user-notifications.component.js","sourceRoot":"","sources":["../../../src/lib/user-notifications/user-notifications.component.ts","../../../src/lib/user-notifications/user-notifications.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, OnDestroy, OnInit, AfterViewInit, inject } from '@angular/core';\nimport { SharedService, NavigationService } from '@memberjunction/ng-shared';\nimport { MJUserNotificationEntity, MJUserNotificationTypeEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { CompositeKey, TransactionGroupBase } from '@memberjunction/core';\nimport { SafeJSONParse, UUIDsEqual } from '@memberjunction/global';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { ApplicationManager } from '@memberjunction/ng-base-application';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n/**\n * Radio button filter options for notification read status\n */\ntype ReadFilterOption = 'All' | 'Unread' | 'Read';\n\n/** How a notification's Message should be rendered. */\ntype MessageKind = 'html' | 'markdown' | 'text';\n\n/**\n * Render-ready view model for one notification. Built once per data/filter change\n * (never inside template bindings): the Message is classified (full HTML document /\n * HTML fragment / Markdown / plain text), reduced to a sanitary body + plain-text\n * preview, and the time-relative label is SNAPSHOT here — computing relative time in\n * the template throws NG0100 at minute boundaries.\n */\ninterface NotificationVM {\n N: MJUserNotificationEntity;\n Kind: MessageKind;\n /** Rich body: extracted+stripped HTML fragment (html) or the raw message (markdown). Empty for plain text. */\n Body: string;\n /** Plain-text excerpt for the collapsed card. */\n Preview: string;\n /** True when there is more to see than the collapsed preview. */\n Expandable: boolean;\n /** Snapshot \"2h ago\" label (refreshed on a timer, never computed in the template). */\n Relative: string;\n Clickable: boolean;\n}\n\n/** One day-bucket of notifications (\"Today\", \"Yesterday\", ...). */\ninterface NotificationGroup {\n Key: string;\n Label: string;\n Items: NotificationVM[];\n}\n\n/**\n * Configuration for record-type resource navigation\n */\ninterface RecordResourceConfig {\n Entity?: string;\n}\n\n/**\n * Configuration for conversation-type resource navigation\n */\ninterface ConversationResourceConfig {\n type: 'conversation';\n conversationId?: string;\n messageId?: string;\n artifactId?: string;\n versionNumber?: string;\n taskId?: string;\n}\n\n/**\n * Configuration for agent-request-type resource navigation\n */\ninterface AgentRequestResourceConfig {\n type: 'agent-request';\n requestId: string;\n}\n\n/**\n * Result of parsing a notification URL\n */\ninterface NotificationUrlInfo {\n urlParts: string[];\n queryString: string;\n}\n\n/** Collapsed-preview cap (characters of plain text). */\nconst PREVIEW_MAX_CHARS = 240;\n\n/** How often the snapshot relative-time labels refresh. */\nconst RELATIVE_REFRESH_MS = 60_000;\n\n@Component({\n standalone: false,\n selector: 'app-user-notifications',\n templateUrl: './user-notifications.component.html',\n styleUrls: ['./user-notifications.component.css']\n})\nexport class UserNotificationsComponent extends BaseAngularComponent implements OnInit, AfterViewInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n\n public RadioSelected: ReadFilterOption = 'All';\n\n /** @deprecated Use {@link RadioSelected}. */\n public get radioSelected(): ReadFilterOption {\n return this.RadioSelected;\n }\n /** @deprecated Use {@link RadioSelected}. */\n public set radioSelected(value: ReadFilterOption) {\n this.RadioSelected = value;\n }\n public CurrentFilter: string = '';\n\n /** @deprecated Use {@link CurrentFilter}. */\n public get currentFilter(): string {\n return this.CurrentFilter;\n }\n /** @deprecated Use {@link CurrentFilter}. */\n public set currentFilter(value: string) {\n this.CurrentFilter = value;\n }\n public NotificationTypes: MJUserNotificationTypeEntity[] = [];\n\n /** @deprecated Use {@link NotificationTypes}. */\n public get notificationTypes(): MJUserNotificationTypeEntity[] {\n return this.NotificationTypes;\n }\n /** @deprecated Use {@link NotificationTypes}. */\n public set notificationTypes(value: MJUserNotificationTypeEntity[]) {\n this.NotificationTypes = value;\n }\n public SelectedTypeFilter: string | null = null;\n\n /** @deprecated Use {@link SelectedTypeFilter}. */\n public get selectedTypeFilter(): string | null {\n return this.SelectedTypeFilter;\n }\n /** @deprecated Use {@link SelectedTypeFilter}. */\n public set selectedTypeFilter(value: string | null) {\n this.SelectedTypeFilter = value;\n }\n public LoadingTypes: boolean = true;\n\n /** @deprecated Use {@link LoadingTypes}. */\n public get loadingTypes(): boolean {\n return this.LoadingTypes;\n }\n /** @deprecated Use {@link LoadingTypes}. */\n public set loadingTypes(value: boolean) {\n this.LoadingTypes = value;\n }\n\n /** IDs of cards currently expanded to their full rendered content. */\n public Expanded = new Set<string>();\n\n private groups: NotificationGroup[] = [];\n private groupsKey = '';\n private vmCache = new Map<string, NotificationVM>();\n private relativeTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor (\n public SharedService: SharedService,\n private navigationService: NavigationService,\n private appManager: ApplicationManager\n ) {\n super();\n }\n\n /** @deprecated Use {@link SharedService}. */\n public get sharedService(): SharedService {\n return this.SharedService;\n }\n /** @deprecated Use {@link SharedService}. */\n public set sharedService(value: SharedService) {\n this.SharedService = value;\n }\n\n async ngOnInit() {\n this.loadNotificationTypes();\n // Refresh the snapshot relative-time labels between change-detection passes.\n this.relativeTimer = setInterval(() => {\n for (const vm of this.vmCache.values()) {\n vm.Relative = this.relativeTime(vm.N.__mj_CreatedAt);\n }\n this.groupsKey = ''; // day buckets can shift at midnight\n this.cdr.markForCheck();\n }, RELATIVE_REFRESH_MS);\n }\n\n ngAfterViewInit(): void {\n this.SharedService.InvokeManualResize(); // make sure the notifications component is sized correctly\n }\n\n ngOnDestroy(): void {\n if (this.relativeTimer != null) {\n clearInterval(this.relativeTimer);\n }\n }\n\n private loadNotificationTypes() {\n // Get notification types from UserInfoEngine cache, sorted client-side\n // UserInfoEngine is auto-configured via @RegisterForStartup()\n this.NotificationTypes = [...UserInfoEngine.Instance.NotificationTypes].sort((a, b) => {\n const priorityA = a.Priority ?? 999;\n const priorityB = b.Priority ?? 999;\n if (priorityA !== priorityB) {\n return priorityA - priorityB;\n }\n return a.Name.localeCompare(b.Name);\n });\n this.LoadingTypes = false;\n }\n\n // ========================================================================\n // Data shaping (filter → view models → day groups)\n // ========================================================================\n\n public get NotificationsToShow(): MJUserNotificationEntity[] {\n let temp: MJUserNotificationEntity[] = [];\n switch (this.RadioSelected) {\n case 'All':\n temp = this.AllNotifications;\n break;\n case 'Unread':\n temp = this.AllNotifications.filter(n => n.Unread);\n break;\n case 'Read':\n temp = this.AllNotifications.filter(n => !n.Unread);\n break;\n }\n\n // Apply type filter if selected\n if (this.SelectedTypeFilter) {\n temp = temp.filter(n => UUIDsEqual(n.NotificationTypeID, this.SelectedTypeFilter));\n }\n\n // Apply text filter if it is not empty\n if (this.CurrentFilter.trim().length > 0) {\n // check for inclusion of filter value in title or message\n temp = temp.filter(n => n.Title?.toLowerCase().includes(this.CurrentFilter.trim().toLowerCase()) ||\n n.Message?.toLowerCase().includes(this.CurrentFilter.trim().toLowerCase())\n );\n }\n\n return temp;\n }\n\n /**\n * The filtered notifications as render-ready day groups. Memoized on a composite\n * key of the inputs so the getter stays cheap across change-detection passes and\n * the (time-sensitive) VM snapshots never rebuild mid-pass.\n */\n public get Groups(): NotificationGroup[] {\n const list = this.NotificationsToShow;\n const unread = list.filter(n => n.Unread).length;\n const key = `${list.length}|${unread}|${this.RadioSelected}|${this.SelectedTypeFilter}|${this.CurrentFilter}|${list[0]?.ID ?? ''}|${list[list.length - 1]?.ID ?? ''}`;\n if (key !== this.groupsKey) {\n this.groups = this.buildGroups(list);\n this.groupsKey = key;\n }\n return this.groups;\n }\n\n private buildGroups(list: MJUserNotificationEntity[]): NotificationGroup[] {\n const groups: NotificationGroup[] = [];\n let current: NotificationGroup | null = null;\n for (const n of list) {\n const label = this.dayLabel(n.__mj_CreatedAt);\n if (!current || current.Label !== label) {\n current = { Key: `${label}-${n.ID}`, Label: label, Items: [] };\n groups.push(current);\n }\n current.Items.push(this.vmFor(n));\n }\n return groups;\n }\n\n private vmFor(n: MJUserNotificationEntity): NotificationVM {\n const cached = this.vmCache.get(n.ID);\n if (cached) {\n cached.N = n;\n cached.Clickable = this.IsNotificationClickable(n);\n return cached;\n }\n const { kind, body, preview, expandable } = this.classifyMessage(n.Message ?? '');\n const vm: NotificationVM = {\n N: n,\n Kind: kind,\n Body: body,\n Preview: preview,\n Expandable: expandable,\n Relative: this.relativeTime(n.__mj_CreatedAt),\n Clickable: this.IsNotificationClickable(n),\n };\n this.vmCache.set(n.ID, vm);\n return vm;\n }\n\n /**\n * Classifies a notification Message for rendering:\n * - Full HTML documents (e.g. templated email bodies) and HTML fragments →\n * parsed with DOMParser, chrome elements (style/script/link/meta/title) removed,\n * and the body markup kept for a SANITIZED [innerHTML] binding (Angular's\n * default sanitizer strips scripts/event handlers on bind).\n * - Markdown-looking text → rendered through mj-markdown when expanded.\n * - Everything else → plain text.\n */\n private classifyMessage(message: string): { kind: MessageKind; body: string; preview: string; expandable: boolean } {\n const trimmed = (message ?? '').trim();\n const looksHtml = /^<!doctype\\s|^<html[\\s>]/i.test(trimmed) || /<\\/?[a-z][^>]*>/i.test(trimmed);\n if (looksHtml) {\n const doc = new DOMParser().parseFromString(trimmed, 'text/html');\n for (const el of Array.from(doc.querySelectorAll('style, script, link, meta, title'))) {\n el.remove();\n }\n const body = doc.body?.innerHTML?.trim() ?? '';\n const text = this.collapseWhitespace(doc.body?.textContent ?? '');\n return { kind: 'html', body, preview: this.excerpt(text), expandable: true };\n }\n const looksMarkdown = /(^|\\n)#{1,6}\\s|\\*\\*[^*]+\\*\\*|(^|\\n)\\s*[-*]\\s+|\\[[^\\]]+\\]\\([^)]+\\)|```/m.test(trimmed);\n const text = this.collapseWhitespace(trimmed);\n if (looksMarkdown) {\n return { kind: 'markdown', body: trimmed, preview: this.excerpt(this.stripMarkdown(text)), expandable: true };\n }\n return { kind: 'text', body: '', preview: text, expandable: text.length > PREVIEW_MAX_CHARS };\n }\n\n private collapseWhitespace(value: string): string {\n return value.replace(/\\s+/g, ' ').trim();\n }\n\n private excerpt(text: string): string {\n return text.length > PREVIEW_MAX_CHARS ? `${text.substring(0, PREVIEW_MAX_CHARS - 1)}…` : text;\n }\n\n /** Light de-noising of markdown syntax for the plain-text preview. */\n private stripMarkdown(text: string): string {\n return text\n .replace(/```[\\s\\S]*?```/g, ' ')\n .replace(/[#*_`>]+/g, '')\n .replace(/\\[([^\\]]+)\\]\\([^)]*\\)/g, '$1')\n .replace(/\\s+/g, ' ')\n .trim();\n }\n\n /** Compact \"just now / 5m ago / 3h ago / 2d ago\" label. NEVER call from templates (NG0100) — snapshot only. */\n private relativeTime(value: Date | string | null | undefined): string {\n if (!value) {\n return '';\n }\n const ms = Date.now() - new Date(value).getTime();\n const minutes = Math.floor(ms / 60_000);\n if (minutes < 1) return 'just now';\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return days < 7 ? `${days}d ago` : '';\n }\n\n private dayLabel(value: Date | string | null | undefined): string {\n if (!value) {\n return 'Earlier';\n }\n const d = new Date(value);\n const now = new Date();\n const startOfDay = (x: Date) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();\n const diffDays = Math.round((startOfDay(now) - startOfDay(d)) / 86_400_000);\n if (diffDays <= 0) return 'Today';\n if (diffDays === 1) return 'Yesterday';\n if (diffDays < 7) return 'This Week';\n return 'Earlier';\n }\n\n // ========================================================================\n // Expand / collapse\n // ========================================================================\n\n public IsExpanded(vm: NotificationVM): boolean {\n return this.Expanded.has(vm.N.ID);\n }\n\n public ToggleExpanded(vm: NotificationVM, event: Event): void {\n event.stopPropagation();\n if (this.Expanded.has(vm.N.ID)) {\n this.Expanded.delete(vm.N.ID);\n } else {\n this.Expanded.add(vm.N.ID);\n // Reading the full content is reading — mark it as such.\n if (vm.N.Unread) {\n void this.MarkAsRead(vm.N, true, null);\n }\n }\n this.cdr.markForCheck();\n }\n\n // ========================================================================\n // Clickability + navigation (unchanged behavior)\n // ========================================================================\n\n public IsNotificationClickable(notification: MJUserNotificationEntity): boolean {\n // Check for special types navigated via NavigationService (not a URL)\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'agent-request' && config.requestId) {\n return true;\n }\n const typeName = SafeJSONParse<{ type?: string }>(notification.ResourceConfiguration)?.type?.trim().toLowerCase();\n if (typeName === 'meet-room') {\n return true;\n }\n }\n\n const info = this.NotificationUrl(notification);\n return (info !== null && info.urlParts && info.urlParts.length > 0);\n }\n\n /** @deprecated Use {@link IsNotificationClickable}. */\n public isNotificationClickable(notification: MJUserNotificationEntity): boolean {\n return this.IsNotificationClickable(notification);\n }\n\n public NotificationUrl(notification: MJUserNotificationEntity): NotificationUrlInfo {\n const url: string[] = [];\n let queryString = '';\n if (notification.ResourceRecordID && notification.ResourceRecordID.length > 0 &&\n notification.ResourceTypeID && notification.ResourceTypeID.length > 0) {\n // we have a resource here, like a Report, Dashboard, etc\n // we can generate a url to navigate to it\n const rt = this.SharedService.ResourceTypeByID(notification.ResourceTypeID);\n let routeSegment: string | null | undefined;\n if (rt)\n routeSegment = this.SharedService.mapResourceTypeNameToRouteSegment(rt.Name);\n\n if (rt && routeSegment && routeSegment.trim().length > 0) {\n url.push('resource');\n url.push(routeSegment);\n url.push(notification.ResourceRecordID.toString());\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n if (rt.Name.trim().toLowerCase() === 'records') {\n // special handling for records\n const config = SafeJSONParse<RecordResourceConfig>(notification.ResourceConfiguration);\n if (config && config.Entity)\n queryString = `Entity=${config.Entity}`;\n }\n else\n queryString = notification.ResourceConfiguration;\n }\n }\n }\n else if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n // we do NOT have a resource type or resource record id, but we do have a ResourceConfiguration\n // string, which means we might have information on how to navigate to what we want if we parse the config\n // HOME screen stuff is done this way\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'conversation') {\n url.push('chat');\n // Build query string with conversation and artifact navigation\n const queryParams: string[] = [];\n if (config.conversationId) queryParams.push(`conversationId=${config.conversationId}`);\n if (config.messageId) queryParams.push(`messageId=${config.messageId}`);\n if (config.artifactId) queryParams.push(`artifactId=${config.artifactId}`);\n if (config.versionNumber) queryParams.push(`versionNumber=${config.versionNumber}`);\n if (config.taskId) queryParams.push(`taskId=${config.taskId}`);\n queryString = queryParams.join('&');\n }\n }\n\n return { urlParts: url, queryString };\n }\n\n /** @deprecated Use {@link NotificationUrl}. */\n public notificationUrl(notification: MJUserNotificationEntity): NotificationUrlInfo {\n return this.NotificationUrl(notification);\n }\n\n public get AllNotifications(): MJUserNotificationEntity[] {\n return SharedService.UserNotifications;\n }\n\n public get UnreadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => n.Unread);\n }\n\n public get ReadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => !n.Unread);\n }\n\n SelectReadOption(option: ReadFilterOption): void {\n this.RadioSelected = option;\n }\n\n /** @deprecated Use {@link SelectReadOption}. */\n selectReadOption(option: ReadFilterOption): void {\n return this.SelectReadOption(option);\n }\n\n OnFilterChanged(value: string): void {\n this.CurrentFilter = value;\n }\n\n /** @deprecated Use {@link OnFilterChanged}. */\n onFilterChanged(value: string): void {\n return this.OnFilterChanged(value);\n }\n\n async MarkAsRead(notification: MJUserNotificationEntity, bRead: boolean, transGroup: TransactionGroupBase | null): Promise<boolean> {\n if (notification) {\n const notificationId = notification.ID;\n notification.Unread = !bRead;\n let notificationEntity: MJUserNotificationEntity;\n if (notification instanceof MJUserNotificationEntity) {\n // the passed in param truly is a MJUserNotificationEntity or subclass, so just use it, saves a DB round trip\n notificationEntity = notification;\n }\n else {\n // the passed in param is just a plain object, so we need to load the entity\n const md = this.ProviderToUse;\n notificationEntity = await md.GetEntityObject<MJUserNotificationEntity>('MJ: User Notifications');\n await notificationEntity.Load(notificationId);\n notificationEntity.Unread = !bRead;\n }\n\n // part of a transaction group, if so, add it as that will defer the actual network traffic/save\n if (transGroup) {\n notificationEntity.TransactionGroup = transGroup;\n await notificationEntity.Save()\n return true;\n }\n else {\n // Save the notification (not part of transaction group)\n await notificationEntity.Save();\n // Update the observables so badge count refreshes immediately\n MJNotificationService.UpdateNotificationObservables();\n return true;\n }\n }\n else {\n return false;\n }\n }\n\n /** @deprecated Use {@link MarkAsRead}. */\n async markAsRead(notification: MJUserNotificationEntity, bRead: boolean, transGroup: TransactionGroupBase | null): Promise<boolean> {\n return this.MarkAsRead(notification, bRead, transGroup);\n }\n\n public async MarkAllAsRead() {\n await this.MarkAll(true);\n }\n\n /** @deprecated Use {@link MarkAllAsRead}. */\n public async markAllAsRead() {\n return this.MarkAllAsRead();\n }\n\n public async MarkAllAsUnread() {\n await this.MarkAll(false);\n }\n\n /** @deprecated Use {@link MarkAllAsUnread}. */\n public async markAllAsUnread() {\n return this.MarkAllAsUnread();\n }\n\n public async MarkAll(bRead: boolean) {\n // Use transaction group for batching - all saves are queued and sent in one round-trip\n const md = this.ProviderToUse;\n const transGroup = await md.CreateTransactionGroup();\n\n // Queue all saves - no need to await individual saves since transaction group queues them\n for (const notification of this.AllNotifications) {\n if (notification.Unread && bRead || !notification.Unread && !bRead) {\n // Don't await - Save() with transaction group queues the operation immediately\n this.MarkAsRead(notification, bRead, transGroup);\n }\n }\n\n // Submit transaction group - this is where the actual network call happens\n if (!await transGroup.Submit())\n this.SharedService.CreateSimpleNotification('Unable to mark all notifications as read', 'error', 5000);\n else\n SharedService.RefreshUserNotifications();\n }\n\n /** @deprecated Use {@link MarkAll}. */\n public async markAll(bRead: boolean) {\n return this.MarkAll(bRead);\n }\n\n NotificationClicked(notification: MJUserNotificationEntity): void {\n if (this.IsNotificationClickable(notification)) {\n // also mark this as read when we click it\n this.MarkAsRead(notification, true, null);\n\n // Check for special navigation types that use NavigationService (not router)\n if (this.navigateToAgentRequest(notification)) {\n return;\n }\n if (this.navigateToConversation(notification)) {\n return;\n }\n if (this.navigateToMeetRoom(notification)) {\n return;\n }\n\n this.navigateToResource(notification);\n }\n }\n\n /** @deprecated Use {@link NotificationClicked}. */\n notificationClicked(notification: MJUserNotificationEntity): void {\n return this.NotificationClicked(notification);\n }\n\n /**\n * Opens the Meet app's Live Room in JOIN mode for a `meet-room` invite notification (the\n * `{ type:'meet-room', room }` ResourceConfiguration), mirroring {@link navigateToConversation}.\n * Returns `false` (not handled) when the config isn't a meet-room invite or the Meet app is absent.\n */\n private navigateToMeetRoom(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n const config = SafeJSONParse<{ type?: string; room?: string }>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'meet-room') {\n return false;\n }\n const meetApp = this.appManager.GetAppByName('Meet');\n if (!meetApp) {\n return false;\n }\n const navConfig: Record<string, string> = {};\n if (config.room) {\n navConfig['room'] = config.room;\n }\n this.navigationService.OpenNavItemByName('Live Room', navConfig, meetApp.ID);\n return true;\n }\n\n /**\n * Navigate to a resource-based notification using NavigationService methods.\n * Routes to the correct resource based on the notification's ResourceType.\n */\n private navigateToResource(notification: MJUserNotificationEntity): void {\n if (!notification.ResourceRecordID || !notification.ResourceTypeID) return;\n\n const rt = this.SharedService.ResourceTypeByID(notification.ResourceTypeID);\n if (!rt) return;\n\n const recordId = notification.ResourceRecordID.toString();\n const rtName = rt.Name.trim().toLowerCase();\n\n switch (rtName) {\n case 'records': {\n const config = SafeJSONParse<RecordResourceConfig>(notification.ResourceConfiguration || '');\n if (config?.Entity) {\n const key = new CompositeKey();\n key.SimpleLoadFromURLSegment(recordId);\n this.navigationService.OpenEntityRecord(config.Entity, key);\n }\n break;\n }\n case 'user views':\n case 'mj: user views':\n this.navigationService.OpenView(recordId, 'View');\n break;\n case 'dashboards':\n this.navigationService.OpenDashboard(recordId, 'Dashboard');\n break;\n default:\n console.warn(`[UserNotifications] Unhandled resource type for navigation: ${rt.Name}`);\n break;\n }\n }\n\n /**\n * Handle navigation to an agent request via NavigationService.\n * Returns true if the notification was an agent-request type and navigation was attempted.\n */\n private navigateToAgentRequest(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'agent-request' || !config.requestId) {\n return false;\n }\n\n // Try the AI app first (has dedicated Agent Requests nav item)\n const aiApp = this.appManager.GetAppByName('AI');\n if (aiApp) {\n this.navigationService.OpenNavItemByName(\n 'Agent Requests',\n { requestId: config.requestId },\n aiApp.ID\n );\n return true;\n }\n\n // Fallback: navigate to Chat app's Conversations with the request context\n const chatApp = this.appManager.GetAppByName('Chat');\n if (chatApp) {\n this.navigationService.OpenNavItemByName(\n 'Conversations',\n { requestId: config.requestId },\n chatApp.ID\n );\n return true;\n }\n\n return false;\n }\n\n /**\n * Handle navigation to a conversation via NavigationService.\n * Returns true if the notification was a conversation type and navigation was attempted.\n */\n private navigateToConversation(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'conversation') {\n return false;\n }\n\n const chatApp = this.appManager.GetAppByName('Chat');\n if (!chatApp) {\n return false;\n }\n\n const navConfig: Record<string, string> = {};\n if (config.conversationId) navConfig['conversationId'] = config.conversationId;\n if (config.messageId) navConfig['messageId'] = config.messageId;\n if (config.artifactId) navConfig['artifactId'] = config.artifactId;\n if (config.versionNumber) navConfig['versionNumber'] = config.versionNumber;\n if (config.taskId) navConfig['taskId'] = config.taskId;\n\n this.navigationService.OpenNavItemByName(\n 'Conversations',\n navConfig,\n chatApp.ID\n );\n return true;\n }\n\n public GetNotificationType(typeId: string | null): MJUserNotificationTypeEntity | null {\n if (!typeId) return null;\n return this.NotificationTypes.find(t => UUIDsEqual(t.ID, typeId)) || null;\n }\n\n /** @deprecated Use {@link GetNotificationType}. */\n public getNotificationType(typeId: string | null): MJUserNotificationTypeEntity | null {\n return this.GetNotificationType(typeId);\n }\n\n public GetTypeIcon(notification: MJUserNotificationEntity): string {\n const type = this.GetNotificationType(notification.NotificationTypeID);\n return type?.Icon || 'fa-bell';\n }\n\n /** @deprecated Use {@link GetTypeIcon}. */\n public getTypeIcon(notification: MJUserNotificationEntity): string {\n return this.GetTypeIcon(notification);\n }\n\n public GetTypeColor(notification: MJUserNotificationEntity): string {\n const type = this.GetNotificationType(notification.NotificationTypeID);\n return type?.Color || 'var(--mj-text-muted)';\n }\n\n /** @deprecated Use {@link GetTypeColor}. */\n public getTypeColor(notification: MJUserNotificationEntity): string {\n return this.GetTypeColor(notification);\n }\n\n public GetTypeName(notification: MJUserNotificationEntity): string {\n const type = this.GetNotificationType(notification.NotificationTypeID);\n return type ? type.Name : 'Notification';\n }\n\n /** @deprecated Use {@link GetTypeName}. */\n public getTypeName(notification: MJUserNotificationEntity): string {\n return this.GetTypeName(notification);\n }\n\n public OnTypeFilterChange(typeId: string | null): void {\n this.SelectedTypeFilter = typeId;\n }\n\n /** @deprecated Use {@link OnTypeFilterChange}. */\n public onTypeFilterChange(typeId: string | null): void {\n return this.OnTypeFilterChange(typeId);\n }\n}\n","<div class=\"notifications-container\">\n <!-- Header Section -->\n <div class=\"notifications-header\">\n <div class=\"header-top\">\n <div class=\"header-title\">\n <div class=\"title-icon\">\n <i class=\"fa-solid fa-bell\"></i>\n </div>\n <div class=\"title-text\">\n <h1>Notifications</h1>\n @if (UnreadNotifications.length > 0) {\n <span class=\"title-subtitle\">{{UnreadNotifications.length}} unread</span>\n } @else if (AllNotifications.length > 0) {\n <span class=\"title-subtitle\">All caught up</span>\n }\n </div>\n </div>\n\n @if (AllNotifications.length > 0) {\n <div class=\"header-actions\">\n @if (UnreadNotifications.length > 0) {\n <button class=\"action-btn action-btn-ghost\"\n type=\"button\"\n (click)=\"markAllAsRead()\"\n aria-label=\"Mark all notifications as read\">\n <i class=\"fa-solid fa-check-double\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Read</span>\n </button>\n }\n @if (ReadNotifications.length > 0) {\n <button class=\"action-btn action-btn-secondary\"\n type=\"button\"\n (click)=\"markAllAsUnread()\"\n aria-label=\"Mark all notifications as unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Unread</span>\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Filters Section -->\n @if (AllNotifications.length > 0) {\n <div class=\"filters-section\">\n <div class=\"filters-slider\">\n <div class=\"slider-content\">\n <!-- Read-status pills -->\n <div class=\"header-stats\" role=\"group\" aria-label=\"Filter notifications by read status\">\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'All'\"\n (click)=\"selectReadOption('All')\"\n [attr.aria-pressed]=\"radioSelected === 'All'\"\n aria-label=\"Show all notifications\">\n <span class=\"stat-label\">All</span>\n <span class=\"stat-count\">{{AllNotifications.length}}</span>\n </button>\n\n @if (UnreadNotifications.length > 0 || ReadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Unread'\"\n [class.has-unread]=\"UnreadNotifications.length > 0\"\n (click)=\"selectReadOption('Unread')\"\n [attr.aria-pressed]=\"radioSelected === 'Unread'\"\n aria-label=\"Show unread notifications\">\n <span class=\"stat-label\">Unread</span>\n <span class=\"stat-count\" [class.unread-count]=\"UnreadNotifications.length > 0\">\n {{UnreadNotifications.length}}\n </span>\n </button>\n }\n\n @if (ReadNotifications.length > 0 || UnreadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Read'\"\n (click)=\"selectReadOption('Read')\"\n [attr.aria-pressed]=\"radioSelected === 'Read'\"\n aria-label=\"Show read notifications\">\n <span class=\"stat-label\">Read</span>\n <span class=\"stat-count\">{{ReadNotifications.length}}</span>\n </button>\n }\n </div>\n\n <!-- Type filter -->\n @if (notificationTypes.length > 0) {\n <div class=\"filter-item type-filter-slider\">\n <select class=\"type-select\"\n [(ngModel)]=\"selectedTypeFilter\"\n (change)=\"onTypeFilterChange(selectedTypeFilter)\"\n aria-label=\"Filter by notification type\">\n <option [value]=\"null\">All Types</option>\n @for (type of notificationTypes; track type.ID) {\n <option [value]=\"type.ID\">{{type.Name}}</option>\n }\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Search -->\n <div class=\"search-section\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\" aria-hidden=\"true\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search notifications...\"\n [value]=\"currentFilter\"\n (input)=\"onFilterChanged($any($event.target).value)\"\n aria-label=\"Search notifications\" />\n </div>\n </div>\n\n @if (NotificationsToShow.length !== AllNotifications.length) {\n <div class=\"filter-info\">\n <span class=\"filter-badge\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n Showing {{NotificationsToShow.length}} of {{AllNotifications.length}}\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Notifications Content -->\n <div class=\"notifications-content\">\n @if (NotificationsToShow.length === 0 && AllNotifications.length === 0) {\n <mj-empty-state\n Variant=\"success\"\n Icon=\"fa-solid fa-bell-slash\"\n Title=\"No Notifications\"\n Message=\"You're all caught up! New notifications will appear here.\" />\n } @else if (NotificationsToShow.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-filter-circle-xmark\"\n Title=\"No Matching Notifications\"\n Message=\"Try adjusting your filters to see more notifications.\" />\n } @else {\n <!-- Day-grouped notification list -->\n <div class=\"notifications-list\">\n @for (group of Groups; track group.Key) {\n <div class=\"group-label\">{{group.Label}}</div>\n\n @for (vm of group.Items; track vm.N.ID) {\n <article class=\"notification-card\"\n [class.unread]=\"vm.N.Unread\"\n [class.expanded]=\"IsExpanded(vm)\"\n [class.clickable]=\"vm.Clickable\"\n role=\"article\"\n [attr.aria-label]=\"vm.N.Title\">\n\n <!-- Unread Indicator Bar -->\n <div class=\"card-indicator\" aria-hidden=\"true\"></div>\n\n <!-- Type Icon -->\n <div class=\"card-icon\" aria-hidden=\"true\">\n <i [class]=\"'fa-solid ' + getTypeIcon(vm.N)\"\n [style.color]=\"getTypeColor(vm.N)\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"card-content\" (click)=\"notificationClicked(vm.N)\">\n <div class=\"card-header\">\n <h3 class=\"card-title\" [class.card-title-unread]=\"vm.N.Unread\">\n {{vm.N.Title}}\n </h3>\n <span class=\"card-time\" [title]=\"(vm.N.__mj_CreatedAt | date:'medium') ?? ''\">\n @if (vm.Relative) {\n {{vm.Relative}}\n } @else {\n <time [attr.datetime]=\"vm.N.__mj_CreatedAt\">{{vm.N.__mj_CreatedAt | date:'MMM d, h:mm a'}}</time>\n }\n </span>\n </div>\n\n <div class=\"card-meta\">\n <span class=\"card-type\">{{getTypeName(vm.N)}}</span>\n @if (vm.Clickable) {\n <span class=\"card-open-hint\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\" aria-hidden=\"true\"></i> Open\n </span>\n }\n </div>\n\n @if (!IsExpanded(vm)) {\n <p class=\"card-message\">{{vm.Preview}}</p>\n } @else {\n <div class=\"card-rich\" (click)=\"$event.stopPropagation()\">\n @switch (vm.Kind) {\n @case ('html') {\n <!-- Angular sanitizes on [innerHTML] bind; chrome tags were stripped at classification -->\n <div class=\"card-rich-html\" [innerHTML]=\"vm.Body\"></div>\n }\n @case ('markdown') {\n <mj-markdown class=\"card-rich-md\" [data]=\"vm.Body\" [enableMermaid]=\"false\"></mj-markdown>\n }\n @default {\n <p class=\"card-message card-message-full\">{{vm.N.Message}}</p>\n }\n }\n </div>\n }\n\n @if (vm.Expandable) {\n <button class=\"card-expand-btn\" type=\"button\"\n (click)=\"ToggleExpanded(vm, $event)\"\n [attr.aria-expanded]=\"IsExpanded(vm)\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsExpanded(vm)\" [class.fa-chevron-up]=\"IsExpanded(vm)\" aria-hidden=\"true\"></i>\n {{ IsExpanded(vm) ? 'Show less' : 'Show more' }}\n </button>\n }\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\">\n @if (vm.N.Unread) {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(vm.N, true, null)\"\n [attr.aria-label]=\"'Mark ' + vm.N.Title + ' as read'\"\n title=\"Mark as Read\">\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Read</span>\n </button>\n } @else {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(vm.N, false, null)\"\n [attr.aria-label]=\"'Mark ' + vm.N.Title + ' as unread'\"\n title=\"Mark as Unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Unread</span>\n </button>\n }\n </div>\n </article>\n }\n }\n </div>\n }\n </div>\n</div>\n"]}
|
|
@@ -20,13 +20,14 @@ export declare class UserProfileComponent extends BaseAngularComponent implement
|
|
|
20
20
|
UnreadNotificationCount: number;
|
|
21
21
|
NotificationSummary: NotificationSummary;
|
|
22
22
|
private destroy$;
|
|
23
|
-
constructor(authBase: MJAuthBase,
|
|
23
|
+
constructor(authBase: MJAuthBase, // case-violation-ok-legacy-back-compat: the constructor uses this parameter by bare name, so the rename is scope-sensitive
|
|
24
|
+
sharedService: SharedService, cdr: ChangeDetectorRef);
|
|
24
25
|
ngOnInit(): Promise<void>;
|
|
25
26
|
ngOnDestroy(): void;
|
|
26
27
|
/**
|
|
27
28
|
* Loads notification data from UserInfoEngine
|
|
28
29
|
*/
|
|
29
|
-
private
|
|
30
|
+
private loadNotificationData;
|
|
30
31
|
/**
|
|
31
32
|
* Toggles a specific notification channel globally
|
|
32
33
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profile.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-profile/user-profile.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGhF,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAI3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AACrE,UAAU,mBAAmB;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,qBAMa,oBAAqB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAehF,QAAQ,EAAE,UAAU;IAC3B,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IAhBN,IAAI,EAAE,GAAG,CAAQ;IACjB,IAAI,EAAE,UAAU,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC1C,OAAO,UAAQ;IACf,MAAM,UAAS;IACf,uBAAuB,SAAK;IAC5B,mBAAmB,EAAE,mBAAmB,CAI7C;IAEF,OAAO,CAAC,QAAQ,CAAuB;gBAG9B,QAAQ,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"user-profile.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-profile/user-profile.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGhF,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAI3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AACrE,UAAU,mBAAmB;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,qBAMa,oBAAqB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAehF,QAAQ,EAAE,UAAU;IAC3B,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IAhBN,IAAI,EAAE,GAAG,CAAQ;IACjB,IAAI,EAAE,UAAU,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC1C,OAAO,UAAQ;IACf,MAAM,UAAS;IACf,uBAAuB,SAAK;IAC5B,mBAAmB,EAAE,mBAAmB,CAI7C;IAEF,OAAO,CAAC,QAAQ,CAAuB;gBAG9B,QAAQ,EAAE,UAAU,EAAG,2HAA2H;IACjJ,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,iBAAiB;IAO1B,QAAQ;IAId,WAAW,IAAI,IAAI;IAKnB;;OAEG;YACW,oBAAoB;IA6ClC;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAoFtE;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM;IAS1D;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM;IAS3D;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO;yCAnMlD,oBAAoB;2CAApB,oBAAoB;CA2MhC"}
|
|
@@ -142,7 +142,8 @@ export class UserProfileComponent extends BaseAngularComponent {
|
|
|
142
142
|
SMSEnabled: false
|
|
143
143
|
};
|
|
144
144
|
destroy$ = new Subject();
|
|
145
|
-
constructor(authBase,
|
|
145
|
+
constructor(authBase, // case-violation-ok-legacy-back-compat: the constructor uses this parameter by bare name, so the rename is scope-sensitive
|
|
146
|
+
sharedService, cdr) {
|
|
146
147
|
super();
|
|
147
148
|
this.authBase = authBase;
|
|
148
149
|
this.sharedService = sharedService;
|
|
@@ -151,7 +152,7 @@ export class UserProfileComponent extends BaseAngularComponent {
|
|
|
151
152
|
this.User = authBase.getUserInfo();
|
|
152
153
|
}
|
|
153
154
|
async ngOnInit() {
|
|
154
|
-
await this.
|
|
155
|
+
await this.loadNotificationData();
|
|
155
156
|
}
|
|
156
157
|
ngOnDestroy() {
|
|
157
158
|
this.destroy$.next();
|
|
@@ -160,7 +161,7 @@ export class UserProfileComponent extends BaseAngularComponent {
|
|
|
160
161
|
/**
|
|
161
162
|
* Loads notification data from UserInfoEngine
|
|
162
163
|
*/
|
|
163
|
-
async
|
|
164
|
+
async loadNotificationData() {
|
|
164
165
|
try {
|
|
165
166
|
this.Loading = true;
|
|
166
167
|
// Get unread notification count
|
|
@@ -272,7 +273,7 @@ export class UserProfileComponent extends BaseAngularComponent {
|
|
|
272
273
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
273
274
|
this.sharedService.CreateSimpleNotification(`Failed to update preferences: ${message}`, 'error', 3000);
|
|
274
275
|
// Revert the UI state
|
|
275
|
-
await this.
|
|
276
|
+
await this.loadNotificationData();
|
|
276
277
|
}
|
|
277
278
|
}
|
|
278
279
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profile.component.js","sourceRoot":"","sources":["../../../src/lib/user-profile/user-profile.component.ts","../../../src/lib/user-profile/user-profile.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { AuthService } from '@auth0/auth0-angular';\nimport { MJAuthBase, StandardUserInfo } from '@memberjunction/ng-auth-services';\nimport { UserInfoEngine, MJUserNotificationPreferenceEntity } from '@memberjunction/core-entities';\nimport { Metadata } from '@memberjunction/core';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { Observable, Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\ninterface NotificationSummary {\n InAppEnabled: boolean;\n EmailEnabled: boolean;\n SMSEnabled: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'app-user-profile',\n templateUrl: './user-profile.component.html',\n styleUrls: ['./user-profile.component.css']\n})\nexport class UserProfileComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n public JSON: any = JSON;\n public User: Observable<StandardUserInfo | null>;\n public Loading = true;\n public Saving = false;\n public UnreadNotificationCount = 0;\n public NotificationSummary: NotificationSummary = {\n InAppEnabled: true,\n EmailEnabled: false,\n SMSEnabled: false\n };\n\n private destroy$ = new Subject<void>();\n\n constructor(\n public authBase: MJAuthBase,\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef\n ) {\n super();\n // v3.0 API - User is now an observable that the template subscribes to\n this.User = authBase.getUserInfo();\n }\n\n async ngOnInit() {\n await this.LoadNotificationData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Loads notification data from UserInfoEngine\n */\n private async LoadNotificationData() {\n try {\n this.Loading = true;\n\n // Get unread notification count\n this.UnreadNotificationCount = UserInfoEngine.Instance.UnreadNotificationCount;\n\n // Calculate global channel preferences\n const preferences = UserInfoEngine.Instance.NotificationPreferences;\n const types = UserInfoEngine.Instance.NotificationTypes;\n\n if (preferences.length === 0 && types.length > 0) {\n // No preferences set yet - use defaults from types\n const inApp = types.some(t => t.DefaultInApp ?? true);\n const email = types.some(t => t.DefaultEmail ?? false);\n const sms = types.some(t => t.DefaultSMS ?? false);\n\n this.NotificationSummary = {\n InAppEnabled: inApp,\n EmailEnabled: email,\n SMSEnabled: sms\n };\n } else if (preferences.length > 0) {\n // Calculate from existing preferences\n const inApp = preferences.some(p => p.InAppEnabled);\n const email = preferences.some(p => p.EmailEnabled);\n const sms = preferences.some(p => p.SMSEnabled);\n\n this.NotificationSummary = {\n InAppEnabled: inApp,\n EmailEnabled: email,\n SMSEnabled: sms\n };\n }\n\n this.Loading = false;\n this.cdr.detectChanges();\n } catch (error: unknown) {\n this.Loading = false;\n const message = error instanceof Error ? error.message : 'Unknown error';\n this.sharedService.CreateSimpleNotification(`Failed to load notification data: ${message}`, 'error', 3000);\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Toggles a specific notification channel globally\n */\n async ToggleChannel(channel: 'InApp' | 'Email' | 'SMS'): Promise<void> {\n try {\n this.Saving = true;\n const md = this.ProviderToUse;\n const currentUser = md.CurrentUser;\n const transGroup = await md.CreateTransactionGroup();\n\n const types = UserInfoEngine.Instance.NotificationTypes;\n const preferences = UserInfoEngine.Instance.NotificationPreferences;\n\n // Determine new state\n let newState: boolean;\n if (channel === 'InApp') {\n newState = !this.NotificationSummary.InAppEnabled;\n this.NotificationSummary.InAppEnabled = newState;\n } else if (channel === 'Email') {\n newState = !this.NotificationSummary.EmailEnabled;\n this.NotificationSummary.EmailEnabled = newState;\n } else {\n newState = !this.NotificationSummary.SMSEnabled;\n this.NotificationSummary.SMSEnabled = newState;\n }\n\n // Update all notification types that allow user preference\n for (const type of types) {\n if (type.AllowUserPreference === false) {\n continue; // Skip locked types\n }\n\n let pref = preferences.find(p => UUIDsEqual(p.NotificationTypeID, type.ID));\n\n if (!pref) {\n // Create new preference record\n pref = await md.GetEntityObject<MJUserNotificationPreferenceEntity>('MJ: User Notification Preferences');\n pref.UserID = currentUser.ID;\n pref.NotificationTypeID = type.ID;\n\n // Set defaults from type\n pref.InAppEnabled = type.DefaultInApp ?? true;\n pref.EmailEnabled = type.DefaultEmail ?? false;\n pref.SMSEnabled = type.DefaultSMS ?? false;\n }\n\n // Update the specific channel\n if (channel === 'InApp') {\n pref.InAppEnabled = newState;\n } else if (channel === 'Email') {\n pref.EmailEnabled = newState;\n } else {\n pref.SMSEnabled = newState;\n }\n\n // Set Enabled based on whether any channel is enabled\n pref.Enabled = pref.InAppEnabled || pref.EmailEnabled || pref.SMSEnabled;\n\n pref.TransactionGroup = transGroup;\n pref.Save();\n }\n\n // Submit transaction group\n const success = await transGroup.Submit();\n\n if (success) {\n this.sharedService.CreateSimpleNotification(\n `${channel} notifications ${newState ? 'enabled' : 'disabled'} globally`,\n 'success',\n 2500\n );\n } else {\n throw new Error('Failed to save preferences');\n }\n\n this.Saving = false;\n this.cdr.detectChanges();\n } catch (error: unknown) {\n this.Saving = false;\n const message = error instanceof Error ? error.message : 'Unknown error';\n this.sharedService.CreateSimpleNotification(`Failed to update preferences: ${message}`, 'error', 3000);\n\n // Revert the UI state\n await this.LoadNotificationData();\n }\n }\n\n /**\n * Gets the appropriate icon for a channel\n */\n GetChannelIcon(channel: 'InApp' | 'Email' | 'SMS'): string {\n switch (channel) {\n case 'InApp': return 'fa-solid fa-bell';\n case 'Email': return 'fa-solid fa-envelope';\n case 'SMS': return 'fa-solid fa-mobile';\n default: return 'fa-solid fa-bell';\n }\n }\n\n /**\n * Gets the label for a channel\n */\n GetChannelLabel(channel: 'InApp' | 'Email' | 'SMS'): string {\n switch (channel) {\n case 'InApp': return 'In-App';\n case 'Email': return 'Email';\n case 'SMS': return 'SMS';\n default: return '';\n }\n }\n\n /**\n * Checks if a channel is enabled\n */\n IsChannelEnabled(channel: 'InApp' | 'Email' | 'SMS'): boolean {\n switch (channel) {\n case 'InApp': return this.NotificationSummary.InAppEnabled;\n case 'Email': return this.NotificationSummary.EmailEnabled;\n case 'SMS': return this.NotificationSummary.SMSEnabled;\n default: return false;\n }\n }\n}\n","@if (Loading) {\n <mj-loading text=\"Loading profile...\"></mj-loading>\n}\n\n@if (!Loading) {\n <div class=\"user-profile-container\">\n <!-- User Info Card -->\n @if (User | async; as user) {\n <div class=\"profile-card\">\n <div class=\"profile-header\">\n <div class=\"avatar-container\">\n <i class=\"fa-solid fa-user avatar-icon\"></i>\n </div>\n <div class=\"profile-info\">\n <h3 class=\"user-name\">{{ user.name }}</h3>\n <p class=\"user-email\">{{ user.email }}</p>\n </div>\n </div>\n </div>\n }\n <!-- Notification Summary Card -->\n <div class=\"notification-card\">\n <div class=\"card-header\">\n <div class=\"header-left\">\n <i class=\"fa-solid fa-bell header-icon\"></i>\n <h4>Notifications</h4>\n </div>\n @if (UnreadNotificationCount > 0) {\n <span class=\"unread-badge\">\n {{ UnreadNotificationCount }}\n </span>\n }\n </div>\n <div class=\"card-body\">\n <p class=\"card-description\">\n Manage your notification preferences for all channels\n </p>\n <div class=\"channel-toggles\">\n <!-- In-App Toggle -->\n <button\n class=\"channel-toggle\"\n [class.active]=\"IsChannelEnabled('InApp')\"\n [disabled]=\"Saving\"\n (click)=\"ToggleChannel('InApp')\"\n type=\"button\"\n >\n <i [class]=\"GetChannelIcon('InApp')\"></i>\n <span class=\"channel-label\">{{ GetChannelLabel('InApp') }}</span>\n <span class=\"toggle-indicator\">\n @if (IsChannelEnabled('InApp')) {\n <i class=\"fa-solid fa-check\"></i>\n }\n </span>\n </button>\n <!-- Email Toggle -->\n <button\n class=\"channel-toggle\"\n [class.active]=\"IsChannelEnabled('Email')\"\n [disabled]=\"Saving\"\n (click)=\"ToggleChannel('Email')\"\n type=\"button\"\n >\n <i [class]=\"GetChannelIcon('Email')\"></i>\n <span class=\"channel-label\">{{ GetChannelLabel('Email') }}</span>\n <span class=\"toggle-indicator\">\n @if (IsChannelEnabled('Email')) {\n <i class=\"fa-solid fa-check\"></i>\n }\n </span>\n </button>\n <!-- SMS Toggle -->\n <button\n class=\"channel-toggle\"\n [class.active]=\"IsChannelEnabled('SMS')\"\n [disabled]=\"Saving\"\n (click)=\"ToggleChannel('SMS')\"\n type=\"button\"\n >\n <i [class]=\"GetChannelIcon('SMS')\"></i>\n <span class=\"channel-label\">{{ GetChannelLabel('SMS') }}</span>\n <span class=\"toggle-indicator\">\n @if (IsChannelEnabled('SMS')) {\n <i class=\"fa-solid fa-check\"></i>\n }\n </span>\n </button>\n </div>\n <div class=\"card-footer\">\n <a href=\"/settings\" class=\"settings-link\">\n View all notification preferences\n <i class=\"fa-solid fa-arrow-right\"></i>\n </a>\n </div>\n </div>\n </div>\n </div>\n}"]}
|
|
1
|
+
{"version":3,"file":"user-profile.component.js","sourceRoot":"","sources":["../../../src/lib/user-profile/user-profile.component.ts","../../../src/lib/user-profile/user-profile.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { AuthService } from '@auth0/auth0-angular';\nimport { MJAuthBase, StandardUserInfo } from '@memberjunction/ng-auth-services';\nimport { UserInfoEngine, MJUserNotificationPreferenceEntity } from '@memberjunction/core-entities';\nimport { Metadata } from '@memberjunction/core';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { Observable, Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\ninterface NotificationSummary {\n InAppEnabled: boolean;\n EmailEnabled: boolean;\n SMSEnabled: boolean;\n}\n\n@Component({\n standalone: false,\n selector: 'app-user-profile',\n templateUrl: './user-profile.component.html',\n styleUrls: ['./user-profile.component.css']\n})\nexport class UserProfileComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n public JSON: any = JSON;\n public User: Observable<StandardUserInfo | null>;\n public Loading = true;\n public Saving = false;\n public UnreadNotificationCount = 0;\n public NotificationSummary: NotificationSummary = {\n InAppEnabled: true,\n EmailEnabled: false,\n SMSEnabled: false\n };\n\n private destroy$ = new Subject<void>();\n\n constructor(\n public authBase: MJAuthBase, // case-violation-ok-legacy-back-compat: the constructor uses this parameter by bare name, so the rename is scope-sensitive\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef\n ) {\n super();\n // v3.0 API - User is now an observable that the template subscribes to\n this.User = authBase.getUserInfo();\n }\n\n async ngOnInit() {\n await this.loadNotificationData();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Loads notification data from UserInfoEngine\n */\n private async loadNotificationData() {\n try {\n this.Loading = true;\n\n // Get unread notification count\n this.UnreadNotificationCount = UserInfoEngine.Instance.UnreadNotificationCount;\n\n // Calculate global channel preferences\n const preferences = UserInfoEngine.Instance.NotificationPreferences;\n const types = UserInfoEngine.Instance.NotificationTypes;\n\n if (preferences.length === 0 && types.length > 0) {\n // No preferences set yet - use defaults from types\n const inApp = types.some(t => t.DefaultInApp ?? true);\n const email = types.some(t => t.DefaultEmail ?? false);\n const sms = types.some(t => t.DefaultSMS ?? false);\n\n this.NotificationSummary = {\n InAppEnabled: inApp,\n EmailEnabled: email,\n SMSEnabled: sms\n };\n } else if (preferences.length > 0) {\n // Calculate from existing preferences\n const inApp = preferences.some(p => p.InAppEnabled);\n const email = preferences.some(p => p.EmailEnabled);\n const sms = preferences.some(p => p.SMSEnabled);\n\n this.NotificationSummary = {\n InAppEnabled: inApp,\n EmailEnabled: email,\n SMSEnabled: sms\n };\n }\n\n this.Loading = false;\n this.cdr.detectChanges();\n } catch (error: unknown) {\n this.Loading = false;\n const message = error instanceof Error ? error.message : 'Unknown error';\n this.sharedService.CreateSimpleNotification(`Failed to load notification data: ${message}`, 'error', 3000);\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Toggles a specific notification channel globally\n */\n async ToggleChannel(channel: 'InApp' | 'Email' | 'SMS'): Promise<void> {\n try {\n this.Saving = true;\n const md = this.ProviderToUse;\n const currentUser = md.CurrentUser;\n const transGroup = await md.CreateTransactionGroup();\n\n const types = UserInfoEngine.Instance.NotificationTypes;\n const preferences = UserInfoEngine.Instance.NotificationPreferences;\n\n // Determine new state\n let newState: boolean;\n if (channel === 'InApp') {\n newState = !this.NotificationSummary.InAppEnabled;\n this.NotificationSummary.InAppEnabled = newState;\n } else if (channel === 'Email') {\n newState = !this.NotificationSummary.EmailEnabled;\n this.NotificationSummary.EmailEnabled = newState;\n } else {\n newState = !this.NotificationSummary.SMSEnabled;\n this.NotificationSummary.SMSEnabled = newState;\n }\n\n // Update all notification types that allow user preference\n for (const type of types) {\n if (type.AllowUserPreference === false) {\n continue; // Skip locked types\n }\n\n let pref = preferences.find(p => UUIDsEqual(p.NotificationTypeID, type.ID));\n\n if (!pref) {\n // Create new preference record\n pref = await md.GetEntityObject<MJUserNotificationPreferenceEntity>('MJ: User Notification Preferences');\n pref.UserID = currentUser.ID;\n pref.NotificationTypeID = type.ID;\n\n // Set defaults from type\n pref.InAppEnabled = type.DefaultInApp ?? true;\n pref.EmailEnabled = type.DefaultEmail ?? false;\n pref.SMSEnabled = type.DefaultSMS ?? false;\n }\n\n // Update the specific channel\n if (channel === 'InApp') {\n pref.InAppEnabled = newState;\n } else if (channel === 'Email') {\n pref.EmailEnabled = newState;\n } else {\n pref.SMSEnabled = newState;\n }\n\n // Set Enabled based on whether any channel is enabled\n pref.Enabled = pref.InAppEnabled || pref.EmailEnabled || pref.SMSEnabled;\n\n pref.TransactionGroup = transGroup;\n pref.Save();\n }\n\n // Submit transaction group\n const success = await transGroup.Submit();\n\n if (success) {\n this.sharedService.CreateSimpleNotification(\n `${channel} notifications ${newState ? 'enabled' : 'disabled'} globally`,\n 'success',\n 2500\n );\n } else {\n throw new Error('Failed to save preferences');\n }\n\n this.Saving = false;\n this.cdr.detectChanges();\n } catch (error: unknown) {\n this.Saving = false;\n const message = error instanceof Error ? error.message : 'Unknown error';\n this.sharedService.CreateSimpleNotification(`Failed to update preferences: ${message}`, 'error', 3000);\n\n // Revert the UI state\n await this.loadNotificationData();\n }\n }\n\n /**\n * Gets the appropriate icon for a channel\n */\n GetChannelIcon(channel: 'InApp' | 'Email' | 'SMS'): string {\n switch (channel) {\n case 'InApp': return 'fa-solid fa-bell';\n case 'Email': return 'fa-solid fa-envelope';\n case 'SMS': return 'fa-solid fa-mobile';\n default: return 'fa-solid fa-bell';\n }\n }\n\n /**\n * Gets the label for a channel\n */\n GetChannelLabel(channel: 'InApp' | 'Email' | 'SMS'): string {\n switch (channel) {\n case 'InApp': return 'In-App';\n case 'Email': return 'Email';\n case 'SMS': return 'SMS';\n default: return '';\n }\n }\n\n /**\n * Checks if a channel is enabled\n */\n IsChannelEnabled(channel: 'InApp' | 'Email' | 'SMS'): boolean {\n switch (channel) {\n case 'InApp': return this.NotificationSummary.InAppEnabled;\n case 'Email': return this.NotificationSummary.EmailEnabled;\n case 'SMS': return this.NotificationSummary.SMSEnabled;\n default: return false;\n }\n }\n}\n","@if (Loading) {\n <mj-loading text=\"Loading profile...\"></mj-loading>\n}\n\n@if (!Loading) {\n <div class=\"user-profile-container\">\n <!-- User Info Card -->\n @if (User | async; as user) {\n <div class=\"profile-card\">\n <div class=\"profile-header\">\n <div class=\"avatar-container\">\n <i class=\"fa-solid fa-user avatar-icon\"></i>\n </div>\n <div class=\"profile-info\">\n <h3 class=\"user-name\">{{ user.name }}</h3>\n <p class=\"user-email\">{{ user.email }}</p>\n </div>\n </div>\n </div>\n }\n <!-- Notification Summary Card -->\n <div class=\"notification-card\">\n <div class=\"card-header\">\n <div class=\"header-left\">\n <i class=\"fa-solid fa-bell header-icon\"></i>\n <h4>Notifications</h4>\n </div>\n @if (UnreadNotificationCount > 0) {\n <span class=\"unread-badge\">\n {{ UnreadNotificationCount }}\n </span>\n }\n </div>\n <div class=\"card-body\">\n <p class=\"card-description\">\n Manage your notification preferences for all channels\n </p>\n <div class=\"channel-toggles\">\n <!-- In-App Toggle -->\n <button\n class=\"channel-toggle\"\n [class.active]=\"IsChannelEnabled('InApp')\"\n [disabled]=\"Saving\"\n (click)=\"ToggleChannel('InApp')\"\n type=\"button\"\n >\n <i [class]=\"GetChannelIcon('InApp')\"></i>\n <span class=\"channel-label\">{{ GetChannelLabel('InApp') }}</span>\n <span class=\"toggle-indicator\">\n @if (IsChannelEnabled('InApp')) {\n <i class=\"fa-solid fa-check\"></i>\n }\n </span>\n </button>\n <!-- Email Toggle -->\n <button\n class=\"channel-toggle\"\n [class.active]=\"IsChannelEnabled('Email')\"\n [disabled]=\"Saving\"\n (click)=\"ToggleChannel('Email')\"\n type=\"button\"\n >\n <i [class]=\"GetChannelIcon('Email')\"></i>\n <span class=\"channel-label\">{{ GetChannelLabel('Email') }}</span>\n <span class=\"toggle-indicator\">\n @if (IsChannelEnabled('Email')) {\n <i class=\"fa-solid fa-check\"></i>\n }\n </span>\n </button>\n <!-- SMS Toggle -->\n <button\n class=\"channel-toggle\"\n [class.active]=\"IsChannelEnabled('SMS')\"\n [disabled]=\"Saving\"\n (click)=\"ToggleChannel('SMS')\"\n type=\"button\"\n >\n <i [class]=\"GetChannelIcon('SMS')\"></i>\n <span class=\"channel-label\">{{ GetChannelLabel('SMS') }}</span>\n <span class=\"toggle-indicator\">\n @if (IsChannelEnabled('SMS')) {\n <i class=\"fa-solid fa-check\"></i>\n }\n </span>\n </button>\n </div>\n <div class=\"card-footer\">\n <a href=\"/settings\" class=\"settings-link\">\n View all notification preferences\n <i class=\"fa-solid fa-arrow-right\"></i>\n </a>\n </div>\n </div>\n </div>\n </div>\n}"]}
|