@memberjunction/ng-explorer-core 6.1.0-edge.4 → 6.1.0-edge.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +19 -0
  2. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  3. package/dist/generated/lazy-feature-config.js +12 -6
  4. package/dist/generated/lazy-feature-config.js.map +1 -1
  5. package/dist/lib/about/about-dialog.component.js +4 -4
  6. package/dist/lib/about/about-dialog.component.js.map +1 -1
  7. package/dist/lib/command-palette/command-palette.component.d.ts +13 -0
  8. package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
  9. package/dist/lib/command-palette/command-palette.component.js +106 -42
  10. package/dist/lib/command-palette/command-palette.component.js.map +1 -1
  11. package/dist/lib/conversation-feedback/conversation-feedback.js +1 -1
  12. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +1 -1
  13. package/dist/lib/oauth/oauth-callback.component.js +1 -1
  14. package/dist/lib/omnibar/omnibar-palette.component.d.ts.map +1 -1
  15. package/dist/lib/omnibar/omnibar-palette.component.js +9 -3
  16. package/dist/lib/omnibar/omnibar-palette.component.js.map +1 -1
  17. package/dist/lib/omnibar/providers/omnibar-record.provider.d.ts.map +1 -1
  18. package/dist/lib/omnibar/providers/omnibar-record.provider.js +9 -3
  19. package/dist/lib/omnibar/providers/omnibar-record.provider.js.map +1 -1
  20. package/dist/lib/profile/profile-dialog.component.js +1 -1
  21. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  22. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +13 -12
  23. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  24. package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts +24 -0
  25. package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts.map +1 -0
  26. package/dist/lib/resource-wrappers/chat-deeplink-params.js +27 -0
  27. package/dist/lib/resource-wrappers/chat-deeplink-params.js.map +1 -0
  28. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +7 -0
  29. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  30. package/dist/lib/resource-wrappers/dashboard-resource.component.js +29 -14
  31. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  32. package/dist/lib/resource-wrappers/list-detail-resource.component.js +1 -1
  33. package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
  34. package/dist/lib/resource-wrappers/query-resource.component.js +1 -1
  35. package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
  36. package/dist/lib/resource-wrappers/record-resource.component.d.ts +3 -0
  37. package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
  38. package/dist/lib/resource-wrappers/record-resource.component.js +18 -4
  39. package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
  40. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
  41. package/dist/lib/resource-wrappers/search-results-resource.component.js +6 -2
  42. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  43. package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
  44. package/dist/lib/resource-wrappers/view-resource.component.js +6 -3
  45. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  46. package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts +20 -8
  47. package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts.map +1 -1
  48. package/dist/lib/server-connectivity/server-connectivity-banner.component.js +25 -20
  49. package/dist/lib/server-connectivity/server-connectivity-banner.component.js.map +1 -1
  50. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +2 -2
  51. package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
  52. package/dist/lib/shell/components/header/app-nav.component.js +1 -1
  53. package/dist/lib/shell/components/header/app-switcher.component.js +82 -83
  54. package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
  55. package/dist/lib/shell/components/record-open/record-bar.component.js +1 -1
  56. package/dist/lib/shell/components/record-open/record-origin-crumb.component.js +1 -1
  57. package/dist/lib/shell/components/record-open/record-switcher-sheet.component.js +1 -1
  58. package/dist/lib/shell/components/record-open/records-hub-pill.component.js +1 -1
  59. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +25 -0
  60. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  61. package/dist/lib/shell/components/tabs/tab-container.component.js +88 -4
  62. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  63. package/dist/lib/shell/services/sharing-center-dialog-host.component.js +2 -2
  64. package/dist/lib/shell/services/sharing-center-dialog-host.component.js.map +1 -1
  65. package/dist/lib/shell/shell-chrome-policy.d.ts +54 -0
  66. package/dist/lib/shell/shell-chrome-policy.d.ts.map +1 -0
  67. package/dist/lib/shell/shell-chrome-policy.js +62 -0
  68. package/dist/lib/shell/shell-chrome-policy.js.map +1 -0
  69. package/dist/lib/shell/shell.component.d.ts +42 -0
  70. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  71. package/dist/lib/shell/shell.component.js +394 -255
  72. package/dist/lib/shell/shell.component.js.map +1 -1
  73. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +1 -1
  74. package/dist/lib/single-dashboard/single-dashboard.component.js +1 -1
  75. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +9 -0
  76. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  77. package/dist/lib/single-list-detail/single-list-detail.component.js +34 -15
  78. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  79. package/dist/lib/single-record/single-record.component.d.ts +10 -0
  80. package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
  81. package/dist/lib/single-record/single-record.component.js +23 -3
  82. package/dist/lib/single-record/single-record.component.js.map +1 -1
  83. package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
  84. package/dist/lib/single-search-result/single-search-result.component.js +5 -2
  85. package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
  86. package/dist/lib/user-notifications/user-notifications.component.js +11 -12
  87. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  88. package/dist/lib/user-profile/user-profile.component.js +1 -1
  89. package/dist/public-api.d.ts +1 -0
  90. package/dist/public-api.d.ts.map +1 -1
  91. package/dist/public-api.js +1 -0
  92. package/dist/public-api.js.map +1 -1
  93. package/package.json +62 -62
