@memberjunction/ng-explorer-core 5.50.0 → 6.1.0-edge.0

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 (55) hide show
  1. package/LICENSE +7 -0
  2. package/dist/app-routing.module.d.ts.map +1 -1
  3. package/dist/app-routing.module.js +5 -5
  4. package/dist/app-routing.module.js.map +1 -1
  5. package/dist/generated/lazy-feature-config.d.ts +11 -2
  6. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  7. package/dist/generated/lazy-feature-config.js +79 -23
  8. package/dist/generated/lazy-feature-config.js.map +1 -1
  9. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  10. package/dist/lib/resource-wrappers/dashboard-resource.component.js +28 -0
  11. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  12. package/dist/lib/services/lazy-module-registry.d.ts +48 -8
  13. package/dist/lib/services/lazy-module-registry.d.ts.map +1 -1
  14. package/dist/lib/services/lazy-module-registry.js +103 -23
  15. package/dist/lib/services/lazy-module-registry.js.map +1 -1
  16. package/dist/lib/shell/components/header/app-nav.component.d.ts +2 -1
  17. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
  18. package/dist/lib/shell/components/header/app-nav.component.js +58 -42
  19. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  20. package/dist/lib/shell/components/record-open/record-bar.component.d.ts +29 -0
  21. package/dist/lib/shell/components/record-open/record-bar.component.d.ts.map +1 -0
  22. package/dist/lib/shell/components/record-open/record-bar.component.js +72 -0
  23. package/dist/lib/shell/components/record-open/record-bar.component.js.map +1 -0
  24. package/dist/lib/shell/components/record-open/record-origin-crumb.component.d.ts +26 -0
  25. package/dist/lib/shell/components/record-open/record-origin-crumb.component.d.ts.map +1 -0
  26. package/dist/lib/shell/components/record-open/record-origin-crumb.component.js +140 -0
  27. package/dist/lib/shell/components/record-open/record-origin-crumb.component.js.map +1 -0
  28. package/dist/lib/shell/components/record-open/record-switcher-sheet.component.d.ts +43 -0
  29. package/dist/lib/shell/components/record-open/record-switcher-sheet.component.d.ts.map +1 -0
  30. package/dist/lib/shell/components/record-open/record-switcher-sheet.component.js +102 -0
  31. package/dist/lib/shell/components/record-open/record-switcher-sheet.component.js.map +1 -0
  32. package/dist/lib/shell/components/record-open/record-switcher.service.d.ts +21 -0
  33. package/dist/lib/shell/components/record-open/record-switcher.service.d.ts.map +1 -0
  34. package/dist/lib/shell/components/record-open/record-switcher.service.js +30 -0
  35. package/dist/lib/shell/components/record-open/record-switcher.service.js.map +1 -0
  36. package/dist/lib/shell/components/record-open/records-hub-pill.component.d.ts +63 -0
  37. package/dist/lib/shell/components/record-open/records-hub-pill.component.d.ts.map +1 -0
  38. package/dist/lib/shell/components/record-open/records-hub-pill.component.js +143 -0
  39. package/dist/lib/shell/components/record-open/records-hub-pill.component.js.map +1 -0
  40. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +228 -2
  41. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  42. package/dist/lib/shell/components/tabs/tab-container.component.js +1073 -113
  43. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  44. package/dist/lib/shell/services/sharing-center-dialog-host.component.d.ts.map +1 -1
  45. package/dist/lib/shell/services/sharing-center-dialog-host.component.js +2 -0
  46. package/dist/lib/shell/services/sharing-center-dialog-host.component.js.map +1 -1
  47. package/dist/lib/shell/shell.component.d.ts +41 -4
  48. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  49. package/dist/lib/shell/shell.component.js +400 -240
  50. package/dist/lib/shell/shell.component.js.map +1 -1
  51. package/dist/lib/shell/shell.module.d.ts +4 -1
  52. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  53. package/dist/lib/shell/shell.module.js +14 -3
  54. package/dist/lib/shell/shell.module.js.map +1 -1
  55. package/package.json +62 -59
