@memberjunction/ng-dashboards 6.2.0-edge.3 → 6.2.0-edge.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts +4 -3
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts.map +1 -1
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js +8 -5
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js.map +1 -1
- package/dist/AI/components/duplicates/compare-value.component.d.ts +67 -0
- package/dist/AI/components/duplicates/compare-value.component.d.ts.map +1 -0
- package/dist/AI/components/duplicates/compare-value.component.js +168 -0
- package/dist/AI/components/duplicates/compare-value.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +49 -3
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +287 -169
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +77 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +116 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +16 -4
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +2 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +12 -6
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-index-auto.d.ts +29 -0
- package/dist/AI/components/vectors/vector-index-auto.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-index-auto.js +59 -0
- package/dist/AI/components/vectors/vector-index-auto.js.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +9 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +65 -20
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +7 -3
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +3 -2
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +0 -3
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +5 -14
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +12 -10
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts +14 -43
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js +6 -29
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +174 -321
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +522 -1195
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts +116 -0
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js +277 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js.map +1 -0
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts +26 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js +32 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts +58 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js +391 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts +37 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js +68 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts +295 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.js +1022 -0
- package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts +23 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.js +3 -0
- package/dist/DashboardEditor/dashboard-editor.types.js.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts +11 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js +17 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js.map +1 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +26 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +302 -219
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -5
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.d.ts +0 -14
- package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.js +7 -29
- package/dist/FormBuilder/form-builder-resource.component.js.map +1 -1
- package/dist/Home/home-agent-context.d.ts +29 -10
- package/dist/Home/home-agent-context.d.ts.map +1 -1
- package/dist/Home/home-agent-context.js +50 -24
- package/dist/Home/home-agent-context.js.map +1 -1
- package/dist/Home/home-dashboard-switcher.component.d.ts +95 -0
- package/dist/Home/home-dashboard-switcher.component.d.ts.map +1 -0
- package/dist/Home/home-dashboard-switcher.component.js +442 -0
- package/dist/Home/home-dashboard-switcher.component.js.map +1 -0
- package/dist/Home/home-dashboard.component.d.ts +330 -17
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +1702 -1014
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Home/home-menus.d.ts +38 -0
- package/dist/Home/home-menus.d.ts.map +1 -0
- package/dist/Home/home-menus.js +53 -0
- package/dist/Home/home-menus.js.map +1 -0
- package/dist/Home/home-pinned-dashboards.d.ts +33 -0
- package/dist/Home/home-pinned-dashboards.d.ts.map +1 -0
- package/dist/Home/home-pinned-dashboards.js +76 -0
- package/dist/Home/home-pinned-dashboards.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-production.component.d.ts +5 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +64 -41
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +3 -2
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js +2 -2
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js.map +1 -1
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts +1 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts.map +1 -1
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js +7 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +7 -7
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +21 -20
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +4 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +69 -62
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +22 -2
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +1 -1
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +3 -1
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/dist/shared/dashboard-library-changes.d.ts +23 -0
- package/dist/shared/dashboard-library-changes.d.ts.map +1 -0
- package/dist/shared/dashboard-library-changes.js +26 -0
- package/dist/shared/dashboard-library-changes.js.map +1 -0
- package/dist/shared/dashboard-owner-names.d.ts +17 -0
- package/dist/shared/dashboard-owner-names.d.ts.map +1 -0
- package/dist/shared/dashboard-owner-names.js +65 -0
- package/dist/shared/dashboard-owner-names.js.map +1 -0
- package/dist/shared/dashboard-recents.d.ts +34 -0
- package/dist/shared/dashboard-recents.d.ts.map +1 -0
- package/dist/shared/dashboard-recents.js +87 -0
- package/dist/shared/dashboard-recents.js.map +1 -0
- package/dist/shared/dashboards-app-install.d.ts +59 -0
- package/dist/shared/dashboards-app-install.d.ts.map +1 -0
- package/dist/shared/dashboards-app-install.js +97 -0
- package/dist/shared/dashboards-app-install.js.map +1 -0
- package/dist/shared/dashboards-app.helpers.d.ts +42 -0
- package/dist/shared/dashboards-app.helpers.d.ts.map +1 -0
- package/dist/shared/dashboards-app.helpers.js +143 -0
- package/dist/shared/dashboards-app.helpers.js.map +1 -0
- package/package.json +69 -68
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, ViewChild, inject, } from '@angular/core';
|
|
2
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
3
|
+
import { MenuAnchorOf, NextMenuFocusIndex, PlaceMenu } from './home-menus';
|
|
4
|
+
import { FilterSwitcherDashboards } from './home-pinned-dashboards';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@angular/common";
|
|
7
|
+
import * as i2 from "@memberjunction/ng-ui-components";
|
|
8
|
+
const _c0 = ["trigger"];
|
|
9
|
+
const _c1 = ["menu"];
|
|
10
|
+
const _forTrack0 = ($index, $item) => $item.ID;
|
|
11
|
+
function HomeDashboardSwitcherComponent_Conditional_0_Case_0_Template(rf, ctx) { if (rf & 1) {
|
|
12
|
+
i0.ɵɵelementStart(0, "h1", 5);
|
|
13
|
+
i0.ɵɵelementContainer(1, 6);
|
|
14
|
+
i0.ɵɵelementEnd();
|
|
15
|
+
} if (rf & 2) {
|
|
16
|
+
i0.ɵɵnextContext(2);
|
|
17
|
+
const titleTrigger_r1 = i0.ɵɵreference(4);
|
|
18
|
+
i0.ɵɵadvance();
|
|
19
|
+
i0.ɵɵproperty("ngTemplateOutlet", titleTrigger_r1);
|
|
20
|
+
} }
|
|
21
|
+
function HomeDashboardSwitcherComponent_Conditional_0_Case_1_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
+
i0.ɵɵelementStart(0, "h2", 5);
|
|
23
|
+
i0.ɵɵelementContainer(1, 6);
|
|
24
|
+
i0.ɵɵelementEnd();
|
|
25
|
+
} if (rf & 2) {
|
|
26
|
+
i0.ɵɵnextContext(2);
|
|
27
|
+
const titleTrigger_r1 = i0.ɵɵreference(4);
|
|
28
|
+
i0.ɵɵadvance();
|
|
29
|
+
i0.ɵɵproperty("ngTemplateOutlet", titleTrigger_r1);
|
|
30
|
+
} }
|
|
31
|
+
function HomeDashboardSwitcherComponent_Conditional_0_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
+
i0.ɵɵelementContainer(0, 6);
|
|
33
|
+
} if (rf & 2) {
|
|
34
|
+
i0.ɵɵnextContext(2);
|
|
35
|
+
const titleTrigger_r1 = i0.ɵɵreference(4);
|
|
36
|
+
i0.ɵɵproperty("ngTemplateOutlet", titleTrigger_r1);
|
|
37
|
+
} }
|
|
38
|
+
function HomeDashboardSwitcherComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
39
|
+
i0.ɵɵconditionalCreate(0, HomeDashboardSwitcherComponent_Conditional_0_Case_0_Template, 2, 1, "h1", 5)(1, HomeDashboardSwitcherComponent_Conditional_0_Case_1_Template, 2, 1, "h2", 5)(2, HomeDashboardSwitcherComponent_Conditional_0_Case_2_Template, 1, 1, "ng-container", 6);
|
|
40
|
+
} if (rf & 2) {
|
|
41
|
+
let tmp_2_0;
|
|
42
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
43
|
+
i0.ɵɵconditional((tmp_2_0 = ctx_r1.HeadingLevel) === 1 ? 0 : tmp_2_0 === 2 ? 1 : 2);
|
|
44
|
+
} }
|
|
45
|
+
function HomeDashboardSwitcherComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
46
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
47
|
+
i0.ɵɵelementStart(0, "button", 7, 1);
|
|
48
|
+
i0.ɵɵlistener("click", function HomeDashboardSwitcherComponent_Conditional_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Toggle()); });
|
|
49
|
+
i0.ɵɵelement(2, "i", 8);
|
|
50
|
+
i0.ɵɵelementStart(3, "span", 9);
|
|
51
|
+
i0.ɵɵtext(4);
|
|
52
|
+
i0.ɵɵelementEnd();
|
|
53
|
+
i0.ɵɵelement(5, "i", 10);
|
|
54
|
+
i0.ɵɵelementEnd();
|
|
55
|
+
} if (rf & 2) {
|
|
56
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
57
|
+
i0.ɵɵattribute("aria-expanded", ctx_r1.IsOpen);
|
|
58
|
+
i0.ɵɵadvance(4);
|
|
59
|
+
i0.ɵɵtextInterpolate(ctx_r1.Label);
|
|
60
|
+
} }
|
|
61
|
+
function HomeDashboardSwitcherComponent_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
62
|
+
i0.ɵɵelement(0, "i", 17);
|
|
63
|
+
} }
|
|
64
|
+
function HomeDashboardSwitcherComponent_Conditional_2_For_11_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
65
|
+
i0.ɵɵelement(0, "i", 17);
|
|
66
|
+
} }
|
|
67
|
+
function HomeDashboardSwitcherComponent_Conditional_2_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
68
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
69
|
+
i0.ɵɵelementStart(0, "button", 25);
|
|
70
|
+
i0.ɵɵlistener("click", function HomeDashboardSwitcherComponent_Conditional_2_For_11_Template_button_click_0_listener() { const d_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.Choose(d_r6.ID)); });
|
|
71
|
+
i0.ɵɵelement(1, "i", 8);
|
|
72
|
+
i0.ɵɵelementStart(2, "span", 16);
|
|
73
|
+
i0.ɵɵtext(3);
|
|
74
|
+
i0.ɵɵelementEnd();
|
|
75
|
+
i0.ɵɵconditionalCreate(4, HomeDashboardSwitcherComponent_Conditional_2_For_11_Conditional_4_Template, 1, 0, "i", 17);
|
|
76
|
+
i0.ɵɵelementEnd();
|
|
77
|
+
} if (rf & 2) {
|
|
78
|
+
const d_r6 = ctx.$implicit;
|
|
79
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
80
|
+
i0.ɵɵclassProp("current", ctx_r1.IsCurrent(d_r6));
|
|
81
|
+
i0.ɵɵattribute("aria-current", ctx_r1.IsCurrent(d_r6) ? "true" : null);
|
|
82
|
+
i0.ɵɵadvance(3);
|
|
83
|
+
i0.ɵɵtextInterpolate(d_r6.Name);
|
|
84
|
+
i0.ɵɵadvance();
|
|
85
|
+
i0.ɵɵconditional(ctx_r1.IsCurrent(d_r6) ? 4 : -1);
|
|
86
|
+
} }
|
|
87
|
+
function HomeDashboardSwitcherComponent_Conditional_2_ForEmpty_12_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
+
i0.ɵɵelementStart(0, "div", 20);
|
|
89
|
+
i0.ɵɵtext(1);
|
|
90
|
+
i0.ɵɵelementEnd();
|
|
91
|
+
} if (rf & 2) {
|
|
92
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
93
|
+
i0.ɵɵadvance();
|
|
94
|
+
i0.ɵɵtextInterpolate(ctx_r1.Query.trim() ? "No pinned dashboard matches." : "No pinned dashboards yet.");
|
|
95
|
+
} }
|
|
96
|
+
function HomeDashboardSwitcherComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
97
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
98
|
+
i0.ɵɵelementStart(0, "div", 11, 2);
|
|
99
|
+
i0.ɵɵlistener("keydown", function HomeDashboardSwitcherComponent_Conditional_2_Template_div_keydown_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnMenuKeydown($event)); });
|
|
100
|
+
i0.ɵɵelementStart(2, "mj-page-search", 12);
|
|
101
|
+
i0.ɵɵlistener("ValueChange", function HomeDashboardSwitcherComponent_Conditional_2_Template_mj_page_search_ValueChange_2_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Query = $event); });
|
|
102
|
+
i0.ɵɵelementEnd();
|
|
103
|
+
i0.ɵɵelementStart(3, "div", 13)(4, "button", 14);
|
|
104
|
+
i0.ɵɵlistener("click", function HomeDashboardSwitcherComponent_Conditional_2_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Choose(null)); });
|
|
105
|
+
i0.ɵɵelement(5, "i", 15);
|
|
106
|
+
i0.ɵɵelementStart(6, "span", 16);
|
|
107
|
+
i0.ɵɵtext(7, "Home");
|
|
108
|
+
i0.ɵɵelementEnd();
|
|
109
|
+
i0.ɵɵconditionalCreate(8, HomeDashboardSwitcherComponent_Conditional_2_Conditional_8_Template, 1, 0, "i", 17);
|
|
110
|
+
i0.ɵɵelementEnd();
|
|
111
|
+
i0.ɵɵelement(9, "div", 18);
|
|
112
|
+
i0.ɵɵrepeaterCreate(10, HomeDashboardSwitcherComponent_Conditional_2_For_11_Template, 5, 5, "button", 19, _forTrack0, false, HomeDashboardSwitcherComponent_Conditional_2_ForEmpty_12_Template, 2, 1, "div", 20);
|
|
113
|
+
i0.ɵɵelementEnd();
|
|
114
|
+
i0.ɵɵelement(13, "div", 18);
|
|
115
|
+
i0.ɵɵelementStart(14, "button", 21);
|
|
116
|
+
i0.ɵɵlistener("click", function HomeDashboardSwitcherComponent_Conditional_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ChooseNew()); });
|
|
117
|
+
i0.ɵɵelement(15, "i", 22);
|
|
118
|
+
i0.ɵɵelementStart(16, "span", 16);
|
|
119
|
+
i0.ɵɵtext(17, "New dashboard");
|
|
120
|
+
i0.ɵɵelementEnd()();
|
|
121
|
+
i0.ɵɵelementStart(18, "button", 23);
|
|
122
|
+
i0.ɵɵlistener("click", function HomeDashboardSwitcherComponent_Conditional_2_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ChooseManagePins()); });
|
|
123
|
+
i0.ɵɵelement(19, "i", 24);
|
|
124
|
+
i0.ɵɵelementStart(20, "span", 16);
|
|
125
|
+
i0.ɵɵtext(21, "Manage pins");
|
|
126
|
+
i0.ɵɵelementEnd()()();
|
|
127
|
+
} if (rf & 2) {
|
|
128
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
129
|
+
i0.ɵɵstyleProp("left", ctx_r1.MenuLeft, "px")("top", ctx_r1.MenuTop, "px")("max-height", ctx_r1.MenuMaxHeight, "px");
|
|
130
|
+
i0.ɵɵadvance(2);
|
|
131
|
+
i0.ɵɵproperty("Value", ctx_r1.Query);
|
|
132
|
+
i0.ɵɵadvance(2);
|
|
133
|
+
i0.ɵɵclassProp("current", !ctx_r1.CurrentId);
|
|
134
|
+
i0.ɵɵattribute("aria-current", !ctx_r1.CurrentId ? "true" : null);
|
|
135
|
+
i0.ɵɵadvance(4);
|
|
136
|
+
i0.ɵɵconditional(!ctx_r1.CurrentId ? 8 : -1);
|
|
137
|
+
i0.ɵɵadvance(2);
|
|
138
|
+
i0.ɵɵrepeater(ctx_r1.FilteredDashboards);
|
|
139
|
+
} }
|
|
140
|
+
function HomeDashboardSwitcherComponent_ng_template_3_Template(rf, ctx) { if (rf & 1) {
|
|
141
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
142
|
+
i0.ɵɵelementStart(0, "button", 26, 1);
|
|
143
|
+
i0.ɵɵlistener("click", function HomeDashboardSwitcherComponent_ng_template_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Toggle()); });
|
|
144
|
+
i0.ɵɵelementStart(2, "span", 27);
|
|
145
|
+
i0.ɵɵtext(3);
|
|
146
|
+
i0.ɵɵelementEnd();
|
|
147
|
+
i0.ɵɵelement(4, "i", 28);
|
|
148
|
+
i0.ɵɵelementEnd();
|
|
149
|
+
} if (rf & 2) {
|
|
150
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
151
|
+
i0.ɵɵattribute("aria-expanded", ctx_r1.IsOpen);
|
|
152
|
+
i0.ɵɵadvance(3);
|
|
153
|
+
i0.ɵɵtextInterpolate(ctx_r1.Label);
|
|
154
|
+
} }
|
|
155
|
+
/** Width of the switcher menu, in pixels. Keep in step with the width in `.switcher-menu`. */
|
|
156
|
+
const SWITCHER_MENU_WIDTH = 300;
|
|
157
|
+
/** True when `target` is `container` or a node inside it. */
|
|
158
|
+
function isInside(container, target) {
|
|
159
|
+
return !!container && target instanceof Node && container.contains(target);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The Dashboards switcher on Home: a trigger and a menu with a filter box, Home, the pinned dashboards, New dashboard
|
|
163
|
+
* and Manage pins. The Pinned header shows it as the "Dashboards" button (menu right-aligned); the dashboard view shows
|
|
164
|
+
* it as the dashboard title (menu left-aligned), whose trigger can be a heading (HeadingLevel). The menu is
|
|
165
|
+
* fixed-position under the trigger, so a collapsed accordion does not clip it. A click outside, Escape, focus moving
|
|
166
|
+
* out, a change of the window's width or a page scroll closes it. Home handles the picks.
|
|
167
|
+
*/
|
|
168
|
+
export class HomeDashboardSwitcherComponent {
|
|
169
|
+
/** The pinned dashboards, in pin order. */
|
|
170
|
+
Dashboards = [];
|
|
171
|
+
/** The dashboard Home shows, or null on the overview. */
|
|
172
|
+
CurrentId = null;
|
|
173
|
+
/** 'button': the Pinned header button. 'title': the dashboard title in the dashboard view. */
|
|
174
|
+
Look = 'button';
|
|
175
|
+
/** The trigger text: "Dashboards" for the button, the dashboard name for the title. */
|
|
176
|
+
Label = 'Dashboards';
|
|
177
|
+
/** 'right' lines the menu up with the trigger's right edge; 'left' with its left edge. */
|
|
178
|
+
Align = 'right';
|
|
179
|
+
/**
|
|
180
|
+
* For the title look: 1 or 2 puts the trigger in an h1 or h2, with no margin or font of its own, and the menu stays
|
|
181
|
+
* outside the heading. Null puts it in no heading. The button look ignores it.
|
|
182
|
+
*/
|
|
183
|
+
HeadingLevel = null;
|
|
184
|
+
/** Emits the dashboard the user picks, or null for Home. */
|
|
185
|
+
Pick = new EventEmitter();
|
|
186
|
+
/** Emits when the user picks New dashboard. */
|
|
187
|
+
New = new EventEmitter();
|
|
188
|
+
/** Emits when the user picks Manage pins. */
|
|
189
|
+
ManagePins = new EventEmitter();
|
|
190
|
+
/** True while the menu shows. */
|
|
191
|
+
IsOpen = false;
|
|
192
|
+
/** The text in the filter box. */
|
|
193
|
+
Query = '';
|
|
194
|
+
/** The menu's left edge, in viewport pixels. */
|
|
195
|
+
MenuLeft = 0;
|
|
196
|
+
/** The menu's top edge, in viewport pixels. */
|
|
197
|
+
MenuTop = 0;
|
|
198
|
+
/** The menu's max height in pixels: the room on its side of the trigger. Null while the menu is measured. */
|
|
199
|
+
MenuMaxHeight = null;
|
|
200
|
+
trigger;
|
|
201
|
+
menu;
|
|
202
|
+
host = inject(ElementRef);
|
|
203
|
+
cdr = inject(ChangeDetectorRef);
|
|
204
|
+
/** The window's width when the menu opened. A resize that keeps it, such as an on-screen keyboard opening, keeps the menu open. */
|
|
205
|
+
openWidth = 0;
|
|
206
|
+
/**
|
|
207
|
+
* Closes the menu on a click outside the switcher. It listens in the capture phase, so a click whose target stops
|
|
208
|
+
* it still counts.
|
|
209
|
+
*/
|
|
210
|
+
onDocumentClick = (event) => {
|
|
211
|
+
if (!isInside(this.host.nativeElement, event.target)) {
|
|
212
|
+
this.Close();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
/** Closes the menu when the page scrolls under it. A scroll inside the menu, such as its list, keeps it open. */
|
|
216
|
+
onScroll = (event) => {
|
|
217
|
+
if (!isInside(this.menu?.nativeElement, event.target)) {
|
|
218
|
+
this.Close();
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
/** The pinned dashboards whose name matches the filter box. */
|
|
222
|
+
get FilteredDashboards() {
|
|
223
|
+
return FilterSwitcherDashboards(this.Dashboards, this.Query);
|
|
224
|
+
}
|
|
225
|
+
/** True for the dashboard Home shows. */
|
|
226
|
+
IsCurrent(dashboard) {
|
|
227
|
+
return UUIDsEqual(dashboard.ID, this.CurrentId);
|
|
228
|
+
}
|
|
229
|
+
/** Opens the menu when it is closed, and closes it when it is open. */
|
|
230
|
+
Toggle() {
|
|
231
|
+
if (this.IsOpen) {
|
|
232
|
+
this.Close();
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
this.Open();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/** Opens the menu under the trigger, inside the viewport, with an empty filter box that has focus. */
|
|
239
|
+
Open() {
|
|
240
|
+
const trigger = this.trigger?.nativeElement;
|
|
241
|
+
if (!trigger)
|
|
242
|
+
return;
|
|
243
|
+
const anchor = MenuAnchorOf(trigger);
|
|
244
|
+
this.Query = '';
|
|
245
|
+
this.IsOpen = true;
|
|
246
|
+
this.openWidth = window.innerWidth;
|
|
247
|
+
this.placeMenu(anchor, 0);
|
|
248
|
+
// Render the menu with no max height to measure its full height, then place it again with that height
|
|
249
|
+
this.MenuMaxHeight = null;
|
|
250
|
+
this.cdr.detectChanges();
|
|
251
|
+
this.placeMenu(anchor, this.menu?.nativeElement.offsetHeight ?? 0);
|
|
252
|
+
this.cdr.detectChanges();
|
|
253
|
+
const filter = this.host.nativeElement.querySelector('.switcher-menu mj-page-search input');
|
|
254
|
+
filter?.focus({ preventScroll: true });
|
|
255
|
+
document.addEventListener('click', this.onDocumentClick, true);
|
|
256
|
+
document.addEventListener('scroll', this.onScroll, true);
|
|
257
|
+
}
|
|
258
|
+
/** Closes the menu. `returnFocus` puts focus back on the trigger (Escape). */
|
|
259
|
+
Close(returnFocus = false) {
|
|
260
|
+
if (!this.IsOpen)
|
|
261
|
+
return;
|
|
262
|
+
this.IsOpen = false;
|
|
263
|
+
this.stopWatchingPage();
|
|
264
|
+
this.cdr.markForCheck();
|
|
265
|
+
if (returnFocus) {
|
|
266
|
+
this.trigger?.nativeElement.focus();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/** Closes the menu and emits the picked dashboard, or null for Home. */
|
|
270
|
+
Choose(dashboardId) {
|
|
271
|
+
this.Close();
|
|
272
|
+
this.Pick.emit(dashboardId);
|
|
273
|
+
}
|
|
274
|
+
/** Closes the menu and emits New. */
|
|
275
|
+
ChooseNew() {
|
|
276
|
+
this.Close();
|
|
277
|
+
this.New.emit();
|
|
278
|
+
}
|
|
279
|
+
/** Closes the menu and emits ManagePins. */
|
|
280
|
+
ChooseManagePins() {
|
|
281
|
+
this.Close();
|
|
282
|
+
this.ManagePins.emit();
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Keys in the menu: Escape closes it and puts focus back on the trigger. ArrowDown and ArrowUp move from the filter
|
|
286
|
+
* box to the first or last row and between the rows; Home and End move between the rows. Other keys do nothing here.
|
|
287
|
+
*/
|
|
288
|
+
OnMenuKeydown(event) {
|
|
289
|
+
if (event.key === 'Escape') {
|
|
290
|
+
event.preventDefault();
|
|
291
|
+
this.Close(true);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const rows = Array.from(this.menu?.nativeElement.querySelectorAll('button.switcher-item') ?? []);
|
|
295
|
+
const next = NextMenuFocusIndex(event.key, rows.findIndex(row => row === document.activeElement), rows.length);
|
|
296
|
+
if (next !== null) {
|
|
297
|
+
event.preventDefault();
|
|
298
|
+
rows[next].focus();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/** Closes the menu when focus moves to an element outside the switcher, as Tab does past the last row. */
|
|
302
|
+
OnFocusOut(event) {
|
|
303
|
+
if (this.IsOpen && event.relatedTarget instanceof Node && !isInside(this.host.nativeElement, event.relatedTarget)) {
|
|
304
|
+
this.Close();
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Closes the menu when the window's width differs from its width at open. A resize of the height only, such as an
|
|
309
|
+
* on-screen keyboard opening for the filter box, keeps the menu open.
|
|
310
|
+
*/
|
|
311
|
+
OnWindowResize() {
|
|
312
|
+
if (window.innerWidth !== this.openWidth) {
|
|
313
|
+
this.Close();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
ngOnDestroy() {
|
|
317
|
+
this.stopWatchingPage();
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Places the menu next to the trigger, lined up by Align, and limits its height to the room on that side. A height
|
|
321
|
+
* of 0 places it below the trigger.
|
|
322
|
+
*/
|
|
323
|
+
placeMenu(anchor, height) {
|
|
324
|
+
const viewport = { Width: window.innerWidth, Height: window.innerHeight };
|
|
325
|
+
const place = PlaceMenu(anchor, SWITCHER_MENU_WIDTH, height, this.Align, viewport);
|
|
326
|
+
this.MenuLeft = place.Left;
|
|
327
|
+
this.MenuTop = place.Top;
|
|
328
|
+
this.MenuMaxHeight = place.MaxHeight;
|
|
329
|
+
}
|
|
330
|
+
/** Removes the page click and scroll listeners the open menu uses. */
|
|
331
|
+
stopWatchingPage() {
|
|
332
|
+
document.removeEventListener('click', this.onDocumentClick, true);
|
|
333
|
+
document.removeEventListener('scroll', this.onScroll, true);
|
|
334
|
+
}
|
|
335
|
+
static ɵfac = function HomeDashboardSwitcherComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HomeDashboardSwitcherComponent)(); };
|
|
336
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: HomeDashboardSwitcherComponent, selectors: [["mj-home-dashboard-switcher"]], viewQuery: function HomeDashboardSwitcherComponent_Query(rf, ctx) { if (rf & 1) {
|
|
337
|
+
i0.ɵɵviewQuery(_c0, 5)(_c1, 5);
|
|
338
|
+
} if (rf & 2) {
|
|
339
|
+
let _t;
|
|
340
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.trigger = _t.first);
|
|
341
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.menu = _t.first);
|
|
342
|
+
} }, hostBindings: function HomeDashboardSwitcherComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
343
|
+
i0.ɵɵlistener("focusout", function HomeDashboardSwitcherComponent_focusout_HostBindingHandler($event) { return ctx.OnFocusOut($event); })("resize", function HomeDashboardSwitcherComponent_resize_HostBindingHandler() { return ctx.OnWindowResize(); }, i0.ɵɵresolveWindow);
|
|
344
|
+
} }, inputs: { Dashboards: "Dashboards", CurrentId: "CurrentId", Look: "Look", Label: "Label", Align: "Align", HeadingLevel: "HeadingLevel" }, outputs: { Pick: "Pick", New: "New", ManagePins: "ManagePins" }, standalone: false, decls: 5, vars: 2, consts: [["titleTrigger", ""], ["trigger", ""], ["menu", ""], ["type", "button", "mjButton", "", "Variant", "secondary", "Size", "sm", "aria-haspopup", "dialog", 1, "switcher-button"], ["role", "dialog", "aria-label", "Pinned dashboards", 1, "switcher-menu", 3, "left", "top", "max-height"], [1, "switcher-heading"], [3, "ngTemplateOutlet"], ["type", "button", "mjButton", "", "Variant", "secondary", "Size", "sm", "aria-haspopup", "dialog", 1, "switcher-button", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-gauge-high"], [1, "switcher-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["role", "dialog", "aria-label", "Pinned dashboards", 1, "switcher-menu", 3, "keydown"], ["Icon", "fa-solid fa-magnifying-glass", "Placeholder", "Find a pinned dashboard", "AriaLabel", "Find a pinned dashboard", 3, "ValueChange", "Value"], [1, "switcher-list"], ["type", "button", 1, "switcher-item", "switcher-home", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-house"], [1, "switcher-item-name"], ["aria-hidden", "true", 1, "fa-solid", "fa-check", "switcher-check"], ["role", "separator", 1, "switcher-divider"], ["type", "button", 1, "switcher-item", "switcher-dashboard", 3, "current"], [1, "switcher-empty"], ["type", "button", 1, "switcher-item", "switcher-new", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["type", "button", 1, "switcher-item", "switcher-manage", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-thumbtack"], ["type", "button", 1, "switcher-item", "switcher-dashboard", 3, "click"], ["type", "button", "aria-haspopup", "dialog", 1, "switcher-title", 3, "click"], [1, "switcher-title-text"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down", "switcher-chevron"]], template: function HomeDashboardSwitcherComponent_Template(rf, ctx) { if (rf & 1) {
|
|
345
|
+
i0.ɵɵconditionalCreate(0, HomeDashboardSwitcherComponent_Conditional_0_Template, 3, 1)(1, HomeDashboardSwitcherComponent_Conditional_1_Template, 6, 2, "button", 3);
|
|
346
|
+
i0.ɵɵconditionalCreate(2, HomeDashboardSwitcherComponent_Conditional_2_Template, 22, 12, "div", 4);
|
|
347
|
+
i0.ɵɵtemplate(3, HomeDashboardSwitcherComponent_ng_template_3_Template, 5, 2, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
348
|
+
} if (rf & 2) {
|
|
349
|
+
i0.ɵɵconditional(ctx.Look === "title" ? 0 : 1);
|
|
350
|
+
i0.ɵɵadvance(2);
|
|
351
|
+
i0.ɵɵconditional(ctx.IsOpen ? 2 : -1);
|
|
352
|
+
} }, dependencies: [i1.NgTemplateOutlet, i2.MJButtonDirective, i2.MJPageSearchComponent], styles: ["[_nghost-%COMP%] { display: inline-flex; min-width: 0; max-width: 100%; }\n .switcher-heading[_ngcontent-%COMP%] { display: flex; min-width: 0; max-width: 100%; margin: 0; font: inherit; }\n \n .switcher-title[_ngcontent-%COMP%] {\n display: inline-flex; align-items: center; gap: var(--mj-space-3); max-width: 100%;\n position: relative; left: calc(-1 * var(--mj-space-2)); padding: var(--mj-space-1) var(--mj-space-2);\n border: 0; border-radius: var(--mj-radius-md); background: transparent; color: var(--mj-text-primary);\n font: inherit; font-size: var(--mj-text-lg); font-weight: var(--mj-font-bold); letter-spacing: var(--mj-tracking-tight);\n cursor: pointer;\n }\n .switcher-title[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .switcher-title[_ngcontent-%COMP%]:focus-visible { outline: none; box-shadow: var(--mj-focus-ring); }\n .switcher-title-text[_ngcontent-%COMP%] { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }\n .switcher-chevron[_ngcontent-%COMP%] { font-size: 11px; color: var(--mj-text-muted); }\n .switcher-menu[_ngcontent-%COMP%] {\n position: fixed; z-index: 10001; width: 300px; overflow-y: auto; padding: 6px;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md); box-shadow: var(--mj-shadow-lg);\n animation: _ngcontent-%COMP%_switcher-in var(--mj-transition-fast);\n }\n @keyframes _ngcontent-%COMP%_switcher-in { from { opacity: 0; } to { opacity: 1; } }\n .switcher-menu[_ngcontent-%COMP%] mj-page-search[_ngcontent-%COMP%] { display: flex; width: 100%; min-width: 0; }\n .switcher-list[_ngcontent-%COMP%] { max-height: 290px; overflow: auto; margin-top: 6px; }\n .switcher-item[_ngcontent-%COMP%] {\n display: flex; align-items: center; gap: var(--mj-space-3); width: 100%; padding: 8px 10px;\n border: 0; border-radius: var(--mj-radius-sm); background: transparent;\n font: inherit; font-size: var(--mj-text-sm); color: var(--mj-text-primary); text-align: left; cursor: pointer;\n }\n .switcher-item[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n .switcher-item[_ngcontent-%COMP%]:focus-visible {\n outline: none; background: var(--mj-bg-surface-hover);\n box-shadow: inset 0 0 0 var(--mj-ring-width) var(--mj-focus-ring-color);\n }\n .switcher-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%]:first-child { width: 14px; text-align: center; font-size: 12px; color: var(--mj-text-muted); }\n .switcher-item-name[_ngcontent-%COMP%] { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }\n .switcher-item.current[_ngcontent-%COMP%] { color: var(--mj-brand-primary); font-weight: var(--mj-font-semibold); }\n .switcher-item.current[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n .switcher-check[_ngcontent-%COMP%] { margin-left: auto; font-size: 12px; }\n .switcher-divider[_ngcontent-%COMP%] { height: 1px; margin: 6px 4px; background: var(--mj-border-default); }\n .switcher-empty[_ngcontent-%COMP%] { padding: 8px 10px; font-size: var(--mj-text-xs); color: var(--mj-text-muted); }\n @media (max-width: 480px) {\n .switcher-label[_ngcontent-%COMP%] {\n position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;\n overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;\n }\n }\n @media (prefers-reduced-motion: reduce) { .switcher-menu[_ngcontent-%COMP%] { animation: none; } }"], changeDetection: 0 });
|
|
353
|
+
}
|
|
354
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HomeDashboardSwitcherComponent, [{
|
|
355
|
+
type: Component,
|
|
356
|
+
args: [{ standalone: false, selector: 'mj-home-dashboard-switcher', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
357
|
+
@if (Look === 'title') {
|
|
358
|
+
@switch (HeadingLevel) {
|
|
359
|
+
@case (1) { <h1 class="switcher-heading"><ng-container [ngTemplateOutlet]="titleTrigger"></ng-container></h1> }
|
|
360
|
+
@case (2) { <h2 class="switcher-heading"><ng-container [ngTemplateOutlet]="titleTrigger"></ng-container></h2> }
|
|
361
|
+
@default { <ng-container [ngTemplateOutlet]="titleTrigger"></ng-container> }
|
|
362
|
+
}
|
|
363
|
+
} @else {
|
|
364
|
+
<button #trigger type="button" mjButton Variant="secondary" Size="sm" class="switcher-button"
|
|
365
|
+
aria-haspopup="dialog" [attr.aria-expanded]="IsOpen" (click)="Toggle()">
|
|
366
|
+
<i class="fa-solid fa-gauge-high" aria-hidden="true"></i>
|
|
367
|
+
<span class="switcher-label">{{ Label }}</span>
|
|
368
|
+
<i class="fa-solid fa-chevron-down" aria-hidden="true"></i>
|
|
369
|
+
</button>
|
|
370
|
+
}
|
|
371
|
+
@if (IsOpen) {
|
|
372
|
+
<div #menu class="switcher-menu" role="dialog" aria-label="Pinned dashboards"
|
|
373
|
+
[style.left.px]="MenuLeft" [style.top.px]="MenuTop" [style.max-height.px]="MenuMaxHeight" (keydown)="OnMenuKeydown($event)">
|
|
374
|
+
<mj-page-search Icon="fa-solid fa-magnifying-glass" Placeholder="Find a pinned dashboard"
|
|
375
|
+
AriaLabel="Find a pinned dashboard" [Value]="Query" (ValueChange)="Query = $event"></mj-page-search>
|
|
376
|
+
<div class="switcher-list">
|
|
377
|
+
<button type="button" class="switcher-item switcher-home" [class.current]="!CurrentId"
|
|
378
|
+
[attr.aria-current]="!CurrentId ? 'true' : null" (click)="Choose(null)">
|
|
379
|
+
<i class="fa-solid fa-house" aria-hidden="true"></i><span class="switcher-item-name">Home</span>
|
|
380
|
+
@if (!CurrentId) { <i class="fa-solid fa-check switcher-check" aria-hidden="true"></i> }
|
|
381
|
+
</button>
|
|
382
|
+
<div class="switcher-divider" role="separator"></div>
|
|
383
|
+
@for (d of FilteredDashboards; track d.ID) {
|
|
384
|
+
<button type="button" class="switcher-item switcher-dashboard" [class.current]="IsCurrent(d)"
|
|
385
|
+
[attr.aria-current]="IsCurrent(d) ? 'true' : null" (click)="Choose(d.ID)">
|
|
386
|
+
<i class="fa-solid fa-gauge-high" aria-hidden="true"></i><span class="switcher-item-name">{{ d.Name }}</span>
|
|
387
|
+
@if (IsCurrent(d)) { <i class="fa-solid fa-check switcher-check" aria-hidden="true"></i> }
|
|
388
|
+
</button>
|
|
389
|
+
} @empty {
|
|
390
|
+
<div class="switcher-empty">{{ Query.trim() ? 'No pinned dashboard matches.' : 'No pinned dashboards yet.' }}</div>
|
|
391
|
+
}
|
|
392
|
+
</div>
|
|
393
|
+
<div class="switcher-divider" role="separator"></div>
|
|
394
|
+
<button type="button" class="switcher-item switcher-new" (click)="ChooseNew()">
|
|
395
|
+
<i class="fa-solid fa-plus" aria-hidden="true"></i><span class="switcher-item-name">New dashboard</span>
|
|
396
|
+
</button>
|
|
397
|
+
<button type="button" class="switcher-item switcher-manage" (click)="ChooseManagePins()">
|
|
398
|
+
<i class="fa-solid fa-thumbtack" aria-hidden="true"></i><span class="switcher-item-name">Manage pins</span>
|
|
399
|
+
</button>
|
|
400
|
+
</div>
|
|
401
|
+
}
|
|
402
|
+
<!-- The title look's trigger; HeadingLevel puts it, and not the menu, in a heading -->
|
|
403
|
+
<ng-template #titleTrigger>
|
|
404
|
+
<button #trigger type="button" class="switcher-title" aria-haspopup="dialog" [attr.aria-expanded]="IsOpen" (click)="Toggle()">
|
|
405
|
+
<span class="switcher-title-text">{{ Label }}</span>
|
|
406
|
+
<i class="fa-solid fa-chevron-down switcher-chevron" aria-hidden="true"></i>
|
|
407
|
+
</button>
|
|
408
|
+
</ng-template>
|
|
409
|
+
`, styles: ["\n :host { display: inline-flex; min-width: 0; max-width: 100%; }\n .switcher-heading { display: flex; min-width: 0; max-width: 100%; margin: 0; font: inherit; }\n /* Shifted with left, not a negative margin: a negative margin makes the heading narrower than the name */\n .switcher-title {\n display: inline-flex; align-items: center; gap: var(--mj-space-3); max-width: 100%;\n position: relative; left: calc(-1 * var(--mj-space-2)); padding: var(--mj-space-1) var(--mj-space-2);\n border: 0; border-radius: var(--mj-radius-md); background: transparent; color: var(--mj-text-primary);\n font: inherit; font-size: var(--mj-text-lg); font-weight: var(--mj-font-bold); letter-spacing: var(--mj-tracking-tight);\n cursor: pointer;\n }\n .switcher-title:hover { background: var(--mj-bg-surface-hover); }\n .switcher-title:focus-visible { outline: none; box-shadow: var(--mj-focus-ring); }\n .switcher-title-text { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }\n .switcher-chevron { font-size: 11px; color: var(--mj-text-muted); }\n .switcher-menu {\n position: fixed; z-index: 10001; width: 300px; overflow-y: auto; padding: 6px;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md); box-shadow: var(--mj-shadow-lg);\n animation: switcher-in var(--mj-transition-fast);\n }\n @keyframes switcher-in { from { opacity: 0; } to { opacity: 1; } }\n .switcher-menu mj-page-search { display: flex; width: 100%; min-width: 0; }\n .switcher-list { max-height: 290px; overflow: auto; margin-top: 6px; }\n .switcher-item {\n display: flex; align-items: center; gap: var(--mj-space-3); width: 100%; padding: 8px 10px;\n border: 0; border-radius: var(--mj-radius-sm); background: transparent;\n font: inherit; font-size: var(--mj-text-sm); color: var(--mj-text-primary); text-align: left; cursor: pointer;\n }\n .switcher-item:hover { background: var(--mj-bg-surface-hover); }\n .switcher-item:focus-visible {\n outline: none; background: var(--mj-bg-surface-hover);\n box-shadow: inset 0 0 0 var(--mj-ring-width) var(--mj-focus-ring-color);\n }\n .switcher-item > i:first-child { width: 14px; text-align: center; font-size: 12px; color: var(--mj-text-muted); }\n .switcher-item-name { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }\n .switcher-item.current { color: var(--mj-brand-primary); font-weight: var(--mj-font-semibold); }\n .switcher-item.current i { color: var(--mj-brand-primary); }\n .switcher-check { margin-left: auto; font-size: 12px; }\n .switcher-divider { height: 1px; margin: 6px 4px; background: var(--mj-border-default); }\n .switcher-empty { padding: 8px 10px; font-size: var(--mj-text-xs); color: var(--mj-text-muted); }\n @media (max-width: 480px) {\n .switcher-label {\n position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;\n overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;\n }\n }\n @media (prefers-reduced-motion: reduce) { .switcher-menu { animation: none; } }\n "] }]
|
|
410
|
+
}], null, { Dashboards: [{
|
|
411
|
+
type: Input
|
|
412
|
+
}], CurrentId: [{
|
|
413
|
+
type: Input
|
|
414
|
+
}], Look: [{
|
|
415
|
+
type: Input
|
|
416
|
+
}], Label: [{
|
|
417
|
+
type: Input
|
|
418
|
+
}], Align: [{
|
|
419
|
+
type: Input
|
|
420
|
+
}], HeadingLevel: [{
|
|
421
|
+
type: Input
|
|
422
|
+
}], Pick: [{
|
|
423
|
+
type: Output
|
|
424
|
+
}], New: [{
|
|
425
|
+
type: Output
|
|
426
|
+
}], ManagePins: [{
|
|
427
|
+
type: Output
|
|
428
|
+
}], trigger: [{
|
|
429
|
+
type: ViewChild,
|
|
430
|
+
args: ['trigger']
|
|
431
|
+
}], menu: [{
|
|
432
|
+
type: ViewChild,
|
|
433
|
+
args: ['menu']
|
|
434
|
+
}], OnFocusOut: [{
|
|
435
|
+
type: HostListener,
|
|
436
|
+
args: ['focusout', ['$event']]
|
|
437
|
+
}], OnWindowResize: [{
|
|
438
|
+
type: HostListener,
|
|
439
|
+
args: ['window:resize']
|
|
440
|
+
}] }); })();
|
|
441
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(HomeDashboardSwitcherComponent, { className: "HomeDashboardSwitcherComponent", filePath: "src/Home/home-dashboard-switcher.component.ts", lineNumber: 141 }); })();
|
|
442
|
+
//# sourceMappingURL=home-dashboard-switcher.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"home-dashboard-switcher.component.js","sourceRoot":"","sources":["../../src/Home/home-dashboard-switcher.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n OnDestroy,\n Output,\n ViewChild,\n inject,\n} from '@angular/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { MenuAnchor, MenuAnchorOf, NextMenuFocusIndex, PlaceMenu } from './home-menus';\nimport { FilterSwitcherDashboards, HomeSwitcherDashboard } from './home-pinned-dashboards';\n\n/** Width of the switcher menu, in pixels. Keep in step with the width in `.switcher-menu`. */\nconst SWITCHER_MENU_WIDTH = 300;\n\n/** True when `target` is `container` or a node inside it. */\nfunction isInside(container: Element | undefined, target: EventTarget | null): boolean {\n return !!container && target instanceof Node && container.contains(target);\n}\n\n/**\n * The Dashboards switcher on Home: a trigger and a menu with a filter box, Home, the pinned dashboards, New dashboard\n * and Manage pins. The Pinned header shows it as the \"Dashboards\" button (menu right-aligned); the dashboard view shows\n * it as the dashboard title (menu left-aligned), whose trigger can be a heading (HeadingLevel). The menu is\n * fixed-position under the trigger, so a collapsed accordion does not clip it. A click outside, Escape, focus moving\n * out, a change of the window's width or a page scroll closes it. Home handles the picks.\n */\n@Component({\n standalone: false,\n selector: 'mj-home-dashboard-switcher',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (Look === 'title') {\n @switch (HeadingLevel) {\n @case (1) { <h1 class=\"switcher-heading\"><ng-container [ngTemplateOutlet]=\"titleTrigger\"></ng-container></h1> }\n @case (2) { <h2 class=\"switcher-heading\"><ng-container [ngTemplateOutlet]=\"titleTrigger\"></ng-container></h2> }\n @default { <ng-container [ngTemplateOutlet]=\"titleTrigger\"></ng-container> }\n }\n } @else {\n <button #trigger type=\"button\" mjButton Variant=\"secondary\" Size=\"sm\" class=\"switcher-button\"\n aria-haspopup=\"dialog\" [attr.aria-expanded]=\"IsOpen\" (click)=\"Toggle()\">\n <i class=\"fa-solid fa-gauge-high\" aria-hidden=\"true\"></i>\n <span class=\"switcher-label\">{{ Label }}</span>\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (IsOpen) {\n <div #menu class=\"switcher-menu\" role=\"dialog\" aria-label=\"Pinned dashboards\"\n [style.left.px]=\"MenuLeft\" [style.top.px]=\"MenuTop\" [style.max-height.px]=\"MenuMaxHeight\" (keydown)=\"OnMenuKeydown($event)\">\n <mj-page-search Icon=\"fa-solid fa-magnifying-glass\" Placeholder=\"Find a pinned dashboard\"\n AriaLabel=\"Find a pinned dashboard\" [Value]=\"Query\" (ValueChange)=\"Query = $event\"></mj-page-search>\n <div class=\"switcher-list\">\n <button type=\"button\" class=\"switcher-item switcher-home\" [class.current]=\"!CurrentId\"\n [attr.aria-current]=\"!CurrentId ? 'true' : null\" (click)=\"Choose(null)\">\n <i class=\"fa-solid fa-house\" aria-hidden=\"true\"></i><span class=\"switcher-item-name\">Home</span>\n @if (!CurrentId) { <i class=\"fa-solid fa-check switcher-check\" aria-hidden=\"true\"></i> }\n </button>\n <div class=\"switcher-divider\" role=\"separator\"></div>\n @for (d of FilteredDashboards; track d.ID) {\n <button type=\"button\" class=\"switcher-item switcher-dashboard\" [class.current]=\"IsCurrent(d)\"\n [attr.aria-current]=\"IsCurrent(d) ? 'true' : null\" (click)=\"Choose(d.ID)\">\n <i class=\"fa-solid fa-gauge-high\" aria-hidden=\"true\"></i><span class=\"switcher-item-name\">{{ d.Name }}</span>\n @if (IsCurrent(d)) { <i class=\"fa-solid fa-check switcher-check\" aria-hidden=\"true\"></i> }\n </button>\n } @empty {\n <div class=\"switcher-empty\">{{ Query.trim() ? 'No pinned dashboard matches.' : 'No pinned dashboards yet.' }}</div>\n }\n </div>\n <div class=\"switcher-divider\" role=\"separator\"></div>\n <button type=\"button\" class=\"switcher-item switcher-new\" (click)=\"ChooseNew()\">\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i><span class=\"switcher-item-name\">New dashboard</span>\n </button>\n <button type=\"button\" class=\"switcher-item switcher-manage\" (click)=\"ChooseManagePins()\">\n <i class=\"fa-solid fa-thumbtack\" aria-hidden=\"true\"></i><span class=\"switcher-item-name\">Manage pins</span>\n </button>\n </div>\n }\n <!-- The title look's trigger; HeadingLevel puts it, and not the menu, in a heading -->\n <ng-template #titleTrigger>\n <button #trigger type=\"button\" class=\"switcher-title\" aria-haspopup=\"dialog\" [attr.aria-expanded]=\"IsOpen\" (click)=\"Toggle()\">\n <span class=\"switcher-title-text\">{{ Label }}</span>\n <i class=\"fa-solid fa-chevron-down switcher-chevron\" aria-hidden=\"true\"></i>\n </button>\n </ng-template>\n `,\n styles: [`\n :host { display: inline-flex; min-width: 0; max-width: 100%; }\n .switcher-heading { display: flex; min-width: 0; max-width: 100%; margin: 0; font: inherit; }\n /* Shifted with left, not a negative margin: a negative margin makes the heading narrower than the name */\n .switcher-title {\n display: inline-flex; align-items: center; gap: var(--mj-space-3); max-width: 100%;\n position: relative; left: calc(-1 * var(--mj-space-2)); padding: var(--mj-space-1) var(--mj-space-2);\n border: 0; border-radius: var(--mj-radius-md); background: transparent; color: var(--mj-text-primary);\n font: inherit; font-size: var(--mj-text-lg); font-weight: var(--mj-font-bold); letter-spacing: var(--mj-tracking-tight);\n cursor: pointer;\n }\n .switcher-title:hover { background: var(--mj-bg-surface-hover); }\n .switcher-title:focus-visible { outline: none; box-shadow: var(--mj-focus-ring); }\n .switcher-title-text { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }\n .switcher-chevron { font-size: 11px; color: var(--mj-text-muted); }\n .switcher-menu {\n position: fixed; z-index: 10001; width: 300px; overflow-y: auto; padding: 6px;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md); box-shadow: var(--mj-shadow-lg);\n animation: switcher-in var(--mj-transition-fast);\n }\n @keyframes switcher-in { from { opacity: 0; } to { opacity: 1; } }\n .switcher-menu mj-page-search { display: flex; width: 100%; min-width: 0; }\n .switcher-list { max-height: 290px; overflow: auto; margin-top: 6px; }\n .switcher-item {\n display: flex; align-items: center; gap: var(--mj-space-3); width: 100%; padding: 8px 10px;\n border: 0; border-radius: var(--mj-radius-sm); background: transparent;\n font: inherit; font-size: var(--mj-text-sm); color: var(--mj-text-primary); text-align: left; cursor: pointer;\n }\n .switcher-item:hover { background: var(--mj-bg-surface-hover); }\n .switcher-item:focus-visible {\n outline: none; background: var(--mj-bg-surface-hover);\n box-shadow: inset 0 0 0 var(--mj-ring-width) var(--mj-focus-ring-color);\n }\n .switcher-item > i:first-child { width: 14px; text-align: center; font-size: 12px; color: var(--mj-text-muted); }\n .switcher-item-name { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }\n .switcher-item.current { color: var(--mj-brand-primary); font-weight: var(--mj-font-semibold); }\n .switcher-item.current i { color: var(--mj-brand-primary); }\n .switcher-check { margin-left: auto; font-size: 12px; }\n .switcher-divider { height: 1px; margin: 6px 4px; background: var(--mj-border-default); }\n .switcher-empty { padding: 8px 10px; font-size: var(--mj-text-xs); color: var(--mj-text-muted); }\n @media (max-width: 480px) {\n .switcher-label {\n position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;\n overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;\n }\n }\n @media (prefers-reduced-motion: reduce) { .switcher-menu { animation: none; } }\n `],\n})\nexport class HomeDashboardSwitcherComponent implements OnDestroy {\n /** The pinned dashboards, in pin order. */\n @Input() Dashboards: HomeSwitcherDashboard[] = [];\n /** The dashboard Home shows, or null on the overview. */\n @Input() CurrentId: string | null = null;\n /** 'button': the Pinned header button. 'title': the dashboard title in the dashboard view. */\n @Input() Look: 'button' | 'title' = 'button';\n /** The trigger text: \"Dashboards\" for the button, the dashboard name for the title. */\n @Input() Label = 'Dashboards';\n /** 'right' lines the menu up with the trigger's right edge; 'left' with its left edge. */\n @Input() Align: 'left' | 'right' = 'right';\n /**\n * For the title look: 1 or 2 puts the trigger in an h1 or h2, with no margin or font of its own, and the menu stays\n * outside the heading. Null puts it in no heading. The button look ignores it.\n */\n @Input() HeadingLevel: 1 | 2 | null = null;\n /** Emits the dashboard the user picks, or null for Home. */\n @Output() Pick = new EventEmitter<string | null>();\n /** Emits when the user picks New dashboard. */\n @Output() New = new EventEmitter<void>();\n /** Emits when the user picks Manage pins. */\n @Output() ManagePins = new EventEmitter<void>();\n\n /** True while the menu shows. */\n public IsOpen = false;\n /** The text in the filter box. */\n public Query = '';\n /** The menu's left edge, in viewport pixels. */\n public MenuLeft = 0;\n /** The menu's top edge, in viewport pixels. */\n public MenuTop = 0;\n /** The menu's max height in pixels: the room on its side of the trigger. Null while the menu is measured. */\n public MenuMaxHeight: number | null = null;\n\n @ViewChild('trigger') private trigger?: ElementRef<HTMLButtonElement>;\n @ViewChild('menu') private menu?: ElementRef<HTMLElement>;\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly cdr = inject(ChangeDetectorRef);\n /** The window's width when the menu opened. A resize that keeps it, such as an on-screen keyboard opening, keeps the menu open. */\n private openWidth = 0;\n\n /**\n * Closes the menu on a click outside the switcher. It listens in the capture phase, so a click whose target stops\n * it still counts.\n */\n private readonly onDocumentClick = (event: MouseEvent): void => {\n if (!isInside(this.host.nativeElement, event.target)) {\n this.Close();\n }\n };\n\n /** Closes the menu when the page scrolls under it. A scroll inside the menu, such as its list, keeps it open. */\n private readonly onScroll = (event: Event): void => {\n if (!isInside(this.menu?.nativeElement, event.target)) {\n this.Close();\n }\n };\n\n /** The pinned dashboards whose name matches the filter box. */\n public get FilteredDashboards(): HomeSwitcherDashboard[] {\n return FilterSwitcherDashboards(this.Dashboards, this.Query);\n }\n\n /** True for the dashboard Home shows. */\n public IsCurrent(dashboard: HomeSwitcherDashboard): boolean {\n return UUIDsEqual(dashboard.ID, this.CurrentId);\n }\n\n /** Opens the menu when it is closed, and closes it when it is open. */\n public Toggle(): void {\n if (this.IsOpen) {\n this.Close();\n } else {\n this.Open();\n }\n }\n\n /** Opens the menu under the trigger, inside the viewport, with an empty filter box that has focus. */\n public Open(): void {\n const trigger = this.trigger?.nativeElement;\n if (!trigger) return;\n const anchor = MenuAnchorOf(trigger);\n this.Query = '';\n this.IsOpen = true;\n this.openWidth = window.innerWidth;\n this.placeMenu(anchor, 0);\n // Render the menu with no max height to measure its full height, then place it again with that height\n this.MenuMaxHeight = null;\n this.cdr.detectChanges();\n this.placeMenu(anchor, this.menu?.nativeElement.offsetHeight ?? 0);\n this.cdr.detectChanges();\n const filter = this.host.nativeElement.querySelector<HTMLInputElement>('.switcher-menu mj-page-search input');\n filter?.focus({ preventScroll: true });\n document.addEventListener('click', this.onDocumentClick, true);\n document.addEventListener('scroll', this.onScroll, true);\n }\n\n /** Closes the menu. `returnFocus` puts focus back on the trigger (Escape). */\n public Close(returnFocus = false): void {\n if (!this.IsOpen) return;\n this.IsOpen = false;\n this.stopWatchingPage();\n this.cdr.markForCheck();\n if (returnFocus) {\n this.trigger?.nativeElement.focus();\n }\n }\n\n /** Closes the menu and emits the picked dashboard, or null for Home. */\n public Choose(dashboardId: string | null): void {\n this.Close();\n this.Pick.emit(dashboardId);\n }\n\n /** Closes the menu and emits New. */\n public ChooseNew(): void {\n this.Close();\n this.New.emit();\n }\n\n /** Closes the menu and emits ManagePins. */\n public ChooseManagePins(): void {\n this.Close();\n this.ManagePins.emit();\n }\n\n /**\n * Keys in the menu: Escape closes it and puts focus back on the trigger. ArrowDown and ArrowUp move from the filter\n * box to the first or last row and between the rows; Home and End move between the rows. Other keys do nothing here.\n */\n public OnMenuKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.Close(true);\n return;\n }\n const rows = Array.from(this.menu?.nativeElement.querySelectorAll<HTMLElement>('button.switcher-item') ?? []);\n const next = NextMenuFocusIndex(event.key, rows.findIndex(row => row === document.activeElement), rows.length);\n if (next !== null) {\n event.preventDefault();\n rows[next].focus();\n }\n }\n\n /** Closes the menu when focus moves to an element outside the switcher, as Tab does past the last row. */\n @HostListener('focusout', ['$event'])\n public OnFocusOut(event: FocusEvent): void {\n if (this.IsOpen && event.relatedTarget instanceof Node && !isInside(this.host.nativeElement, event.relatedTarget)) {\n this.Close();\n }\n }\n\n /**\n * Closes the menu when the window's width differs from its width at open. A resize of the height only, such as an\n * on-screen keyboard opening for the filter box, keeps the menu open.\n */\n @HostListener('window:resize')\n public OnWindowResize(): void {\n if (window.innerWidth !== this.openWidth) {\n this.Close();\n }\n }\n\n ngOnDestroy(): void {\n this.stopWatchingPage();\n }\n\n /**\n * Places the menu next to the trigger, lined up by Align, and limits its height to the room on that side. A height\n * of 0 places it below the trigger.\n */\n private placeMenu(anchor: MenuAnchor, height: number): void {\n const viewport = { Width: window.innerWidth, Height: window.innerHeight };\n const place = PlaceMenu(anchor, SWITCHER_MENU_WIDTH, height, this.Align, viewport);\n this.MenuLeft = place.Left;\n this.MenuTop = place.Top;\n this.MenuMaxHeight = place.MaxHeight;\n }\n\n /** Removes the page click and scroll listeners the open menu uses. */\n private stopWatchingPage(): void {\n document.removeEventListener('click', this.onDocumentClick, true);\n document.removeEventListener('scroll', this.onScroll, true);\n }\n}\n"]}
|