@@ -25,6 +25,16 @@ export declare class SingleRecordComponent extends BaseAngularComponent {
25
25
  recordSaved: EventEmitter<BaseEntity>;
26
26
  /** Emitted when the hosted form asks to be dismissed (e.g. Discard on a new record). */
27
27
  recordDismissed: EventEmitter<void>;
28
+ private formHost?;
29
+ /**
30
+ * True while the hosted form is in edit mode. The host already exposes the
31
+ * live form instance, so this is a read, not a new event pipeline.
32
+ *
33
+ * MJ forms are read-only until the user explicitly clicks Edit, so edit mode
34
+ * is a deliberate gesture and a sound proxy for "there is work in here worth
35
+ * protecting" — which is all the preview-tab replacement guard needs.
36
+ */
37
+ IsEditing(): boolean;
28
38
  private navigationService;
29
39
  private sharedService;
30
40
  private formPresenter;
@@ -1 +1 @@
1
- {"version":3,"file":"single-record.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-record/single-record.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAyB,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAA0B,MAAM,+BAA+B,CAAC;AAEnH,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAErE;;;;;;;;;;;;;GAaG;AACH,qBAMa,qBAAsB,SAAQ,oBAAoB;IAC7C,UAAU,EAAE,YAAY,CAAsB;IAC9C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAM;IAC/B,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAM;IAE7D,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,CAA4B;IAC5D,WAAW,EAAE,YAAY,CAAC,UAAU,CAAC,CAAkC;IACxF,wFAAwF;IACvE,eAAe,EAAE,YAAY,CAAC,IAAI,CAAC,CAA4B;IAEhF,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,mBAAmB,CAA6B;IAExD,uEAAuE;IACvE,cAAc,IAAI,IAAI;IAItB,uEAAuE;IACvE,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAMvC,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAIjC,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI;IAIlD,4EAA4E;IAC5E,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;yCApCvC,qBAAqB;2CAArB,qBAAqB;CA4EjC"}
1
+ {"version":3,"file":"single-record.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-record/single-record.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAoC,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAqD,MAAM,+BAA+B,CAAC;AAE9I,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAErE;;;;;;;;;;;;;GAaG;AACH,qBAMa,qBAAsB,SAAQ,oBAAoB;IAC7C,UAAU,EAAE,YAAY,CAAsB;IAC9C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAM;IAC/B,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAM;IAE7D,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,CAA4B;IAC5D,WAAW,EAAE,YAAY,CAAC,UAAU,CAAC,CAAkC;IACxF,wFAAwF;IACvE,eAAe,EAAE,YAAY,CAAC,IAAI,CAAC,CAA4B;IAE1C,OAAO,CAAC,QAAQ,CAAC,CAA4B;IAEnF;;;;;;;OAOG;IACI,SAAS,IAAI,OAAO;IAI3B,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,mBAAmB,CAA6B;IAExD,uEAAuE;IACvE,cAAc,IAAI,IAAI;IAItB,uEAAuE;IACvE,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAMvC,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAIjC,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI;IAIlD,4EAA4E;IAC5E,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;yCAlDvC,qBAAqB;2CAArB,qBAAqB;CA0FjC"}
@@ -1,6 +1,6 @@
1
- import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
1
+ import { Component, EventEmitter, inject, Input, Output, ViewChild } from '@angular/core';
2
2
  import { CompositeKey } from '@memberjunction/core';
3
- import { MJFormPresenterService } from '@memberjunction/ng-base-forms';
3
+ import { MJFormPresenterService, MjEntityFormHostComponent } from '@memberjunction/ng-base-forms';
4
4
  import { NavigationService, RecentAccessService, SharedService } from '@memberjunction/ng-shared';
5
5
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
6
6
  import * as i0 from "@angular/core";
@@ -27,6 +27,18 @@ export class SingleRecordComponent extends BaseAngularComponent {
27
27
  recordSaved = new EventEmitter();
28
28
  /** Emitted when the hosted form asks to be dismissed (e.g. Discard on a new record). */
29
29
  recordDismissed = new EventEmitter();
30
+ formHost;
31
+ /**
32
+ * True while the hosted form is in edit mode. The host already exposes the
33
+ * live form instance, so this is a read, not a new event pipeline.
34
+ *
35
+ * MJ forms are read-only until the user explicitly clicks Edit, so edit mode
36
+ * is a deliberate gesture and a sound proxy for "there is work in here worth
37
+ * protecting" — which is all the preview-tab replacement guard needs.
38
+ */
39
+ IsEditing() {
40
+ return this.formHost?.Form?.EditMode === true;
41
+ }
30
42
  navigationService = inject(NavigationService);
31
43
  sharedService = inject(SharedService);
32
44
  formPresenter = inject(MJFormPresenterService);
@@ -89,7 +101,12 @@ export class SingleRecordComponent extends BaseAngularComponent {
89
101
  }
90
102
  }
91
103
  static ɵfac = /*@__PURE__*/ (() => { let ɵSingleRecordComponent_BaseFactory; return function SingleRecordComponent_Factory(__ngFactoryType__) { return (ɵSingleRecordComponent_BaseFactory || (ɵSingleRecordComponent_BaseFactory = i0.ɵɵgetInheritedFactory(SingleRecordComponent)))(__ngFactoryType__ || SingleRecordComponent); }; })();
92
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SingleRecordComponent, selectors: [["mj-single-record"]], inputs: { PrimaryKey: "PrimaryKey", entityName: "entityName", newRecordValues: "newRecordValues" }, outputs: { loadComplete: "loadComplete", recordSaved: "recordSaved", recordDismissed: "recordDismissed" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 4, consts: [[3, "LoadComplete", "LoadError", "RecordReady", "Saved", "Navigate", "Notification", "Dismissed", "EntityName", "PrimaryKey", "NewRecordValues", "Provider"]], template: function SingleRecordComponent_Template(rf, ctx) { if (rf & 1) {
104
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SingleRecordComponent, selectors: [["mj-single-record"]], viewQuery: function SingleRecordComponent_Query(rf, ctx) { if (rf & 1) {
105
+ i0.ɵɵviewQuery(MjEntityFormHostComponent, 5);
106
+ } if (rf & 2) {
107
+ let _t;
108
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.formHost = _t.first);
109
+ } }, inputs: { PrimaryKey: "PrimaryKey", entityName: "entityName", newRecordValues: "newRecordValues" }, outputs: { loadComplete: "loadComplete", recordSaved: "recordSaved", recordDismissed: "recordDismissed" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 4, consts: [[3, "LoadComplete", "LoadError", "RecordReady", "Saved", "Navigate", "Notification", "Dismissed", "EntityName", "PrimaryKey", "NewRecordValues", "Provider"]], template: function SingleRecordComponent_Template(rf, ctx) { if (rf & 1) {
93
110
  i0.ɵɵelementStart(0, "mj-entity-form-host", 0);
94
111
  i0.ɵɵlistener("LoadComplete", function SingleRecordComponent_Template_mj_entity_form_host_LoadComplete_0_listener() { return ctx.onLoadComplete(); })("LoadError", function SingleRecordComponent_Template_mj_entity_form_host_LoadError_0_listener() { return ctx.onLoadComplete(); })("RecordReady", function SingleRecordComponent_Template_mj_entity_form_host_RecordReady_0_listener($event) { return ctx.onRecordReady($event); })("Saved", function SingleRecordComponent_Template_mj_entity_form_host_Saved_0_listener($event) { return ctx.onSaved($event); })("Navigate", function SingleRecordComponent_Template_mj_entity_form_host_Navigate_0_listener($event) { return ctx.handleNavigation($event); })("Notification", function SingleRecordComponent_Template_mj_entity_form_host_Notification_0_listener($event) { return ctx.onNotification($event); })("Dismissed", function SingleRecordComponent_Template_mj_entity_form_host_Dismissed_0_listener() { return ctx.recordDismissed.emit(); });
95
112
  i0.ɵɵelementEnd();
@@ -112,6 +129,9 @@ export class SingleRecordComponent extends BaseAngularComponent {
112
129
  type: Output
113
130
  }], recordDismissed: [{
114
131
  type: Output
132
+ }], formHost: [{
133
+ type: ViewChild,
134
+ args: [MjEntityFormHostComponent]
115
135
  }] }); })();
116
136
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SingleRecordComponent, { className: "SingleRecordComponent", filePath: "src/lib/single-record/single-record.component.ts", lineNumber: 27 }); })();
117
137
  //# sourceMappingURL=single-record.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"single-record.component.js","sourceRoot":"","sources":["../../../src/lib/single-record/single-record.component.ts","../../../src/lib/single-record/single-record.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, inject, Input, Output } from '@angular/core';\nimport { CompositeKey, BaseEntity } from '@memberjunction/core';\nimport { FormNavigationEvent, FormNotificationEvent, MJFormPresenterService } from '@memberjunction/ng-base-forms';\nimport { NavigationService, RecentAccessService, SharedService } from '@memberjunction/ng-shared';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n/**\n * Explorer-side host for a single entity record in the main tab area.\n *\n * This is now a **thin wrapper** around the Generic `<mj-entity-form-host>`\n * (in `@memberjunction/ng-base-forms`), which owns all the mechanics: resolving\n * the form (class / custom / interactive override + variants), loading the\n * record, dynamically creating the form, binding it, and tearing it down.\n *\n * SingleRecordComponent's only remaining job is the **Explorer mapping**:\n * translating the host's framework-agnostic events into Explorer services —\n * `Navigate` → {@link NavigationService}, `Notification` → {@link SharedService},\n * record loads → {@link RecentAccessService} — none of which belong in a Generic\n * component.\n */\n@Component({\n standalone: false,\n selector: 'mj-single-record',\n templateUrl: './single-record.component.html',\n styleUrls: ['./single-record.component.css']\n})\nexport class SingleRecordComponent extends BaseAngularComponent {\n @Input() public PrimaryKey: CompositeKey = new CompositeKey();\n @Input() public entityName: string | null = '';\n @Input() public newRecordValues: string | Record<string, unknown> | null = '';\n\n @Output() public loadComplete: EventEmitter<void> = new EventEmitter<void>();\n @Output() public recordSaved: EventEmitter<BaseEntity> = new EventEmitter<BaseEntity>();\n /** Emitted when the hosted form asks to be dismissed (e.g. Discard on a new record). */\n @Output() public recordDismissed: EventEmitter<void> = new EventEmitter<void>();\n\n private navigationService = inject(NavigationService);\n private sharedService = inject(SharedService);\n private formPresenter = inject(MJFormPresenterService);\n private recentAccessService = new RecentAccessService();\n\n /** Unblock the shell's first-resource-load gate (success or error). */\n onLoadComplete(): void {\n this.loadComplete.emit();\n }\n\n /** Log access for existing records once the form's record is ready. */\n onRecordReady(record: BaseEntity): void {\n if (record?.IsSaved) {\n this.recentAccessService.logAccess(record.EntityInfo.Name, record.PrimaryKey, 'record');\n }\n }\n\n onSaved(record: BaseEntity): void {\n this.recordSaved.emit(record);\n }\n\n onNotification(event: FormNotificationEvent): void {\n this.sharedService.CreateSimpleNotification(event.Message, event.Type, event.Duration);\n }\n\n /** Map the form's navigation requests onto Explorer's NavigationService. */\n handleNavigation(event: FormNavigationEvent): void {\n switch (event.Kind) {\n case 'record':\n this.navigationService.OpenEntityRecord(event.EntityName, event.PrimaryKey, { forceNewTab: event.OpenInNewTab });\n break;\n case 'new-record':\n // Creating a related record from inside an open form: force a new tab so the\n // parent record stays intact in single-resource mode.\n this.navigationService.OpenNewEntityRecord(event.EntityName, {\n newRecordValues: event.DefaultValues,\n forceNewTab: true,\n });\n break;\n case 'entity-hierarchy':\n this.navigationService.OpenEntityRecord(event.EntityName, event.PrimaryKey);\n break;\n case 'external-link':\n window.open(event.Url, '_blank');\n break;\n case 'email':\n window.open(`mailto:${event.EmailAddress}`, '_self');\n break;\n case 'dismiss':\n this.recordDismissed.emit();\n break;\n case 'create-related': {\n // A FK field wants a new related record created. Open the related entity's form\n // as a dialog/slide-in (prefilled), then hand the saved record back so the field\n // can select it.\n const ref = this.formPresenter.Open({\n EntityName: event.EntityName,\n Presentation: event.Presentation ?? 'dialog',\n NewRecordValues: event.NewRecordValues,\n Provider: event.Provider,\n });\n ref.AfterSaved().then(created => event.Complete(created));\n break;\n }\n }\n }\n}\n","<mj-entity-form-host\n [EntityName]=\"entityName\"\n [PrimaryKey]=\"PrimaryKey\"\n [NewRecordValues]=\"newRecordValues\"\n [Provider]=\"Provider\"\n (LoadComplete)=\"onLoadComplete()\"\n (LoadError)=\"onLoadComplete()\"\n (RecordReady)=\"onRecordReady($event)\"\n (Saved)=\"onSaved($event)\"\n (Navigate)=\"handleNavigation($event)\"\n (Notification)=\"onNotification($event)\"\n (Dismissed)=\"recordDismissed.emit()\">\n</mj-entity-form-host>\n"]}