@@ -0,0 +1,29 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Mobile record bar — the records region's chrome below the shell breakpoint,
5
+ * where the golden-layout tab strip is unusable (one tab fits, the rest are
6
+ * unreachable). Shows the ACTIVE record (entity type icon tinted with its
7
+ * app color + title) and the open-record count; the whole bar is one button
8
+ * that opens the record switcher sheet.
9
+ *
10
+ * Dumb by design: tab-container computes every input from the workspace
11
+ * configuration (it already tracks active tab, app colors, and type icons
12
+ * for the strip) — the bar renders and emits, nothing more.
13
+ */
14
+ export declare class RecordBarComponent {
15
+ /** Active record's title */
16
+ Title: string;
17
+ /** Active record's entity TYPE icon (FontAwesome classes) */
18
+ Icon: string;
19
+ /** Active record's app color (runtime data — binds as an inline style) */
20
+ Color: string;
21
+ /** Open record count (region + docked — matches the switcher sheet rows) */
22
+ Count: number;
23
+ /** The bar was tapped — open the record switcher */
24
+ SwitcherRequested: EventEmitter<void>;
25
+ OnBarClick(): void;
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<RecordBarComponent, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<RecordBarComponent, "mj-record-bar", never, { "Title": { "alias": "Title"; "required": false; }; "Icon": { "alias": "Icon"; "required": false; }; "Color": { "alias": "Color"; "required": false; }; "Count": { "alias": "Count"; "required": false; }; }, { "SwitcherRequested": "SwitcherRequested"; }, never, never, true, never>;
28
+ }
29
+ //# sourceMappingURL=record-bar.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-bar.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-bar.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,MAAM,eAAe,CAAC;;AAEvE;;;;;;;;;;GAUG;AACH,qBAMa,kBAAkB;IAC7B,4BAA4B;IACnB,KAAK,SAAM;IACpB,6DAA6D;IACpD,IAAI,SAA8B;IAC3C,0EAA0E;IACjE,KAAK,SAAM;IACpB,4EAA4E;IACnE,KAAK,SAAK;IAEnB,oDAAoD;IAC1C,iBAAiB,qBAA4B;IAEvD,UAAU,IAAI,IAAI;yCAbP,kBAAkB;2CAAlB,kBAAkB;CAgB9B"}
@@ -0,0 +1,72 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Mobile record bar — the records region's chrome below the shell breakpoint,
5
+ * where the golden-layout tab strip is unusable (one tab fits, the rest are
6
+ * unreachable). Shows the ACTIVE record (entity type icon tinted with its
7
+ * app color + title) and the open-record count; the whole bar is one button
8
+ * that opens the record switcher sheet.
9
+ *
10
+ * Dumb by design: tab-container computes every input from the workspace
11
+ * configuration (it already tracks active tab, app colors, and type icons
12
+ * for the strip) — the bar renders and emits, nothing more.
13
+ */
14
+ export class RecordBarComponent {
15
+ /** Active record's title */
16
+ Title = '';
17
+ /** Active record's entity TYPE icon (FontAwesome classes) */
18
+ Icon = 'fa-regular fa-file-lines';
19
+ /** Active record's app color (runtime data — binds as an inline style) */
20
+ Color = '';
21
+ /** Open record count (region + docked — matches the switcher sheet rows) */
22
+ Count = 0;
23
+ /** The bar was tapped — open the record switcher */
24
+ SwitcherRequested = new EventEmitter();
25
+ OnBarClick() {
26
+ this.SwitcherRequested.emit();
27
+ }
28
+ static ɵfac = function RecordBarComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordBarComponent)(); };
29
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordBarComponent, selectors: [["mj-record-bar"]], inputs: { Title: "Title", Icon: "Icon", Color: "Color", Count: "Count" }, outputs: { SwitcherRequested: "SwitcherRequested" }, decls: 10, vars: 7, consts: [["type", "button", "aria-haspopup", "dialog", 1, "record-bar", 3, "click"], ["aria-hidden", "true", 1, "record-bar-icon"], [1, "record-bar-title"], ["aria-hidden", "true", 1, "record-bar-count"], [1, "fa-regular", "fa-folder-open"], [1, "record-bar-count-num"], [1, "fa-solid", "fa-chevron-down", "record-bar-chevron"]], template: function RecordBarComponent_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵdomElementStart(0, "button", 0);
31
+ i0.ɵɵdomListener("click", function RecordBarComponent_Template_button_click_0_listener() { return ctx.OnBarClick(); });
32
+ i0.ɵɵdomElementStart(1, "span", 1);
33
+ i0.ɵɵdomElement(2, "i");
34
+ i0.ɵɵdomElementEnd();
35
+ i0.ɵɵdomElementStart(3, "span", 2);
36
+ i0.ɵɵtext(4);
37
+ i0.ɵɵdomElementEnd();
38
+ i0.ɵɵdomElementStart(5, "span", 3);
39
+ i0.ɵɵdomElement(6, "i", 4);
40
+ i0.ɵɵdomElementStart(7, "span", 5);
41
+ i0.ɵɵtext(8);
42
+ i0.ɵɵdomElementEnd();
43
+ i0.ɵɵdomElement(9, "i", 6);
44
+ i0.ɵɵdomElementEnd()();
45
+ } if (rf & 2) {
46
+ i0.ɵɵattribute("aria-label", "Switch records \u2014 " + ctx.Count + " open");
47
+ i0.ɵɵadvance();
48
+ i0.ɵɵstyleProp("color", ctx.Color || null);
49
+ i0.ɵɵadvance();
50
+ i0.ɵɵclassMap(ctx.Icon);
51
+ i0.ɵɵadvance(2);
52
+ i0.ɵɵtextInterpolate(ctx.Title);
53
+ i0.ɵɵadvance(4);
54
+ i0.ɵɵtextInterpolate(ctx.Count);
55
+ } }, styles: ["[_nghost-%COMP%] {\n display: block;\n flex-shrink: 0;\n}\n\n.record-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 9px;\n width: 100%;\n height: 44px; \n\n padding: 0 10px 0 12px;\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n \n\n background: var(--mj-bg-surface);\n font-family: inherit;\n cursor: pointer;\n text-align: left;\n}\n\n.record-bar[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-hover);\n}\n\n.record-bar[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n}\n\n.record-bar-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border-radius: 7px;\n flex-shrink: 0;\n font-size: 13px;\n \n\n background: color-mix(in srgb, currentColor 14%, transparent);\n}\n\n.record-bar-title[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-size: var(--mj-text-sm, 14px);\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.record-bar-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n flex-shrink: 0;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 12.5px;\n font-weight: 700;\n color: var(--mj-text-secondary);\n}\n\n.record-bar-chevron[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-muted);\n}"] });
56
+ }
57
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordBarComponent, [{
58
+ type: Component,
59
+ args: [{ selector: 'mj-record-bar', standalone: true, template: "<button\n type=\"button\"\n class=\"record-bar\"\n [attr.aria-label]=\"'Switch records \u2014 ' + Count + ' open'\"\n aria-haspopup=\"dialog\"\n (click)=\"OnBarClick()\">\n <span class=\"record-bar-icon\" [style.color]=\"Color || null\" aria-hidden=\"true\">\n <i [class]=\"Icon\"></i>\n </span>\n <span class=\"record-bar-title\">{{ Title }}</span>\n <span class=\"record-bar-count\" aria-hidden=\"true\">\n <i class=\"fa-regular fa-folder-open\"></i>\n <span class=\"record-bar-count-num\">{{ Count }}</span>\n <i class=\"fa-solid fa-chevron-down record-bar-chevron\"></i>\n </span>\n</button>\n", styles: [":host {\n display: block;\n flex-shrink: 0;\n}\n\n.record-bar {\n display: flex;\n align-items: center;\n gap: 9px;\n width: 100%;\n height: 44px; /* touch target \u2014 WCAG 2.5.8 comfortable on mobile */\n padding: 0 10px 0 12px;\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n /* Match the active tab / crumb surface so the bar reads as the record's chrome */\n background: var(--mj-bg-surface);\n font-family: inherit;\n cursor: pointer;\n text-align: left;\n}\n\n.record-bar:active {\n background: var(--mj-bg-surface-hover);\n}\n\n.record-bar:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n}\n\n.record-bar-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border-radius: 7px;\n flex-shrink: 0;\n font-size: 13px;\n /* App color arrives via [style.color]; the chip tint derives from it */\n background: color-mix(in srgb, currentColor 14%, transparent);\n}\n\n.record-bar-title {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n font-size: var(--mj-text-sm, 14px);\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.record-bar-count {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n flex-shrink: 0;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 12.5px;\n font-weight: 700;\n color: var(--mj-text-secondary);\n}\n\n.record-bar-chevron {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n"] }]
60
+ }], null, { Title: [{
61
+ type: Input
62
+ }], Icon: [{
63
+ type: Input
64
+ }], Color: [{
65
+ type: Input
66
+ }], Count: [{
67
+ type: Input
68
+ }], SwitcherRequested: [{
69
+ type: Output
70
+ }] }); })();
71
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordBarComponent, { className: "RecordBarComponent", filePath: "src/lib/shell/components/record-open/record-bar.component.ts", lineNumber: 20 }); })();
72
+ //# sourceMappingURL=record-bar.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-bar.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-bar.component.ts","../../../../../src/lib/shell/components/record-open/record-bar.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAEvE;;;;;;;;;;GAUG;AAOH,MAAM,OAAO,kBAAkB;IAC7B,4BAA4B;IACnB,KAAK,GAAG,EAAE,CAAC;IACpB,6DAA6D;IACpD,IAAI,GAAG,0BAA0B,CAAC;IAC3C,0EAA0E;IACjE,KAAK,GAAG,EAAE,CAAC;IACpB,4EAA4E;IACnE,KAAK,GAAG,CAAC,CAAC;IAEnB,oDAAoD;IAC1C,iBAAiB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEvD,UAAU;QACR,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;4GAfU,kBAAkB;6DAAlB,kBAAkB;YCnB/B,oCAKyB;YAAvB,kGAAS,gBAAY,IAAC;YACtB,kCAA+E;YAC7E,uBAAsB;YACxB,oBAAO;YACP,kCAA+B;YAAA,YAAW;YAAA,oBAAO;YACjD,kCAAkD;YAChD,0BAAyC;YACzC,kCAAmC;YAAA,YAAW;YAAA,oBAAO;YACrD,0BAA2D;YAE/D,AADE,oBAAO,EACA;;;YATuB,cAA6B;YAA7B,0CAA6B;YACtD,cAAc;YAAd,uBAAc;YAEY,eAAW;YAAX,+BAAW;YAGL,eAAW;YAAX,+BAAW;;;iFDOrC,kBAAkB;cAN9B,SAAS;2BACE,eAAe,cACb,IAAI;;kBAMf,KAAK;;kBAEL,KAAK;;kBAEL,KAAK;;kBAEL,KAAK;;kBAGL,MAAM;;kFAXI,kBAAkB","sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\n\n/**\n * Mobile record bar — the records region's chrome below the shell breakpoint,\n * where the golden-layout tab strip is unusable (one tab fits, the rest are\n * unreachable). Shows the ACTIVE record (entity type icon tinted with its\n * app color + title) and the open-record count; the whole bar is one button\n * that opens the record switcher sheet.\n *\n * Dumb by design: tab-container computes every input from the workspace\n * configuration (it already tracks active tab, app colors, and type icons\n * for the strip) — the bar renders and emits, nothing more.\n */\n@Component({\n selector: 'mj-record-bar',\n standalone: true,\n templateUrl: './record-bar.component.html',\n styleUrls: ['./record-bar.component.css']\n})\nexport class RecordBarComponent {\n /** Active record's title */\n @Input() Title = '';\n /** Active record's entity TYPE icon (FontAwesome classes) */\n @Input() Icon = 'fa-regular fa-file-lines';\n /** Active record's app color (runtime data — binds as an inline style) */\n @Input() Color = '';\n /** Open record count (region + docked — matches the switcher sheet rows) */\n @Input() Count = 0;\n\n /** The bar was tapped — open the record switcher */\n @Output() SwitcherRequested = new EventEmitter<void>();\n\n OnBarClick(): void {\n this.SwitcherRequested.emit();\n }\n}\n","<button\n type=\"button\"\n class=\"record-bar\"\n [attr.aria-label]=\"'Switch records — ' + Count + ' open'\"\n aria-haspopup=\"dialog\"\n (click)=\"OnBarClick()\">\n <span class=\"record-bar-icon\" [style.color]=\"Color || null\" aria-hidden=\"true\">\n <i [class]=\"Icon\"></i>\n </span>\n <span class=\"record-bar-title\">{{ Title }}</span>\n <span class=\"record-bar-count\" aria-hidden=\"true\">\n <i class=\"fa-regular fa-folder-open\"></i>\n <span class=\"record-bar-count-num\">{{ Count }}</span>\n <i class=\"fa-solid fa-chevron-down record-bar-chevron\"></i>\n </span>\n</button>\n"]}
@@ -0,0 +1,26 @@
1
+ import { RecordSourceContext } from '@memberjunction/ng-shared';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Pane-level origin crumb — the FIRST element inside a record's golden-layout
5
+ * pane (Matt's placement call, 2026-07-30: no record-chrome refactor; the
6
+ * crumb rides the pane). One instance per record pane, which makes it correct
7
+ * in every layout context the region-level bar could not be:
8
+ * - split views: each pane carries its OWN origin
9
+ * - docked records (main layout, bar or single-resource): provenance intact
10
+ * - edit mode / custom form headers: unaffected — the crumb sits above the
11
+ * form entirely, in shell-owned territory
12
+ * Rendered/positioned by the tab-container wherever record content attaches
13
+ * (fresh loads, cache reattaches after promote/demote, single-resource).
14
+ */
15
+ export declare class RecordOriginCrumbComponent {
16
+ Origin: RecordSourceContext | null;
17
+ private navigationService;
18
+ get Clickable(): boolean;
19
+ /** Page segment: full restore — the captured page, section state included */
20
+ OnPageClick(): Promise<void>;
21
+ /** App segment: the app's LANDING page (breadcrumb level semantics) */
22
+ OnAppClick(): Promise<void>;
23
+ static ɵfac: i0.ɵɵFactoryDeclaration<RecordOriginCrumbComponent, never>;
24
+ static ɵcmp: i0.ɵɵComponentDeclaration<RecordOriginCrumbComponent, "mj-record-origin-crumb", never, { "Origin": { "alias": "Origin"; "required": false; }; }, {}, never, never, true, never>;
25
+ }
26
+ //# sourceMappingURL=record-origin-crumb.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-origin-crumb.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-origin-crumb.component.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,mBAAmB,EAA+B,MAAM,2BAA2B,CAAC;;AAEhH;;;;;;;;;;;GAWG;AACH,qBA8Fa,0BAA0B;IAC5B,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAQ;IAEnD,OAAO,CAAC,iBAAiB,CAA6B;IAEtD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,6EAA6E;IACvE,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC,uEAAuE;IACjE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;yCAjBtB,0BAA0B;2CAA1B,0BAA0B;CAsBtC"}
@@ -0,0 +1,140 @@
1
+ import { Component, Input, inject } from '@angular/core';
2
+ import { NavigationService, RecordSourceHasReturnTarget } from '@memberjunction/ng-shared';
3
+ import * as i0 from "@angular/core";
4
+ function RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
5
+ const _r1 = i0.ɵɵgetCurrentView();
6
+ i0.ɵɵdomElementStart(0, "button", 3);
7
+ i0.ɵɵdomListener("click", function RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnPageClick()); });
8
+ i0.ɵɵtext(1);
9
+ i0.ɵɵdomElementEnd();
10
+ } if (rf & 2) {
11
+ const ctx_r1 = i0.ɵɵnextContext(3);
12
+ i0.ɵɵadvance();
13
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.Origin.sourceLabel, " ");
14
+ } }
15
+ function RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
16
+ const _r4 = i0.ɵɵgetCurrentView();
17
+ i0.ɵɵdomElementStart(0, "span", 5);
18
+ i0.ɵɵtext(1, "\u203A");
19
+ i0.ɵɵdomElementEnd();
20
+ i0.ɵɵdomElementStart(2, "button", 6);
21
+ i0.ɵɵdomListener("click", function RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_2_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnPageClick()); });
22
+ i0.ɵɵtext(3);
23
+ i0.ɵɵdomElementEnd();
24
+ } if (rf & 2) {
25
+ const ctx_r1 = i0.ɵɵnextContext(4);
26
+ i0.ɵɵadvance(3);
27
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.Origin.sourceNavLabel, " ");
28
+ } }
29
+ function RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
30
+ const _r3 = i0.ɵɵgetCurrentView();
31
+ i0.ɵɵdomElementStart(0, "button", 4);
32
+ i0.ɵɵdomListener("click", function RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnAppClick()); });
33
+ i0.ɵɵtext(1);
34
+ i0.ɵɵdomElementEnd();
35
+ i0.ɵɵconditionalCreate(2, RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_2_Conditional_2_Template, 4, 1);
36
+ } if (rf & 2) {
37
+ const ctx_r1 = i0.ɵɵnextContext(3);
38
+ i0.ɵɵdomProperty("title", "Go to " + ctx_r1.Origin.sourceAppName);
39
+ i0.ɵɵadvance();
40
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.Origin.sourceAppName, " ");
41
+ i0.ɵɵadvance();
42
+ i0.ɵɵconditional(ctx_r1.Origin.sourceNavLabel ? 2 : -1);
43
+ } }
44
+ function RecordOriginCrumbComponent_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
45
+ i0.ɵɵdomElement(0, "i", 1);
46
+ i0.ɵɵconditionalCreate(1, RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_1_Template, 2, 1, "button", 2)(2, RecordOriginCrumbComponent_Conditional_0_Conditional_0_Conditional_2_Template, 3, 3);
47
+ } if (rf & 2) {
48
+ const ctx_r1 = i0.ɵɵnextContext(2);
49
+ i0.ɵɵadvance();
50
+ i0.ɵɵconditional(ctx_r1.Origin.sourceLabel ? 1 : 2);
51
+ } }
52
+ function RecordOriginCrumbComponent_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
53
+ i0.ɵɵdomElementStart(0, "span", 0);
54
+ i0.ɵɵtext(1);
55
+ i0.ɵɵdomElementEnd();
56
+ } if (rf & 2) {
57
+ const ctx_r1 = i0.ɵɵnextContext(2);
58
+ i0.ɵɵadvance();
59
+ i0.ɵɵtextInterpolate1("From ", ctx_r1.Origin.sourceLabel);
60
+ } }
61
+ function RecordOriginCrumbComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
62
+ i0.ɵɵconditionalCreate(0, RecordOriginCrumbComponent_Conditional_0_Conditional_0_Template, 3, 1)(1, RecordOriginCrumbComponent_Conditional_0_Conditional_1_Template, 2, 1, "span", 0);
63
+ } if (rf & 2) {
64
+ const ctx_r1 = i0.ɵɵnextContext();
65
+ i0.ɵɵconditional(ctx_r1.Clickable ? 0 : 1);
66
+ } }
67
+ /**
68
+ * Pane-level origin crumb — the FIRST element inside a record's golden-layout
69
+ * pane (Matt's placement call, 2026-07-30: no record-chrome refactor; the
70
+ * crumb rides the pane). One instance per record pane, which makes it correct
71
+ * in every layout context the region-level bar could not be:
72
+ * - split views: each pane carries its OWN origin
73
+ * - docked records (main layout, bar or single-resource): provenance intact
74
+ * - edit mode / custom form headers: unaffected — the crumb sits above the
75
+ * form entirely, in shell-owned territory
76
+ * Rendered/positioned by the tab-container wherever record content attaches
77
+ * (fresh loads, cache reattaches after promote/demote, single-resource).
78
+ */
79
+ export class RecordOriginCrumbComponent {
80
+ Origin = null;
81
+ navigationService = inject(NavigationService);
82
+ get Clickable() {
83
+ return RecordSourceHasReturnTarget(this.Origin);
84
+ }
85
+ /** Page segment: full restore — the captured page, section state included */
86
+ async OnPageClick() {
87
+ if (this.Origin) {
88
+ await this.navigationService.ReturnToRecordSource(this.Origin);
89
+ }
90
+ }
91
+ /** App segment: the app's LANDING page (breadcrumb level semantics) */
92
+ async OnAppClick() {
93
+ if (this.Origin?.sourceAppId) {
94
+ await this.navigationService.SwitchToAppHome(this.Origin.sourceAppId);
95
+ }
96
+ }
97
+ static ɵfac = function RecordOriginCrumbComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordOriginCrumbComponent)(); };
98
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordOriginCrumbComponent, selectors: [["mj-record-origin-crumb"]], hostBindings: function RecordOriginCrumbComponent_HostBindings(rf, ctx) { if (rf & 1) {
99
+ i0.ɵɵlistener("mousedown", function RecordOriginCrumbComponent_mousedown_HostBindingHandler($event) { return $event.stopPropagation(); })("click", function RecordOriginCrumbComponent_click_HostBindingHandler($event) { return $event.stopPropagation(); });
100
+ } }, inputs: { Origin: "Origin" }, decls: 1, vars: 1, consts: [[1, "origin-static"], ["aria-hidden", "true", 1, "fa-solid", "fa-arrow-left", "crumb-lead"], ["type", "button", "title", "Back to where you opened this record", 1, "crumb-seg"], ["type", "button", "title", "Back to where you opened this record", 1, "crumb-seg", 3, "click"], ["type", "button", 1, "crumb-seg", 3, "click", "title"], ["aria-hidden", "true", 1, "crumb-sep"], ["type", "button", "title", "Back to where you opened this record", 1, "crumb-seg", "crumb-page", 3, "click"]], template: function RecordOriginCrumbComponent_Template(rf, ctx) { if (rf & 1) {
101
+ i0.ɵɵconditionalCreate(0, RecordOriginCrumbComponent_Conditional_0_Template, 2, 1);
102
+ } if (rf & 2) {
103
+ i0.ɵɵconditional(ctx.Origin ? 0 : -1);
104
+ } }, styles: ["[_nghost-%COMP%] {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n height: 36px;\n \n\n\n\n padding: 0 12px 0 24px;\n \n\n\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n [_nghost-%COMP%]:not(:has(*)) { display: none; }\n .crumb-lead[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-right: 6px;\n }\n \n\n .crumb-seg[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n padding: 5px 8px;\n border: none;\n border-radius: 4px;\n background: transparent;\n font-size: 12px;\n line-height: 1;\n font-family: inherit;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .crumb-seg[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n .crumb-seg[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n }\n .crumb-page[_ngcontent-%COMP%] { font-weight: 500; }\n .crumb-sep[_ngcontent-%COMP%] { color: var(--mj-text-muted); font-size: 12px; }\n .origin-static[_ngcontent-%COMP%] {\n padding: 5px 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n }"] });
105
+ }
106
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordOriginCrumbComponent, [{
107
+ type: Component,
108
+ args: [{ selector: 'mj-record-origin-crumb', standalone: true, host: {
109
+ '(mousedown)': '$event.stopPropagation()',
110
+ '(click)': '$event.stopPropagation()'
111
+ }, template: `
112
+ @if (Origin) {
113
+ @if (Clickable) {
114
+ <i class="fa-solid fa-arrow-left crumb-lead" aria-hidden="true"></i>
115
+ @if (Origin.sourceLabel) {
116
+ <button type="button" class="crumb-seg" (click)="OnPageClick()" title="Back to where you opened this record">
117
+ {{ Origin.sourceLabel }}
118
+ </button>
119
+ } @else {
120
+ <button type="button" class="crumb-seg" (click)="OnAppClick()" [title]="'Go to ' + Origin.sourceAppName">
121
+ {{ Origin.sourceAppName }}
122
+ </button>
123
+ @if (Origin.sourceNavLabel) {
124
+ <span class="crumb-sep" aria-hidden="true">›</span>
125
+ <button type="button" class="crumb-seg crumb-page" (click)="OnPageClick()" title="Back to where you opened this record">
126
+ {{ Origin.sourceNavLabel }}
127
+ </button>
128
+ }
129
+ }
130
+ } @else {
131
+ <!-- Provenance only — no return target (e.g. opened by an agent) -->
132
+ <span class="origin-static">From {{ Origin.sourceLabel }}</span>
133
+ }
134
+ }
135
+ `, styles: ["\n :host {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n height: 36px;\n /* Left indent deliberately DEEPER than the first tab's edge (~16px)\n so the crumb reads as a level BENEATH the tab \u2014 hierarchy, not a\n sibling bar. */\n padding: 0 12px 0 24px;\n /* Match the ACTIVE tab's surface so the tab flows into its pane\n (the sunken tone read as a disconnected band between them). */\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n :host:not(:has(*)) { display: none; }\n .crumb-lead {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-right: 6px;\n }\n /* Each breadcrumb level is its OWN link with its own hover */\n .crumb-seg {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n padding: 5px 8px;\n border: none;\n border-radius: 4px;\n background: transparent;\n font-size: 12px;\n line-height: 1;\n font-family: inherit;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .crumb-seg:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n .crumb-seg:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n }\n .crumb-page { font-weight: 500; }\n .crumb-sep { color: var(--mj-text-muted); font-size: 12px; }\n .origin-static {\n padding: 5px 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n "] }]
136
+ }], null, { Origin: [{
137
+ type: Input
138
+ }] }); })();
139
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordOriginCrumbComponent, { className: "RecordOriginCrumbComponent", filePath: "src/lib/shell/components/record-open/record-origin-crumb.component.ts", lineNumber: 110 }); })();
140
+ //# sourceMappingURL=record-origin-crumb.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-origin-crumb.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-origin-crumb.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAuB,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;;;;IA8BtG,oCAA6G;IAArE,8NAAS,oBAAa,KAAC;IAC7D,YACF;IAAA,oBAAS;;;IADP,cACF;IADE,0DACF;;;;IAME,kCAA2C;IAAA,sBAAC;IAAA,oBAAO;IACnD,oCAAwH;IAArE,4OAAS,oBAAa,KAAC;IACxE,YACF;IAAA,oBAAS;;;IADP,eACF;IADE,6DACF;;;;IAPF,oCAAyG;IAAjE,8NAAS,mBAAY,KAAC;IAC5D,YACF;IAAA,oBAAS;IACT,4HAA6B;;;IAHkC,iEAAyC;IACtG,cACF;IADE,4DACF;IACA,cAKC;IALD,uDAKC;;;IAdH,0BAAoE;IAKlE,AAJF,2HAA0B,wFAIjB;;;IAJT,cAcC;IAdD,mDAcC;;;IAGD,kCAA4B;IAAA,YAA6B;IAAA,oBAAO;;;IAApC,cAA6B;IAA7B,yDAA6B;;;IAFzD,AAjBF,gGAAiB,qFAiBR;;;IAjBT,0CAoBC;;AA7CP;;;;;;;;;;;GAWG;AA+FH,MAAM,OAAO,0BAA0B;IAC5B,MAAM,GAA+B,IAAI,CAAC;IAE3C,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAEtD,IAAI,SAAS;QACX,OAAO,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,WAAW;QACf,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;oHArBU,0BAA0B;6DAA1B,0BAA0B;YAA1B,6GAAA,wBAAwB,IAAE,wFAA1B,wBAAwB,IAAE;;YAlFnC,kFAAc;;YAAd,qCAsBC;;;iFA4DQ,0BAA0B;cA9FtC,SAAS;2BACE,wBAAwB,cACtB,IAAI,QAKV;oBACJ,aAAa,EAAE,0BAA0B;oBACzC,SAAS,EAAE,0BAA0B;iBACtC,YACS;;;;;;;;;;;;;;;;;;;;;;;;GAwBT;;kBA4DA,KAAK;;kFADK,0BAA0B","sourcesContent":["import { Component, Input, inject } from '@angular/core';\nimport { NavigationService, RecordSourceContext, RecordSourceHasReturnTarget } from '@memberjunction/ng-shared';\n\n/**\n * Pane-level origin crumb — the FIRST element inside a record's golden-layout\n * pane (Matt's placement call, 2026-07-30: no record-chrome refactor; the\n * crumb rides the pane). One instance per record pane, which makes it correct\n * in every layout context the region-level bar could not be:\n * - split views: each pane carries its OWN origin\n * - docked records (main layout, bar or single-resource): provenance intact\n * - edit mode / custom form headers: unaffected — the crumb sits above the\n * form entirely, in shell-owned territory\n * Rendered/positioned by the tab-container wherever record content attaches\n * (fresh loads, cache reattaches after promote/demote, single-resource).\n */\n@Component({\n selector: 'mj-record-origin-crumb',\n standalone: true,\n // The crumb sits INSIDE a GL pane: without these stoppers, clicks bubble\n // to Golden Layout's pane-focus handlers, which re-activate the pane's\n // own tab and STOMP the navigation the click just started (the app\n // segment created the destination tab and then lost the activation race).\n host: {\n '(mousedown)': '$event.stopPropagation()',\n '(click)': '$event.stopPropagation()'\n },\n template: `\n @if (Origin) {\n @if (Clickable) {\n <i class=\"fa-solid fa-arrow-left crumb-lead\" aria-hidden=\"true\"></i>\n @if (Origin.sourceLabel) {\n <button type=\"button\" class=\"crumb-seg\" (click)=\"OnPageClick()\" title=\"Back to where you opened this record\">\n {{ Origin.sourceLabel }}\n </button>\n } @else {\n <button type=\"button\" class=\"crumb-seg\" (click)=\"OnAppClick()\" [title]=\"'Go to ' + Origin.sourceAppName\">\n {{ Origin.sourceAppName }}\n </button>\n @if (Origin.sourceNavLabel) {\n <span class=\"crumb-sep\" aria-hidden=\"true\">›</span>\n <button type=\"button\" class=\"crumb-seg crumb-page\" (click)=\"OnPageClick()\" title=\"Back to where you opened this record\">\n {{ Origin.sourceNavLabel }}\n </button>\n }\n }\n } @else {\n <!-- Provenance only — no return target (e.g. opened by an agent) -->\n <span class=\"origin-static\">From {{ Origin.sourceLabel }}</span>\n }\n }\n `,\n styles: [`\n :host {\n display: flex;\n align-items: center;\n gap: 2px;\n flex-shrink: 0;\n height: 36px;\n /* Left indent deliberately DEEPER than the first tab's edge (~16px)\n so the crumb reads as a level BENEATH the tab — hierarchy, not a\n sibling bar. */\n padding: 0 12px 0 24px;\n /* Match the ACTIVE tab's surface so the tab flows into its pane\n (the sunken tone read as a disconnected band between them). */\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n }\n :host:not(:has(*)) { display: none; }\n .crumb-lead {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-right: 6px;\n }\n /* Each breadcrumb level is its OWN link with its own hover */\n .crumb-seg {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n padding: 5px 8px;\n border: none;\n border-radius: 4px;\n background: transparent;\n font-size: 12px;\n line-height: 1;\n font-family: inherit;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .crumb-seg:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n .crumb-seg:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n }\n .crumb-page { font-weight: 500; }\n .crumb-sep { color: var(--mj-text-muted); font-size: 12px; }\n .origin-static {\n padding: 5px 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n }\n `]\n})\nexport class RecordOriginCrumbComponent {\n @Input() Origin: RecordSourceContext | null = null;\n\n private navigationService = inject(NavigationService);\n\n get Clickable(): boolean {\n return RecordSourceHasReturnTarget(this.Origin);\n }\n\n /** Page segment: full restore — the captured page, section state included */\n async OnPageClick(): Promise<void> {\n if (this.Origin) {\n await this.navigationService.ReturnToRecordSource(this.Origin);\n }\n }\n\n /** App segment: the app's LANDING page (breadcrumb level semantics) */\n async OnAppClick(): Promise<void> {\n if (this.Origin?.sourceAppId) {\n await this.navigationService.SwitchToAppHome(this.Origin.sourceAppId);\n }\n }\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * One row of the mobile record switcher. Built by tab-container from the
5
+ * workspace configuration — region records AND workspace-docked records
6
+ * (docked/region composition is a desktop concept; on mobile they are one
7
+ * list).
8
+ */
9
+ export interface RecordSwitcherEntry {
10
+ TabId: string;
11
+ Title: string;
12
+ /** Entity TYPE icon (FontAwesome classes, via ResolveRecordTypeIcon) */
13
+ Icon: string;
14
+ /** App color (runtime data — binds as an inline style) */
15
+ Color: string;
16
+ /** Origin breadcrumb text ("Data Explorer › Data") or null when unknown */
17
+ OriginLabel: string | null;
18
+ IsActive: boolean;
19
+ }
20
+ /**
21
+ * Mobile record switcher — a bottom sheet listing every open record: entity
22
+ * icon in app color, title, origin subtitle; tap to activate, ✕ to close.
23
+ * Opened from the record bar and the nav drawer's Records pill.
24
+ *
25
+ * Dumb by design: entries arrive as inputs; activation and close intents
26
+ * emit back to tab-container, which owns the workspace/golden-layout
27
+ * plumbing (close routes through the SAME path as the tab context menu).
28
+ */
29
+ export declare class RecordSwitcherSheetComponent {
30
+ Entries: RecordSwitcherEntry[];
31
+ Visible: boolean;
32
+ VisibleChange: EventEmitter<boolean>;
33
+ /** Row tapped — activate this record */
34
+ ActivateRequested: EventEmitter<string>;
35
+ /** Row's ✕ tapped — close this record (sheet stays open) */
36
+ CloseRequested: EventEmitter<string>;
37
+ OnSheetVisibleChange(visible: boolean): void;
38
+ OnRowClick(entry: RecordSwitcherEntry): void;
39
+ OnCloseClick(event: MouseEvent, entry: RecordSwitcherEntry): void;
40
+ static ɵfac: i0.ɵɵFactoryDeclaration<RecordSwitcherSheetComponent, never>;
41
+ static ɵcmp: i0.ɵɵComponentDeclaration<RecordSwitcherSheetComponent, "mj-record-switcher-sheet", never, { "Entries": { "alias": "Entries"; "required": false; }; "Visible": { "alias": "Visible"; "required": false; }; }, { "VisibleChange": "VisibleChange"; "ActivateRequested": "ActivateRequested"; "CloseRequested": "CloseRequested"; }, never, never, true, never>;
42
+ }
43
+ //# sourceMappingURL=record-switcher-sheet.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-switcher-sheet.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-switcher-sheet.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAiB,MAAM,eAAe,CAAC;;AAGvE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,qBAOa,4BAA4B;IAC9B,OAAO,EAAE,mBAAmB,EAAE,CAAM;IAEpC,OAAO,UAAS;IACf,aAAa,wBAA+B;IAEtD,wCAAwC;IAC9B,iBAAiB,uBAA8B;IACzD,4DAA4D;IAClD,cAAc,uBAA8B;IAEtD,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAK5C,UAAU,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAI5C,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI;yCApBtD,4BAA4B;2CAA5B,4BAA4B;CAwBxC"}
@@ -0,0 +1,102 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { MJBottomSheetComponent } from '@memberjunction/ng-ui-components';
3
+ import * as i0 from "@angular/core";
4
+ const _forTrack0 = ($index, $item) => $item.TabId;
5
+ function RecordSwitcherSheetComponent_For_3_Conditional_7_Template(rf, ctx) { if (rf & 1) {
6
+ i0.ɵɵelementStart(0, "span", 8);
7
+ i0.ɵɵtext(1);
8
+ i0.ɵɵelementEnd();
9
+ } if (rf & 2) {
10
+ const entry_r2 = i0.ɵɵnextContext().$implicit;
11
+ i0.ɵɵadvance();
12
+ i0.ɵɵtextInterpolate(entry_r2.OriginLabel);
13
+ } }
14
+ function RecordSwitcherSheetComponent_For_3_Template(rf, ctx) { if (rf & 1) {
15
+ const _r1 = i0.ɵɵgetCurrentView();
16
+ i0.ɵɵelementStart(0, "div", 3)(1, "button", 4);
17
+ i0.ɵɵlistener("click", function RecordSwitcherSheetComponent_For_3_Template_button_click_1_listener() { const entry_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnRowClick(entry_r2)); });
18
+ i0.ɵɵelementStart(2, "span", 5);
19
+ i0.ɵɵelement(3, "i");
20
+ i0.ɵɵelementEnd();
21
+ i0.ɵɵelementStart(4, "span", 6)(5, "span", 7);
22
+ i0.ɵɵtext(6);
23
+ i0.ɵɵelementEnd();
24
+ i0.ɵɵconditionalCreate(7, RecordSwitcherSheetComponent_For_3_Conditional_7_Template, 2, 1, "span", 8);
25
+ i0.ɵɵelementEnd()();
26
+ i0.ɵɵelementStart(8, "button", 9);
27
+ i0.ɵɵlistener("click", function RecordSwitcherSheetComponent_For_3_Template_button_click_8_listener($event) { const entry_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnCloseClick($event, entry_r2)); });
28
+ i0.ɵɵelement(9, "i", 10);
29
+ i0.ɵɵelementEnd()();
30
+ } if (rf & 2) {
31
+ const entry_r2 = ctx.$implicit;
32
+ i0.ɵɵclassProp("switcher-row--active", entry_r2.IsActive);
33
+ i0.ɵɵadvance();
34
+ i0.ɵɵattribute("aria-current", entry_r2.IsActive ? "true" : null);
35
+ i0.ɵɵadvance();
36
+ i0.ɵɵstyleProp("color", entry_r2.Color || null);
37
+ i0.ɵɵadvance();
38
+ i0.ɵɵclassMap(entry_r2.Icon);
39
+ i0.ɵɵadvance(3);
40
+ i0.ɵɵtextInterpolate(entry_r2.Title);
41
+ i0.ɵɵadvance();
42
+ i0.ɵɵconditional(entry_r2.OriginLabel ? 7 : -1);
43
+ i0.ɵɵadvance();
44
+ i0.ɵɵattribute("aria-label", "Close " + entry_r2.Title);
45
+ } }
46
+ /**
47
+ * Mobile record switcher — a bottom sheet listing every open record: entity
48
+ * icon in app color, title, origin subtitle; tap to activate, ✕ to close.
49
+ * Opened from the record bar and the nav drawer's Records pill.
50
+ *
51
+ * Dumb by design: entries arrive as inputs; activation and close intents
52
+ * emit back to tab-container, which owns the workspace/golden-layout
53
+ * plumbing (close routes through the SAME path as the tab context menu).
54
+ */
55
+ export class RecordSwitcherSheetComponent {
56
+ Entries = [];
57
+ Visible = false;
58
+ VisibleChange = new EventEmitter();
59
+ /** Row tapped — activate this record */
60
+ ActivateRequested = new EventEmitter();
61
+ /** Row's ✕ tapped — close this record (sheet stays open) */
62
+ CloseRequested = new EventEmitter();
63
+ OnSheetVisibleChange(visible) {
64
+ this.Visible = visible;
65
+ this.VisibleChange.emit(visible);
66
+ }
67
+ OnRowClick(entry) {
68
+ this.ActivateRequested.emit(entry.TabId);
69
+ }
70
+ OnCloseClick(event, entry) {
71
+ event.stopPropagation();
72
+ this.CloseRequested.emit(entry.TabId);
73
+ }
74
+ static ɵfac = function RecordSwitcherSheetComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordSwitcherSheetComponent)(); };
75
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RecordSwitcherSheetComponent, selectors: [["mj-record-switcher-sheet"]], inputs: { Entries: "Entries", Visible: "Visible" }, outputs: { VisibleChange: "VisibleChange", ActivateRequested: "ActivateRequested", CloseRequested: "CloseRequested" }, decls: 4, vars: 1, consts: [["Title", "Open Records", "AriaLabel", "Record switcher", 3, "VisibleChange", "Visible"], [1, "switcher-list"], [1, "switcher-row", 3, "switcher-row--active"], [1, "switcher-row"], ["type", "button", 1, "switcher-row-main", 3, "click"], ["aria-hidden", "true", 1, "switcher-row-icon"], [1, "switcher-row-text"], [1, "switcher-row-title"], [1, "switcher-row-origin"], ["type", "button", 1, "switcher-row-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"]], template: function RecordSwitcherSheetComponent_Template(rf, ctx) { if (rf & 1) {
76
+ i0.ɵɵelementStart(0, "mj-bottom-sheet", 0);
77
+ i0.ɵɵlistener("VisibleChange", function RecordSwitcherSheetComponent_Template_mj_bottom_sheet_VisibleChange_0_listener($event) { return ctx.OnSheetVisibleChange($event); });
78
+ i0.ɵɵelementStart(1, "div", 1);
79
+ i0.ɵɵrepeaterCreate(2, RecordSwitcherSheetComponent_For_3_Template, 10, 10, "div", 2, _forTrack0);
80
+ i0.ɵɵelementEnd()();
81
+ } if (rf & 2) {
82
+ i0.ɵɵproperty("Visible", ctx.Visible);
83
+ i0.ɵɵadvance(2);
84
+ i0.ɵɵrepeater(ctx.Entries);
85
+ } }, dependencies: [MJBottomSheetComponent], styles: [".switcher-list[_ngcontent-%COMP%] {\n padding: 0 10px;\n}\n\n.switcher-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n border-radius: 11px;\n}\n\n.switcher-row--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.switcher-row-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 11px;\n flex: 1;\n min-width: 0;\n padding: 10px 8px;\n border: none;\n background: transparent;\n border-radius: 11px;\n font-family: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.switcher-row-main[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-hover);\n}\n\n.switcher-row-main[_ngcontent-%COMP%]:focus-visible, \n.switcher-row-close[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n}\n\n.switcher-row-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 9px;\n flex-shrink: 0;\n font-size: 16px;\n \n\n background: color-mix(in srgb, currentColor 14%, transparent);\n}\n\n.switcher-row-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n min-width: 0;\n gap: 1px;\n}\n\n.switcher-row-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm, 14px);\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.switcher-row-origin[_ngcontent-%COMP%] {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.switcher-row-close[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 38px;\n height: 38px;\n flex-shrink: 0;\n border: none;\n background: transparent;\n border-radius: 8px;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: pointer;\n}\n\n.switcher-row-close[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}"] });
86
+ }
87
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordSwitcherSheetComponent, [{
88
+ type: Component,
89
+ args: [{ selector: 'mj-record-switcher-sheet', standalone: true, imports: [MJBottomSheetComponent], template: "<mj-bottom-sheet\n [Visible]=\"Visible\"\n (VisibleChange)=\"OnSheetVisibleChange($event)\"\n Title=\"Open Records\"\n AriaLabel=\"Record switcher\">\n <div class=\"switcher-list\">\n @for (entry of Entries; track entry.TabId) {\n <div class=\"switcher-row\" [class.switcher-row--active]=\"entry.IsActive\">\n <button\n type=\"button\"\n class=\"switcher-row-main\"\n [attr.aria-current]=\"entry.IsActive ? 'true' : null\"\n (click)=\"OnRowClick(entry)\">\n <span class=\"switcher-row-icon\" [style.color]=\"entry.Color || null\" aria-hidden=\"true\">\n <i [class]=\"entry.Icon\"></i>\n </span>\n <span class=\"switcher-row-text\">\n <span class=\"switcher-row-title\">{{ entry.Title }}</span>\n @if (entry.OriginLabel) {\n <span class=\"switcher-row-origin\">{{ entry.OriginLabel }}</span>\n }\n </span>\n </button>\n <button\n type=\"button\"\n class=\"switcher-row-close\"\n [attr.aria-label]=\"'Close ' + entry.Title\"\n (click)=\"OnCloseClick($event, entry)\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n</mj-bottom-sheet>\n", styles: [".switcher-list {\n padding: 0 10px;\n}\n\n.switcher-row {\n display: flex;\n align-items: center;\n border-radius: 11px;\n}\n\n.switcher-row--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.switcher-row-main {\n display: flex;\n align-items: center;\n gap: 11px;\n flex: 1;\n min-width: 0;\n padding: 10px 8px;\n border: none;\n background: transparent;\n border-radius: 11px;\n font-family: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.switcher-row-main:active {\n background: var(--mj-bg-surface-hover);\n}\n\n.switcher-row-main:focus-visible,\n.switcher-row-close:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n}\n\n.switcher-row-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 9px;\n flex-shrink: 0;\n font-size: 16px;\n /* App color arrives via [style.color]; the chip tint derives from it */\n background: color-mix(in srgb, currentColor 14%, transparent);\n}\n\n.switcher-row-text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n gap: 1px;\n}\n\n.switcher-row-title {\n font-size: var(--mj-text-sm, 14px);\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.switcher-row-origin {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.switcher-row-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 38px;\n height: 38px;\n flex-shrink: 0;\n border: none;\n background: transparent;\n border-radius: 8px;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: pointer;\n}\n\n.switcher-row-close:active {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n"] }]
90
+ }], null, { Entries: [{
91
+ type: Input
92
+ }], Visible: [{
93
+ type: Input
94
+ }], VisibleChange: [{
95
+ type: Output
96
+ }], ActivateRequested: [{
97
+ type: Output
98
+ }], CloseRequested: [{
99
+ type: Output
100
+ }] }); })();
101
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RecordSwitcherSheetComponent, { className: "RecordSwitcherSheetComponent", filePath: "src/lib/shell/components/record-open/record-switcher-sheet.component.ts", lineNumber: 38 }); })();
102
+ //# sourceMappingURL=record-switcher-sheet.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-switcher-sheet.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-switcher-sheet.component.ts","../../../../../src/lib/shell/components/record-open/record-switcher-sheet.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;;;;ICkB5D,+BAAkC;IAAA,YAAuB;IAAA,iBAAO;;;IAA9B,cAAuB;IAAvB,0CAAuB;;;;IAX/D,AADF,8BAAwE,gBAKxC;IAA5B,mNAAS,2BAAiB,KAAC;IAC3B,+BAAuF;IACrF,oBAA4B;IAC9B,iBAAO;IAEL,AADF,+BAAgC,cACG;IAAA,YAAiB;IAAA,iBAAO;IACzD,qGAAyB;IAI7B,AADE,iBAAO,EACA;IACT,iCAIwC;IAAtC,yNAAS,qCAA2B,KAAC;IACrC,wBAAoD;IAExD,AADE,iBAAS,EACL;;;IAvBoB,yDAA6C;IAInE,cAAoD;;IAEpB,cAAmC;IAAnC,+CAAmC;IAC9D,cAAoB;IAApB,4BAAoB;IAGU,eAAiB;IAAjB,oCAAiB;IAClD,cAEC;IAFD,+CAEC;IAMH,cAA0C;;;ADLpD;;;;;;;;GAQG;AAQH,MAAM,OAAO,4BAA4B;IAC9B,OAAO,GAA0B,EAAE,CAAC;IAEpC,OAAO,GAAG,KAAK,CAAC;IACf,aAAa,GAAG,IAAI,YAAY,EAAW,CAAC;IAEtD,wCAAwC;IAC9B,iBAAiB,GAAG,IAAI,YAAY,EAAU,CAAC;IACzD,4DAA4D;IAClD,cAAc,GAAG,IAAI,YAAY,EAAU,CAAC;IAEtD,oBAAoB,CAAC,OAAgB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,UAAU,CAAC,KAA0B;QACnC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,YAAY,CAAC,KAAiB,EAAE,KAA0B;QACxD,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;sHAvBU,4BAA4B;6DAA5B,4BAA4B;YCrCzC,0CAI8B;YAF5B,wIAAiB,gCAA4B,IAAC;YAG9C,8BAA2B;YACzB,iGAyBC;YAEL,AADE,iBAAM,EACU;;YAhChB,qCAAmB;YAKjB,eAyBC;YAzBD,0BAyBC;4BDEO,sBAAsB;;iFAIrB,4BAA4B;cAPxC,SAAS;2BACE,0BAA0B,cACxB,IAAI,WACP,CAAC,sBAAsB,CAAC;;kBAKhC,KAAK;;kBAEL,KAAK;;kBACL,MAAM;;kBAGN,MAAM;;kBAEN,MAAM;;kFATI,4BAA4B","sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { MJBottomSheetComponent } from '@memberjunction/ng-ui-components';\n\n/**\n * One row of the mobile record switcher. Built by tab-container from the\n * workspace configuration — region records AND workspace-docked records\n * (docked/region composition is a desktop concept; on mobile they are one\n * list).\n */\nexport interface RecordSwitcherEntry {\n TabId: string;\n Title: string;\n /** Entity TYPE icon (FontAwesome classes, via ResolveRecordTypeIcon) */\n Icon: string;\n /** App color (runtime data — binds as an inline style) */\n Color: string;\n /** Origin breadcrumb text (\"Data Explorer › Data\") or null when unknown */\n OriginLabel: string | null;\n IsActive: boolean;\n}\n\n/**\n * Mobile record switcher — a bottom sheet listing every open record: entity\n * icon in app color, title, origin subtitle; tap to activate, ✕ to close.\n * Opened from the record bar and the nav drawer's Records pill.\n *\n * Dumb by design: entries arrive as inputs; activation and close intents\n * emit back to tab-container, which owns the workspace/golden-layout\n * plumbing (close routes through the SAME path as the tab context menu).\n */\n@Component({\n selector: 'mj-record-switcher-sheet',\n standalone: true,\n imports: [MJBottomSheetComponent],\n templateUrl: './record-switcher-sheet.component.html',\n styleUrls: ['./record-switcher-sheet.component.css']\n})\nexport class RecordSwitcherSheetComponent {\n @Input() Entries: RecordSwitcherEntry[] = [];\n\n @Input() Visible = false;\n @Output() VisibleChange = new EventEmitter<boolean>();\n\n /** Row tapped — activate this record */\n @Output() ActivateRequested = new EventEmitter<string>();\n /** Row's ✕ tapped — close this record (sheet stays open) */\n @Output() CloseRequested = new EventEmitter<string>();\n\n OnSheetVisibleChange(visible: boolean): void {\n this.Visible = visible;\n this.VisibleChange.emit(visible);\n }\n\n OnRowClick(entry: RecordSwitcherEntry): void {\n this.ActivateRequested.emit(entry.TabId);\n }\n\n OnCloseClick(event: MouseEvent, entry: RecordSwitcherEntry): void {\n event.stopPropagation();\n this.CloseRequested.emit(entry.TabId);\n }\n}\n","<mj-bottom-sheet\n [Visible]=\"Visible\"\n (VisibleChange)=\"OnSheetVisibleChange($event)\"\n Title=\"Open Records\"\n AriaLabel=\"Record switcher\">\n <div class=\"switcher-list\">\n @for (entry of Entries; track entry.TabId) {\n <div class=\"switcher-row\" [class.switcher-row--active]=\"entry.IsActive\">\n <button\n type=\"button\"\n class=\"switcher-row-main\"\n [attr.aria-current]=\"entry.IsActive ? 'true' : null\"\n (click)=\"OnRowClick(entry)\">\n <span class=\"switcher-row-icon\" [style.color]=\"entry.Color || null\" aria-hidden=\"true\">\n <i [class]=\"entry.Icon\"></i>\n </span>\n <span class=\"switcher-row-text\">\n <span class=\"switcher-row-title\">{{ entry.Title }}</span>\n @if (entry.OriginLabel) {\n <span class=\"switcher-row-origin\">{{ entry.OriginLabel }}</span>\n }\n </span>\n </button>\n <button\n type=\"button\"\n class=\"switcher-row-close\"\n [attr.aria-label]=\"'Close ' + entry.Title\"\n (click)=\"OnCloseClick($event, entry)\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n</mj-bottom-sheet>\n"]}
@@ -0,0 +1,21 @@
1
+ import { Observable } from 'rxjs';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Opener for the mobile record switcher sheet. The sheet renders inside
5
+ * tab-container (which owns close routing and both golden-layout managers),
6
+ * but open requests come from surfaces that live elsewhere in the shell —
7
+ * the nav drawer's Records pill today. This service is that one-way channel:
8
+ * callers Open(), tab-container listens.
9
+ *
10
+ * (The record bar doesn't need it — it's a child of tab-container and emits
11
+ * directly.)
12
+ */
13
+ export declare class RecordSwitcherService {
14
+ private openRequested;
15
+ /** tab-container subscribes; each emission shows the switcher sheet */
16
+ get OpenRequested(): Observable<void>;
17
+ Open(): void;
18
+ static ɵfac: i0.ɵɵFactoryDeclaration<RecordSwitcherService, never>;
19
+ static ɵprov: i0.ɵɵInjectableDeclaration<RecordSwitcherService>;
20
+ }
21
+ //# sourceMappingURL=record-switcher.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-switcher.service.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-switcher.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;;AAE3C;;;;;;;;;GASG;AACH,qBACa,qBAAqB;IAChC,OAAO,CAAC,aAAa,CAAuB;IAE5C,uEAAuE;IACvE,IAAW,aAAa,IAAI,UAAU,CAAC,IAAI,CAAC,CAE3C;IAEM,IAAI,IAAI,IAAI;yCARR,qBAAqB;6CAArB,qBAAqB;CAWjC"}
@@ -0,0 +1,30 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Opener for the mobile record switcher sheet. The sheet renders inside
6
+ * tab-container (which owns close routing and both golden-layout managers),
7
+ * but open requests come from surfaces that live elsewhere in the shell —
8
+ * the nav drawer's Records pill today. This service is that one-way channel:
9
+ * callers Open(), tab-container listens.
10
+ *
11
+ * (The record bar doesn't need it — it's a child of tab-container and emits
12
+ * directly.)
13
+ */
14
+ export class RecordSwitcherService {
15
+ openRequested = new Subject();
16
+ /** tab-container subscribes; each emission shows the switcher sheet */
17
+ get OpenRequested() {
18
+ return this.openRequested.asObservable();
19
+ }
20
+ Open() {
21
+ this.openRequested.next();
22
+ }
23
+ static ɵfac = function RecordSwitcherService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RecordSwitcherService)(); };
24
+ static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: RecordSwitcherService, factory: RecordSwitcherService.ɵfac, providedIn: 'root' });
25
+ }
26
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RecordSwitcherService, [{
27
+ type: Injectable,
28
+ args: [{ providedIn: 'root' }]
29
+ }], null, null); })();
30
+ //# sourceMappingURL=record-switcher.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-switcher.service.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/record-open/record-switcher.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAc,OAAO,EAAE,MAAM,MAAM,CAAC;;AAE3C;;;;;;;;;GASG;AAEH,MAAM,OAAO,qBAAqB;IACxB,aAAa,GAAG,IAAI,OAAO,EAAQ,CAAC;IAE5C,uEAAuE;IACvE,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;IAC3C,CAAC;IAEM,IAAI;QACT,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IAC5B,CAAC;+GAVU,qBAAqB;gEAArB,qBAAqB,WAArB,qBAAqB,mBADR,MAAM;;iFACnB,qBAAqB;cADjC,UAAU;eAAC,EAAE,UAAU,EAAE,MAAM,EAAE","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Observable, Subject } from 'rxjs';\n\n/**\n * Opener for the mobile record switcher sheet. The sheet renders inside\n * tab-container (which owns close routing and both golden-layout managers),\n * but open requests come from surfaces that live elsewhere in the shell —\n * the nav drawer's Records pill today. This service is that one-way channel:\n * callers Open(), tab-container listens.\n *\n * (The record bar doesn't need it — it's a child of tab-container and emits\n * directly.)\n */\n@Injectable({ providedIn: 'root' })\nexport class RecordSwitcherService {\n private openRequested = new Subject<void>();\n\n /** tab-container subscribes; each emission shows the switcher sheet */\n public get OpenRequested(): Observable<void> {\n return this.openRequested.asObservable();\n }\n\n public Open(): void {\n this.openRequested.next();\n }\n}\n"]}