1
+ {"version":3,"file":"single-record.component.js","sourceRoot":"","sources":["../../../src/lib/single-record/single-record.component.ts","../../../src/lib/single-record/single-record.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, inject, Input, Output, ViewChild } from '@angular/core';\nimport { CompositeKey, BaseEntity } from '@memberjunction/core';\nimport { FormNavigationEvent, FormNotificationEvent, MJFormPresenterService, MjEntityFormHostComponent } from '@memberjunction/ng-base-forms';\nimport { NavigationService, RecentAccessService, SharedService } from '@memberjunction/ng-shared';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n/**\n * Explorer-side host for a single entity record in the main tab area.\n *\n * This is now a **thin wrapper** around the Generic `<mj-entity-form-host>`\n * (in `@memberjunction/ng-base-forms`), which owns all the mechanics: resolving\n * the form (class / custom / interactive override + variants), loading the\n * record, dynamically creating the form, binding it, and tearing it down.\n *\n * SingleRecordComponent's only remaining job is the **Explorer mapping**:\n * translating the host's framework-agnostic events into Explorer services —\n * `Navigate` → {@link NavigationService}, `Notification` → {@link SharedService},\n * record loads → {@link RecentAccessService} — none of which belong in a Generic\n * component.\n */\n@Component({\n standalone: false,\n selector: 'mj-single-record',\n templateUrl: './single-record.component.html',\n styleUrls: ['./single-record.component.css']\n})\nexport class SingleRecordComponent extends BaseAngularComponent {\n @Input() public PrimaryKey: CompositeKey = new CompositeKey();\n @Input() public entityName: string | null = '';\n @Input() public newRecordValues: string | Record<string, unknown> | null = '';\n\n @Output() public loadComplete: EventEmitter<void> = new EventEmitter<void>();\n @Output() public recordSaved: EventEmitter<BaseEntity> = new EventEmitter<BaseEntity>();\n /** Emitted when the hosted form asks to be dismissed (e.g. Discard on a new record). */\n @Output() public recordDismissed: EventEmitter<void> = new EventEmitter<void>();\n\n @ViewChild(MjEntityFormHostComponent) private formHost?: MjEntityFormHostComponent;\n\n /**\n * True while the hosted form is in edit mode. The host already exposes the\n * live form instance, so this is a read, not a new event pipeline.\n *\n * MJ forms are read-only until the user explicitly clicks Edit, so edit mode\n * is a deliberate gesture and a sound proxy for \"there is work in here worth\n * protecting\" — which is all the preview-tab replacement guard needs.\n */\n public IsEditing(): boolean {\n return this.formHost?.Form?.EditMode === true;\n }\n\n private navigationService = inject(NavigationService);\n private sharedService = inject(SharedService);\n private formPresenter = inject(MJFormPresenterService);\n private recentAccessService = new RecentAccessService();\n\n /** Unblock the shell's first-resource-load gate (success or error). */\n onLoadComplete(): void {\n this.loadComplete.emit();\n }\n\n /** Log access for existing records once the form's record is ready. */\n onRecordReady(record: BaseEntity): void {\n if (record?.IsSaved) {\n this.recentAccessService.logAccess(record.EntityInfo.Name, record.PrimaryKey, 'record');\n }\n }\n\n onSaved(record: BaseEntity): void {\n this.recordSaved.emit(record);\n }\n\n onNotification(event: FormNotificationEvent): void {\n this.sharedService.CreateSimpleNotification(event.Message, event.Type, event.Duration);\n }\n\n /** Map the form's navigation requests onto Explorer's NavigationService. */\n handleNavigation(event: FormNavigationEvent): void {\n switch (event.Kind) {\n case 'record':\n this.navigationService.OpenEntityRecord(event.EntityName, event.PrimaryKey, { forceNewTab: event.OpenInNewTab });\n break;\n case 'new-record':\n // Creating a related record from inside an open form: force a new tab so the\n // parent record stays intact in single-resource mode.\n this.navigationService.OpenNewEntityRecord(event.EntityName, {\n newRecordValues: event.DefaultValues,\n forceNewTab: true,\n });\n break;\n case 'entity-hierarchy':\n this.navigationService.OpenEntityRecord(event.EntityName, event.PrimaryKey);\n break;\n case 'external-link':\n window.open(event.Url, '_blank');\n break;\n case 'email':\n window.open(`mailto:${event.EmailAddress}`, '_self');\n break;\n case 'dismiss':\n this.recordDismissed.emit();\n break;\n case 'create-related': {\n // A FK field wants a new related record created. Open the related entity's form\n // as a dialog/slide-in (prefilled), then hand the saved record back so the field\n // can select it.\n const ref = this.formPresenter.Open({\n EntityName: event.EntityName,\n Presentation: event.Presentation ?? 'dialog',\n NewRecordValues: event.NewRecordValues,\n Provider: event.Provider,\n });\n ref.AfterSaved().then(created => event.Complete(created));\n break;\n }\n }\n }\n}\n","<mj-entity-form-host\n [EntityName]=\"entityName\"\n [PrimaryKey]=\"PrimaryKey\"\n [NewRecordValues]=\"newRecordValues\"\n [Provider]=\"Provider\"\n (LoadComplete)=\"onLoadComplete()\"\n (LoadError)=\"onLoadComplete()\"\n (RecordReady)=\"onRecordReady($event)\"\n (Saved)=\"onSaved($event)\"\n (Navigate)=\"handleNavigation($event)\"\n (Notification)=\"onNotification($event)\"\n (Dismissed)=\"recordDismissed.emit()\">\n</mj-entity-form-host>\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"single-search-result.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAyB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAEvI,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AACrE,KAAK,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEzE,qBAMa,2BAA4B,SAAQ,oBAAqB,YAAW,SAAS;IA8BtF,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,GAAG;IA9BG,MAAM,EAAE,MAAM,CAAM;IACpB,WAAW,EAAE,MAAM,CAAM;IACxB,YAAY,wBAA+B;IAC3C,WAAW,wBAA+B;IAEpD,WAAW,EAAE,WAAW,CAAa;IACrC,WAAW,SAAK;IAChB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;IAE5C,0EAA0E;IAC1E,IAAW,UAAU,IAAI,MAAM,CAK9B;IAED,8EAA8E;IACvE,YAAY,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAQ9C;gBAGQ,iBAAiB,EAAE,iBAAiB,EACpC,GAAG,EAAE,iBAAiB;IAIhC,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMzC;;;OAGG;YACW,aAAa;IA+B3B,OAAO,CAAC,cAAc;YAOR,WAAW;IAazB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,sBAAsB;IAavB,iBAAiB,IAAI,IAAI;IAQzB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAM1C,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAIrD,yGAAyG;IAClG,mBAAmB,CAAC,GAAG,EAAE,2BAA2B,GAAG,IAAI;IAMlE,oEAAoE;IACpE,OAAO,CAAC,gBAAgB;yCA9Ib,2BAA2B;2CAA3B,2BAA2B;CA4JvC"}
1
+ {"version":3,"file":"single-search-result.component.d.ts","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,iBAAiB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACpH,OAAO,EAAyB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAEvI,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AACrE,KAAK,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,QAAQ,CAAC;AAEzE,qBAMa,2BAA4B,SAAQ,oBAAqB,YAAW,SAAS;IA8BtF,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,GAAG;IA9BG,MAAM,EAAE,MAAM,CAAM;IACpB,WAAW,EAAE,MAAM,CAAM;IACxB,YAAY,wBAA+B;IAC3C,WAAW,wBAA+B;IAEpD,WAAW,EAAE,WAAW,CAAa;IACrC,WAAW,SAAK;IAChB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;IAE5C,0EAA0E;IAC1E,IAAW,UAAU,IAAI,MAAM,CAK9B;IAED,8EAA8E;IACvE,YAAY,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAQ9C;gBAGQ,iBAAiB,EAAE,iBAAiB,EACpC,GAAG,EAAE,iBAAiB;IAIhC,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAMzC;;;OAGG;YACW,aAAa;IA+B3B,OAAO,CAAC,cAAc;YAOR,WAAW;IAazB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,sBAAsB;IAavB,iBAAiB,IAAI,IAAI;IAQzB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAM1C,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAIrD,yGAAyG;IAClG,mBAAmB,CAAC,GAAG,EAAE,2BAA2B,GAAG,IAAI;IASlE,oEAAoE;IACpE,OAAO,CAAC,gBAAgB;yCAjJb,2BAA2B;2CAA3B,2BAA2B;CA+JvC"}
@@ -193,7 +193,10 @@ export class SingleSearchResultComponent extends BaseAngularComponent {
193
193
  /** Navigate to a related record requested from within a view-type renderer (e.g. a foreign-key cell). */
194
194
  OnOpenRelatedRecord(nav) {
195
195
  if (nav?.entityName && nav.recordKey != null) {
196
- this.navigationService.OpenEntityRecord(nav.entityName, CompositeKey.FromID(String(nav.recordKey)));
196
+ // The related entity is arbitrary, so its key column can have any name — resolve the key
197
+ // against its metadata rather than hardcoding `ID` via FromID.
198
+ const entityInfo = this.ProviderToUse.EntityByName(nav.entityName);
199
+ this.navigationService.OpenEntityRecord(nav.entityName, CompositeKey.FromURLSegment(entityInfo, String(nav.recordKey)));
197
200
  }
198
201
  }
199
202
  /** Format entity icon to ensure proper Font Awesome class format */
@@ -244,7 +247,7 @@ export class SingleSearchResultComponent extends BaseAngularComponent {
244
247
  i0.ɵɵconditional(ctx.SearchState === "single-result" ? 12 : -1);
245
248
  i0.ɵɵadvance();
246
249
  i0.ɵɵconditional(ctx.SearchState === "viewer" && ctx.EntityInfo ? 13 : -1);
247
- } }, dependencies: [i2.LoadingComponent, i3.EntityViewerComponent, i4.MJEmptyStateComponent, i5.DecimalPipe], styles: [".search-result-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n\n\n\n\n\n.content-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n flex-wrap: wrap;\n}\n\n.entity-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.entity-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.record-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n\n\n\n\n\n.header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-shrink: 0;\n}\n\n\n\n.header-action-btn[_ngcontent-%COMP%] {\n position: relative;\n width: 36px;\n height: 36px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n.header-action-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n.header-action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n padding: 3px;\n}\n\n.toggle-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n.toggle-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n.toggle-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 48px 0;\n}\n\n\n\n\n\n\n.search-result-empty-message[_ngcontent-%COMP%] {\n margin: 4px 0;\n font-size: 15px;\n}\n\n.empty-hint[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n\n\n\n\n\n.viewer-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n}"] });
250
+ } }, dependencies: [i2.LoadingComponent, i3.EntityViewerComponent, i4.MJEmptyStateComponent, i5.DecimalPipe], styles: [".search-result-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n\n\n\n\n.content-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 24px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n flex-wrap: wrap;\n}\n\n.entity-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-brand-primary);\n}\n\n.entity-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.record-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n\n\n\n\n.header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-shrink: 0;\n}\n\n\n.header-action-btn[_ngcontent-%COMP%] {\n position: relative;\n width: 36px;\n height: 36px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n.header-action-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n.header-action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n padding: 3px;\n}\n\n.toggle-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 32px;\n border: none;\n background: transparent;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n transition: all 0.15s ease;\n}\n.toggle-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n.toggle-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 48px 0;\n}\n\n\n\n\n\n.search-result-empty-message[_ngcontent-%COMP%] {\n margin: 4px 0;\n font-size: 15px;\n}\n\n.empty-hint[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n\n\n\n\n.viewer-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n}"] });
248
251
  }
249
252
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SingleSearchResultComponent, [{
250
253
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"single-search-result.component.js","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts","../../../src/lib/single-search-result/single-search-result.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';\nimport { RunView, CompositeKey, EntityInfo } from '@memberjunction/core';\nimport { NavigationService } from '@memberjunction/ng-shared';\nimport { DataLoadedEvent, RecordOpenedEvent, EntityViewerConfig, ViewRelatedRecordNavigation } from '@memberjunction/ng-entity-viewer';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\ntype SearchState = 'loading' | 'no-results' | 'single-result' | 'viewer';\n\n@Component({\n standalone: false,\n selector: 'mj-single-search-result',\n templateUrl: './single-search-result.component.html',\n styleUrls: ['./single-search-result.component.css']\n})\nexport class SingleSearchResultComponent extends BaseAngularComponent implements OnChanges {\n @Input() public entity: string = '';\n @Input() public searchInput: string = '';\n @Output() public loadComplete = new EventEmitter<boolean>();\n @Output() public loadStarted = new EventEmitter<boolean>();\n\n public SearchState: SearchState = 'loading';\n public ResultCount = 0;\n public EntityInfo: EntityInfo | null = null;\n\n /** Resolved icon class for the entity, matching Data Explorer's format */\n public get EntityIcon(): string {\n if (this.EntityInfo?.Icon) {\n return this.formatEntityIcon(this.EntityInfo.Icon);\n }\n return 'fa-solid fa-table';\n }\n\n /** Configuration for the entity-viewer — matches the Data Explorer's setup */\n public ViewerConfig: Partial<EntityViewerConfig> = {\n showFilter: false,\n showViewModeToggle: false,\n showRecordCount: false,\n showPagination: true,\n serverSideFiltering: true,\n serverSideSorting: true,\n height: '100%'\n };\n\n constructor(\n private navigationService: NavigationService,\n private cdr: ChangeDetectorRef\n ) {\n super();}\n\n ngOnChanges(changes: SimpleChanges): void {\n if ((changes['entity'] || changes['searchInput']) && this.entity && this.searchInput) {\n this.ExecuteSearch();\n }\n }\n\n /**\n * Runs a lightweight pre-query (MaxRows: 2, PK fields only) to determine result count,\n * then routes to the appropriate state: no-results, single-result auto-nav, or viewer.\n */\n private async ExecuteSearch(): Promise<void> {\n this.SearchState = 'loading';\n this.ResultCount = 0;\n this.loadStarted.emit(true);\n\n // Resolve EntityInfo early so the header can show icon + display name during loading\n const entityInfo = this.findEntityInfo();\n this.EntityInfo = entityInfo ?? null;\n this.cdr.detectChanges();\n\n if (!entityInfo) {\n this.setNoResults();\n return;\n }\n\n const result = await this.runPreQuery(entityInfo);\n if (!result.Success || result.Results.length === 0) {\n this.setNoResults();\n return;\n }\n\n if (result.Results.length === 1) {\n this.navigateToSingleResult(entityInfo, result.Results[0]);\n return;\n }\n\n // 2+ results — show the entity-viewer\n this.SearchState = 'viewer';\n this.cdr.detectChanges();\n }\n\n private findEntityInfo(): EntityInfo | undefined {\n const md = this.ProviderToUse;\n return md.Entities.find(e =>\n e.Name.trim().toLowerCase() === this.entity.trim().toLowerCase()\n );\n }\n\n private async runPreQuery(entityInfo: EntityInfo) {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const pkFields = entityInfo.PrimaryKeys.map(pk => pk.Name);\n return rv.RunView<Record<string, unknown>>({\n EntityName: this.entity,\n ExtraFilter: 'ID IS NOT NULL',\n UserSearchString: this.searchInput,\n Fields: pkFields,\n ResultType: 'simple',\n MaxRows: 2,\n });\n }\n\n private setNoResults(): void {\n this.SearchState = 'no-results';\n this.ResultCount = 0;\n this.loadComplete.emit(true);\n this.cdr.detectChanges();\n }\n\n private navigateToSingleResult(entityInfo: EntityInfo, record: Record<string, unknown>): void {\n this.SearchState = 'single-result';\n this.ResultCount = 1;\n this.cdr.detectChanges();\n\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromEntityInfoAndRecord(entityInfo, record);\n this.navigationService.OpenEntityRecord(entityInfo.Name, compositeKey);\n this.loadComplete.emit(true);\n }\n\n // ── Header action handlers ──\n\n public OnCreateNewRecord(): void {\n if (this.EntityInfo) {\n this.navigationService.OpenNewEntityRecord(this.EntityInfo.Name);\n }\n }\n\n // ── Entity-viewer event handlers ──\n\n public OnDataLoaded(event: DataLoadedEvent): void {\n this.ResultCount = event.totalRowCount;\n this.loadComplete.emit(true);\n this.cdr.detectChanges();\n }\n\n public OnRecordOpened(event: RecordOpenedEvent): void {\n this.navigationService.OpenEntityRecord(event.entity.Name, event.compositeKey);\n }\n\n /** Navigate to a related record requested from within a view-type renderer (e.g. a foreign-key cell). */\n public OnOpenRelatedRecord(nav: ViewRelatedRecordNavigation): void {\n if (nav?.entityName && nav.recordKey != null) {\n this.navigationService.OpenEntityRecord(nav.entityName, CompositeKey.FromID(String(nav.recordKey)));\n }\n }\n\n /** Format entity icon to ensure proper Font Awesome class format */\n private formatEntityIcon(icon: string): string {\n if (!icon) {\n return 'fa-solid fa-table';\n }\n if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||\n icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||\n icon.startsWith('fa ')) {\n return icon;\n }\n if (icon.startsWith('fa-')) {\n return `fa-solid ${icon}`;\n }\n return `fa-solid fa-${icon}`;\n }\n}\n","<div class=\"search-result-container\">\n <!-- Content Header — matches Data Explorer layout -->\n <div class=\"content-header\">\n <div class=\"header-left\">\n <i [class]=\"EntityIcon\" class=\"entity-icon\"></i>\n <h2 class=\"entity-title\">{{ EntityInfo?.DisplayNameOrName || entity }}</h2>\n @if (SearchState === 'loading') {\n <span class=\"record-count\">Searching for \"{{ searchInput }}\"...</span>\n } @else if (SearchState === 'no-results') {\n <span class=\"record-count\">No results for \"{{ searchInput }}\"</span>\n } @else if (ResultCount > 0) {\n <span class=\"record-count\">{{ ResultCount | number }} {{ ResultCount === 1 ? 'result' : 'results' }} for \"{{ searchInput }}\"</span>\n }\n </div>\n\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"header-right\">\n <!-- New Record -->\n <button\n class=\"header-action-btn\"\n (click)=\"OnCreateNewRecord()\"\n title=\"New Record\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n </div>\n\n <!-- Loading state -->\n @if (SearchState === 'loading') {\n <div class=\"loading-container\">\n <mj-loading text=\"Searching...\"></mj-loading>\n </div>\n }\n\n <!-- No results -->\n @if (SearchState === 'no-results') {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\">\n <p class=\"search-result-empty-message\">No results found for \"<strong>{{ searchInput }}</strong>\" in {{ entity }}</p>\n <p class=\"empty-hint\">Try a different search term or entity</p>\n </mj-empty-state>\n }\n\n <!-- Single result — auto-navigating to entity form -->\n @if (SearchState === 'single-result') {\n <mj-empty-state\n Icon=\"fa-solid fa-arrow-right\"\n Title=\"Found 1 result — opening record...\" />\n }\n\n <!-- Entity Viewer (2+ results) -->\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"viewer-container\">\n <mj-entity-viewer\n [Entity]=\"EntityInfo\"\n [Provider]=\"Provider\"\n [FilterText]=\"searchInput\"\n [Config]=\"ViewerConfig\"\n (DataLoaded)=\"OnDataLoaded($event)\"\n (RecordOpened)=\"OnRecordOpened($event)\"\n (OpenRelatedRecordRequested)=\"OnOpenRelatedRecord($event)\"\n (CreateRecordRequested)=\"OnCreateNewRecord()\">\n </mj-entity-viewer>\n </div>\n }\n</div>\n"]}
1
+ {"version":3,"file":"single-search-result.component.js","sourceRoot":"","sources":["../../../src/lib/single-search-result/single-search-result.component.ts","../../../src/lib/single-search-result/single-search-result.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';\nimport { RunView, CompositeKey, EntityInfo } from '@memberjunction/core';\nimport { NavigationService } from '@memberjunction/ng-shared';\nimport { DataLoadedEvent, RecordOpenedEvent, EntityViewerConfig, ViewRelatedRecordNavigation } from '@memberjunction/ng-entity-viewer';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\ntype SearchState = 'loading' | 'no-results' | 'single-result' | 'viewer';\n\n@Component({\n standalone: false,\n selector: 'mj-single-search-result',\n templateUrl: './single-search-result.component.html',\n styleUrls: ['./single-search-result.component.css']\n})\nexport class SingleSearchResultComponent extends BaseAngularComponent implements OnChanges {\n @Input() public entity: string = '';\n @Input() public searchInput: string = '';\n @Output() public loadComplete = new EventEmitter<boolean>();\n @Output() public loadStarted = new EventEmitter<boolean>();\n\n public SearchState: SearchState = 'loading';\n public ResultCount = 0;\n public EntityInfo: EntityInfo | null = null;\n\n /** Resolved icon class for the entity, matching Data Explorer's format */\n public get EntityIcon(): string {\n if (this.EntityInfo?.Icon) {\n return this.formatEntityIcon(this.EntityInfo.Icon);\n }\n return 'fa-solid fa-table';\n }\n\n /** Configuration for the entity-viewer — matches the Data Explorer's setup */\n public ViewerConfig: Partial<EntityViewerConfig> = {\n showFilter: false,\n showViewModeToggle: false,\n showRecordCount: false,\n showPagination: true,\n serverSideFiltering: true,\n serverSideSorting: true,\n height: '100%'\n };\n\n constructor(\n private navigationService: NavigationService,\n private cdr: ChangeDetectorRef\n ) {\n super();}\n\n ngOnChanges(changes: SimpleChanges): void {\n if ((changes['entity'] || changes['searchInput']) && this.entity && this.searchInput) {\n this.ExecuteSearch();\n }\n }\n\n /**\n * Runs a lightweight pre-query (MaxRows: 2, PK fields only) to determine result count,\n * then routes to the appropriate state: no-results, single-result auto-nav, or viewer.\n */\n private async ExecuteSearch(): Promise<void> {\n this.SearchState = 'loading';\n this.ResultCount = 0;\n this.loadStarted.emit(true);\n\n // Resolve EntityInfo early so the header can show icon + display name during loading\n const entityInfo = this.findEntityInfo();\n this.EntityInfo = entityInfo ?? null;\n this.cdr.detectChanges();\n\n if (!entityInfo) {\n this.setNoResults();\n return;\n }\n\n const result = await this.runPreQuery(entityInfo);\n if (!result.Success || result.Results.length === 0) {\n this.setNoResults();\n return;\n }\n\n if (result.Results.length === 1) {\n this.navigateToSingleResult(entityInfo, result.Results[0]);\n return;\n }\n\n // 2+ results — show the entity-viewer\n this.SearchState = 'viewer';\n this.cdr.detectChanges();\n }\n\n private findEntityInfo(): EntityInfo | undefined {\n const md = this.ProviderToUse;\n return md.Entities.find(e =>\n e.Name.trim().toLowerCase() === this.entity.trim().toLowerCase()\n );\n }\n\n private async runPreQuery(entityInfo: EntityInfo) {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const pkFields = entityInfo.PrimaryKeys.map(pk => pk.Name);\n return rv.RunView<Record<string, unknown>>({\n EntityName: this.entity,\n ExtraFilter: 'ID IS NOT NULL',\n UserSearchString: this.searchInput,\n Fields: pkFields,\n ResultType: 'simple',\n MaxRows: 2,\n });\n }\n\n private setNoResults(): void {\n this.SearchState = 'no-results';\n this.ResultCount = 0;\n this.loadComplete.emit(true);\n this.cdr.detectChanges();\n }\n\n private navigateToSingleResult(entityInfo: EntityInfo, record: Record<string, unknown>): void {\n this.SearchState = 'single-result';\n this.ResultCount = 1;\n this.cdr.detectChanges();\n\n const compositeKey = new CompositeKey();\n compositeKey.LoadFromEntityInfoAndRecord(entityInfo, record);\n this.navigationService.OpenEntityRecord(entityInfo.Name, compositeKey);\n this.loadComplete.emit(true);\n }\n\n // ── Header action handlers ──\n\n public OnCreateNewRecord(): void {\n if (this.EntityInfo) {\n this.navigationService.OpenNewEntityRecord(this.EntityInfo.Name);\n }\n }\n\n // ── Entity-viewer event handlers ──\n\n public OnDataLoaded(event: DataLoadedEvent): void {\n this.ResultCount = event.totalRowCount;\n this.loadComplete.emit(true);\n this.cdr.detectChanges();\n }\n\n public OnRecordOpened(event: RecordOpenedEvent): void {\n this.navigationService.OpenEntityRecord(event.entity.Name, event.compositeKey);\n }\n\n /** Navigate to a related record requested from within a view-type renderer (e.g. a foreign-key cell). */\n public OnOpenRelatedRecord(nav: ViewRelatedRecordNavigation): void {\n if (nav?.entityName && nav.recordKey != null) {\n // The related entity is arbitrary, so its key column can have any name — resolve the key\n // against its metadata rather than hardcoding `ID` via FromID.\n const entityInfo = this.ProviderToUse.EntityByName(nav.entityName);\n this.navigationService.OpenEntityRecord(nav.entityName, CompositeKey.FromURLSegment(entityInfo, String(nav.recordKey)));\n }\n }\n\n /** Format entity icon to ensure proper Font Awesome class format */\n private formatEntityIcon(icon: string): string {\n if (!icon) {\n return 'fa-solid fa-table';\n }\n if (icon.startsWith('fa-solid') || icon.startsWith('fa-regular') ||\n icon.startsWith('fa-light') || icon.startsWith('fa-brands') ||\n icon.startsWith('fa ')) {\n return icon;\n }\n if (icon.startsWith('fa-')) {\n return `fa-solid ${icon}`;\n }\n return `fa-solid fa-${icon}`;\n }\n}\n","<div class=\"search-result-container\">\n <!-- Content Header — matches Data Explorer layout -->\n <div class=\"content-header\">\n <div class=\"header-left\">\n <i [class]=\"EntityIcon\" class=\"entity-icon\"></i>\n <h2 class=\"entity-title\">{{ EntityInfo?.DisplayNameOrName || entity }}</h2>\n @if (SearchState === 'loading') {\n <span class=\"record-count\">Searching for \"{{ searchInput }}\"...</span>\n } @else if (SearchState === 'no-results') {\n <span class=\"record-count\">No results for \"{{ searchInput }}\"</span>\n } @else if (ResultCount > 0) {\n <span class=\"record-count\">{{ ResultCount | number }} {{ ResultCount === 1 ? 'result' : 'results' }} for \"{{ searchInput }}\"</span>\n }\n </div>\n\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"header-right\">\n <!-- New Record -->\n <button\n class=\"header-action-btn\"\n (click)=\"OnCreateNewRecord()\"\n title=\"New Record\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n </div>\n\n <!-- Loading state -->\n @if (SearchState === 'loading') {\n <div class=\"loading-container\">\n <mj-loading text=\"Searching...\"></mj-loading>\n </div>\n }\n\n <!-- No results -->\n @if (SearchState === 'no-results') {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\">\n <p class=\"search-result-empty-message\">No results found for \"<strong>{{ searchInput }}</strong>\" in {{ entity }}</p>\n <p class=\"empty-hint\">Try a different search term or entity</p>\n </mj-empty-state>\n }\n\n <!-- Single result — auto-navigating to entity form -->\n @if (SearchState === 'single-result') {\n <mj-empty-state\n Icon=\"fa-solid fa-arrow-right\"\n Title=\"Found 1 result — opening record...\" />\n }\n\n <!-- Entity Viewer (2+ results) -->\n @if (SearchState === 'viewer' && EntityInfo) {\n <div class=\"viewer-container\">\n <mj-entity-viewer\n [Entity]=\"EntityInfo\"\n [Provider]=\"Provider\"\n [FilterText]=\"searchInput\"\n [Config]=\"ViewerConfig\"\n (DataLoaded)=\"OnDataLoaded($event)\"\n (RecordOpened)=\"OnRecordOpened($event)\"\n (OpenRelatedRecordRequested)=\"OnOpenRelatedRecord($event)\"\n (CreateRecordRequested)=\"OnCreateNewRecord()\">\n </mj-entity-viewer>\n </div>\n }\n</div>\n"]}
@@ -234,9 +234,8 @@ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Ca
234
234
  i0.ɵɵtextInterpolate(vm_r10.N.Message);
235
235
  } }
236
236
  function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Template(rf, ctx) { if (rf & 1) {
237
- const _r11 = i0.ɵɵgetCurrentView();
238
237
  i0.ɵɵelementStart(0, "div", 60);
239
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
238
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
240
239
  i0.ɵɵconditionalCreate(1, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_1_Template, 1, 1, "div", 61)(2, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_2_Template, 1, 2, "mj-markdown", 62)(3, UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Case_3_Template, 2, 1, "p", 63);
241
240
  i0.ɵɵelementEnd();
242
241
  } if (rf & 2) {
@@ -246,9 +245,9 @@ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_17_Te
246
245
  i0.ɵɵconditional((tmp_22_0 = vm_r10.Kind) === "html" ? 1 : tmp_22_0 === "markdown" ? 2 : 3);
247
246
  } }
248
247
  function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_18_Template(rf, ctx) { if (rf & 1) {
249
- const _r12 = i0.ɵɵgetCurrentView();
248
+ const _r11 = i0.ɵɵgetCurrentView();
250
249
  i0.ɵɵelementStart(0, "button", 64);
251
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_18_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r12); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.ToggleExpanded(vm_r10, $event)); });
250
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_18_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r11); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.ToggleExpanded(vm_r10, $event)); });
252
251
  i0.ɵɵelement(1, "i", 65);
253
252
  i0.ɵɵtext(2);
254
253
  i0.ɵɵelementEnd();
@@ -262,9 +261,9 @@ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_18_Te
262
261
  i0.ɵɵtextInterpolate1(" ", ctx_r0.IsExpanded(vm_r10) ? "Show less" : "Show more", " ");
263
262
  } }
264
263
  function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_20_Template(rf, ctx) { if (rf & 1) {
265
- const _r13 = i0.ɵɵgetCurrentView();
264
+ const _r12 = i0.ɵɵgetCurrentView();
266
265
  i0.ɵɵelementStart(0, "button", 66);
267
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_20_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.markAsRead(vm_r10.N, true, null)); });
266
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_20_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.markAsRead(vm_r10.N, true, null)); });
268
267
  i0.ɵɵelement(1, "i", 67);
269
268
  i0.ɵɵelementStart(2, "span", 68);
270
269
  i0.ɵɵtext(3, "Read");
@@ -274,9 +273,9 @@ function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_20_Te
274
273
  i0.ɵɵattribute("aria-label", "Mark " + vm_r10.N.Title + " as read");
275
274
  } }
276
275
  function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_21_Template(rf, ctx) { if (rf & 1) {
277
- const _r14 = i0.ɵɵgetCurrentView();
276
+ const _r13 = i0.ɵɵgetCurrentView();
278
277
  i0.ɵɵelementStart(0, "button", 69);
279
- i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_21_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.markAsRead(vm_r10.N, false, null)); });
278
+ i0.ɵɵlistener("click", function UserNotificationsComponent_Conditional_16_For_2_For_3_Conditional_21_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const vm_r10 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.markAsRead(vm_r10.N, false, null)); });
280
279
  i0.ɵɵelement(1, "i", 20);
281
280
  i0.ɵɵelementStart(2, "span", 68);
282
281
  i0.ɵɵtext(3, "Unread");
@@ -345,11 +344,11 @@ function UserNotificationsComponent_Conditional_16_For_2_Template(rf, ctx) { if
345
344
  i0.ɵɵelementEnd();
346
345
  i0.ɵɵrepeaterCreate(2, UserNotificationsComponent_Conditional_16_For_2_For_3_Template, 22, 24, "article", 42, _forTrack2);
347
346
  } if (rf & 2) {
348
- const group_r15 = ctx.$implicit;
347
+ const group_r14 = ctx.$implicit;
349
348
  i0.ɵɵadvance();
350
- i0.ɵɵtextInterpolate(group_r15.Label);
349
+ i0.ɵɵtextInterpolate(group_r14.Label);
351
350
  i0.ɵɵadvance();
352
- i0.ɵɵrepeater(group_r15.Items);
351
+ i0.ɵɵrepeater(group_r14.Items);
353
352
  } }
354
353
  function UserNotificationsComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
355
354
  i0.ɵɵelementStart(0, "div", 13);
@@ -908,7 +907,7 @@ export class UserNotificationsComponent extends BaseAngularComponent {
908
907
  i0.ɵɵconditional(ctx.AllNotifications.length > 0 ? 12 : -1);
909
908
  i0.ɵɵadvance(2);
910
909
  i0.ɵɵconditional(ctx.NotificationsToShow.length === 0 && ctx.AllNotifications.length === 0 ? 14 : ctx.NotificationsToShow.length === 0 ? 15 : 16);
911
- } }, dependencies: [i3.MarkdownComponent, i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.SelectControlValueAccessor, i4.NgControlStatus, i4.NgModel, i5.MJEmptyStateComponent, i6.DatePipe], styles: ["\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.notifications-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n}\n\n\n\n\n.notifications-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 20px 24px 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-top[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 14px;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.title-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: var(--mj-radius-lg, 12px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.title-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.title-text[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.title-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s, border-color 0.15s;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n}\n\n.filters-slider[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.slider-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.header-stats[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 4px;\n padding: 3px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n}\n\n.stat-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.stat-pill[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.stat-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stat-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-text-muted) 14%, transparent);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.stat-count.unread-count[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.type-select[_ngcontent-%COMP%] {\n padding: 7px 10px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.search-section[_ngcontent-%COMP%] {\n flex: 1 1 220px;\n min-width: 180px;\n}\n\n.search-container[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 32px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n\n.filter-info[_ngcontent-%COMP%] {\n flex-basis: 100%;\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 11px;\n font-weight: 600;\n}\n\n\n\n\n.notifications-content[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: 16px 24px 32px 24px;\n}\n\n.notifications-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n max-width: 960px;\n margin: 0 auto;\n}\n\n.group-label[_ngcontent-%COMP%] {\n position: sticky;\n top: -16px;\n z-index: 1;\n padding: 10px 2px 4px 2px;\n background: var(--mj-bg-page);\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n}\n\n.group-label[_ngcontent-%COMP%]:not(:first-child) {\n margin-top: 8px;\n}\n\n\n\n\n.notification-card[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 12px);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;\n overflow: hidden;\n}\n\n.notification-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.notification-card.unread[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.card-indicator[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n border-radius: 0 2px 2px 0;\n}\n\n.notification-card.unread[_ngcontent-%COMP%] .card-indicator[_ngcontent-%COMP%] {\n display: block;\n}\n\n.card-icon[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md, 10px);\n background: var(--mj-bg-surface-sunken);\n font-size: 14px;\n}\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.notification-card.clickable[_ngcontent-%COMP%] .card-content[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow-wrap: anywhere;\n}\n\n.card-title-unread[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.card-time[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 3px 0 6px 0;\n}\n\n.card-type[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n.card-open-hint[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.notification-card.clickable[_ngcontent-%COMP%]:hover .card-open-hint[_ngcontent-%COMP%] {\n display: inline-flex;\n}\n\n.card-message[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n\n.card-message-full[_ngcontent-%COMP%] {\n display: block;\n -webkit-line-clamp: unset;\n white-space: pre-wrap;\n}\n\n\n\n\n.card-rich[_ngcontent-%COMP%] {\n margin-top: 4px;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-card);\n cursor: default;\n}\n\n\n\n.card-rich-html[_ngcontent-%COMP%] {\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n overflow-x: auto;\n}\n\n.card-rich-html[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n max-width: 100%;\n height: auto;\n}\n\n.card-rich-html[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n max-width: 100%;\n border-collapse: collapse;\n}\n\n.card-rich-html[_ngcontent-%COMP%] td[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 4px 8px;\n border: 1px solid var(--mj-border-subtle);\n}\n\n.card-rich-html[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n\n.card-rich-html[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0.4em 0 0.3em 0;\n font-size: 1.05em;\n}\n\n.card-rich-md[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n}\n\n.card-expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n padding: 4px 10px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 700;\n cursor: pointer;\n}\n\n.card-expand-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n\n\n\n.card-actions[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: flex-start;\n}\n\n.card-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid transparent;\n border-radius: var(--mj-radius-md, 8px);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.card-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n\n\n\n@media (max-width: 720px) {\n .notifications-header[_ngcontent-%COMP%] {\n padding: 14px 14px 10px 14px;\n }\n\n .notifications-content[_ngcontent-%COMP%] {\n padding: 12px 12px 24px 12px;\n }\n\n .btn-text[_ngcontent-%COMP%], \n .action-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .card-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 2px;\n }\n\n .card-time[_ngcontent-%COMP%] {\n order: -1;\n }\n}"] });
910
+ } }, dependencies: [i3.MarkdownComponent, i4.NgSelectOption, i4.ɵNgSelectMultipleOption, i4.SelectControlValueAccessor, i4.NgControlStatus, i4.NgModel, i5.MJEmptyStateComponent, i6.DatePipe], styles: ["\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.notifications-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n}\n\n\n\n.notifications-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 20px 24px 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-top[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 14px;\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.title-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: var(--mj-radius-lg, 12px);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n.title-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.title-text[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1.2;\n}\n\n.title-subtitle[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s, border-color 0.15s;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.action-btn-ghost[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n}\n\n.filters-slider[_ngcontent-%COMP%] {\n min-width: 0;\n}\n\n.slider-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.header-stats[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 4px;\n padding: 3px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n}\n\n.stat-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 12px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.stat-pill[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.stat-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.stat-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-text-muted) 14%, transparent);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n}\n\n.stat-count.unread-count[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.type-select[_ngcontent-%COMP%] {\n padding: 7px 10px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n cursor: pointer;\n}\n\n.search-section[_ngcontent-%COMP%] {\n flex: 1 1 220px;\n min-width: 180px;\n}\n\n.search-container[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n\n.search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 8px 12px 8px 32px;\n border-radius: var(--mj-radius-md, 8px);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n}\n\n.filter-info[_ngcontent-%COMP%] {\n flex-basis: 100%;\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 11px;\n font-weight: 600;\n}\n\n\n\n.notifications-content[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: 16px 24px 32px 24px;\n}\n\n.notifications-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n max-width: 960px;\n margin: 0 auto;\n}\n\n.group-label[_ngcontent-%COMP%] {\n position: sticky;\n top: -16px;\n z-index: 1;\n padding: 10px 2px 4px 2px;\n background: var(--mj-bg-page);\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n}\n\n.group-label[_ngcontent-%COMP%]:not(:first-child) {\n margin-top: 8px;\n}\n\n\n\n.notification-card[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 12px);\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;\n overflow: hidden;\n}\n\n.notification-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.notification-card.unread[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.card-indicator[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n border-radius: 0 2px 2px 0;\n}\n\n.notification-card.unread[_ngcontent-%COMP%] .card-indicator[_ngcontent-%COMP%] {\n display: block;\n}\n\n.card-icon[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md, 10px);\n background: var(--mj-bg-surface-sunken);\n font-size: 14px;\n}\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.notification-card.clickable[_ngcontent-%COMP%] .card-content[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 12px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow-wrap: anywhere;\n}\n\n.card-title-unread[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.card-time[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 3px 0 6px 0;\n}\n\n.card-type[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n.card-open-hint[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n}\n\n.notification-card.clickable[_ngcontent-%COMP%]:hover .card-open-hint[_ngcontent-%COMP%] {\n display: inline-flex;\n}\n\n.card-message[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n\n.card-message-full[_ngcontent-%COMP%] {\n display: block;\n -webkit-line-clamp: unset;\n white-space: pre-wrap;\n}\n\n\n\n.card-rich[_ngcontent-%COMP%] {\n margin-top: 4px;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-subtle);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-card);\n cursor: default;\n}\n\n\n.card-rich-html[_ngcontent-%COMP%] {\n font-size: 13px;\n line-height: 1.55;\n color: var(--mj-text-primary);\n overflow-x: auto;\n}\n\n.card-rich-html[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n max-width: 100%;\n height: auto;\n}\n\n.card-rich-html[_ngcontent-%COMP%] table[_ngcontent-%COMP%] {\n max-width: 100%;\n border-collapse: collapse;\n}\n\n.card-rich-html[_ngcontent-%COMP%] td[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 4px 8px;\n border: 1px solid var(--mj-border-subtle);\n}\n\n.card-rich-html[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--mj-text-link);\n}\n\n.card-rich-html[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], \n.card-rich-html[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0.4em 0 0.3em 0;\n font-size: 1.05em;\n}\n\n.card-rich-md[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n}\n\n.card-expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n padding: 4px 10px;\n border: none;\n border-radius: var(--mj-radius-full, 999px);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 700;\n cursor: pointer;\n}\n\n.card-expand-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n\n\n.card-actions[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n align-items: flex-start;\n}\n\n.card-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: 1px solid transparent;\n border-radius: var(--mj-radius-md, 8px);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.15s, color 0.15s;\n}\n\n.card-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n\n\n@media (max-width: 720px) {\n .notifications-header[_ngcontent-%COMP%] {\n padding: 14px 14px 10px 14px;\n }\n\n .notifications-content[_ngcontent-%COMP%] {\n padding: 12px 12px 24px 12px;\n }\n\n .btn-text[_ngcontent-%COMP%], \n .action-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .card-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 2px;\n }\n\n .card-time[_ngcontent-%COMP%] {\n order: -1;\n }\n}"] });
912
911
  }
913
912
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserNotificationsComponent, [{
914
913
  type: Component,