@memberjunction/ng-dashboard-viewer 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.
Files changed (99) hide show
  1. package/README.md +165 -17
  2. package/dist/lib/config-dialogs/confirm-dialog.component.d.ts +3 -4
  3. package/dist/lib/config-dialogs/confirm-dialog.component.d.ts.map +1 -1
  4. package/dist/lib/config-dialogs/confirm-dialog.component.js +3 -2
  5. package/dist/lib/config-dialogs/confirm-dialog.component.js.map +1 -1
  6. package/dist/lib/config-panels/artifact-config-panel.component.d.ts.map +1 -1
  7. package/dist/lib/config-panels/artifact-config-panel.component.js +59 -50
  8. package/dist/lib/config-panels/artifact-config-panel.component.js.map +1 -1
  9. package/dist/lib/config-panels/base-config-panel.d.ts +8 -3
  10. package/dist/lib/config-panels/base-config-panel.d.ts.map +1 -1
  11. package/dist/lib/config-panels/base-config-panel.js +10 -3
  12. package/dist/lib/config-panels/base-config-panel.js.map +1 -1
  13. package/dist/lib/config-panels/query-config-panel.component.js +124 -99
  14. package/dist/lib/config-panels/query-config-panel.component.js.map +1 -1
  15. package/dist/lib/config-panels/view-config-panel.component.js +111 -103
  16. package/dist/lib/config-panels/view-config-panel.component.js.map +1 -1
  17. package/dist/lib/config-panels/weburl-config-panel.component.js +89 -80
  18. package/dist/lib/config-panels/weburl-config-panel.component.js.map +1 -1
  19. package/dist/lib/dashboard-browser/dashboard-browser.component.d.ts +79 -28
  20. package/dist/lib/dashboard-browser/dashboard-browser.component.d.ts.map +1 -1
  21. package/dist/lib/dashboard-browser/dashboard-browser.component.js +446 -447
  22. package/dist/lib/dashboard-browser/dashboard-browser.component.js.map +1 -1
  23. package/dist/lib/dashboard-card/dashboard-card.component.d.ts +69 -0
  24. package/dist/lib/dashboard-card/dashboard-card.component.d.ts.map +1 -0
  25. package/dist/lib/dashboard-card/dashboard-card.component.js +281 -0
  26. package/dist/lib/dashboard-card/dashboard-card.component.js.map +1 -0
  27. package/dist/lib/dashboard-card/dashboard-card.helpers.d.ts +18 -0
  28. package/dist/lib/dashboard-card/dashboard-card.helpers.d.ts.map +1 -0
  29. package/dist/lib/dashboard-card/dashboard-card.helpers.js +43 -0
  30. package/dist/lib/dashboard-card/dashboard-card.helpers.js.map +1 -0
  31. package/dist/lib/dashboard-card/layout-preview-cache.d.ts +15 -0
  32. package/dist/lib/dashboard-card/layout-preview-cache.d.ts.map +1 -0
  33. package/dist/lib/dashboard-card/layout-preview-cache.js +22 -0
  34. package/dist/lib/dashboard-card/layout-preview-cache.js.map +1 -0
  35. package/dist/lib/dashboard-viewer/dashboard-viewer.component.d.ts +69 -12
  36. package/dist/lib/dashboard-viewer/dashboard-viewer.component.d.ts.map +1 -1
  37. package/dist/lib/dashboard-viewer/dashboard-viewer.component.js +173 -145
  38. package/dist/lib/dashboard-viewer/dashboard-viewer.component.js.map +1 -1
  39. package/dist/lib/dashboard-viewer.module.d.ts +24 -20
  40. package/dist/lib/dashboard-viewer.module.d.ts.map +1 -1
  41. package/dist/lib/dashboard-viewer.module.js +42 -5
  42. package/dist/lib/dashboard-viewer.module.js.map +1 -1
  43. package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.d.ts +7 -12
  44. package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.d.ts.map +1 -1
  45. package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.js +3 -1
  46. package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.js.map +1 -1
  47. package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.d.ts +54 -0
  48. package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.d.ts.map +1 -0
  49. package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.js +156 -0
  50. package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.js.map +1 -0
  51. package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.d.ts +5 -11
  52. package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.d.ts.map +1 -1
  53. package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.js +3 -1
  54. package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.js.map +1 -1
  55. package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.d.ts +147 -0
  56. package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.d.ts.map +1 -0
  57. package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.js +536 -0
  58. package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.js.map +1 -0
  59. package/dist/lib/layout-preview/dashboard-layout-preview-node.component.d.ts +20 -0
  60. package/dist/lib/layout-preview/dashboard-layout-preview-node.component.d.ts.map +1 -0
  61. package/dist/lib/layout-preview/dashboard-layout-preview-node.component.js +80 -0
  62. package/dist/lib/layout-preview/dashboard-layout-preview-node.component.js.map +1 -0
  63. package/dist/lib/layout-preview/dashboard-layout-preview.component.d.ts +28 -0
  64. package/dist/lib/layout-preview/dashboard-layout-preview.component.d.ts.map +1 -0
  65. package/dist/lib/layout-preview/dashboard-layout-preview.component.js +62 -0
  66. package/dist/lib/layout-preview/dashboard-layout-preview.component.js.map +1 -0
  67. package/dist/lib/layout-preview/dashboard-layout-preview.d.ts +33 -0
  68. package/dist/lib/layout-preview/dashboard-layout-preview.d.ts.map +1 -0
  69. package/dist/lib/layout-preview/dashboard-layout-preview.js +138 -0
  70. package/dist/lib/layout-preview/dashboard-layout-preview.js.map +1 -0
  71. package/dist/lib/models/dashboard-layout-editor.d.ts +78 -0
  72. package/dist/lib/models/dashboard-layout-editor.d.ts.map +1 -0
  73. package/dist/lib/models/dashboard-layout-editor.js +374 -0
  74. package/dist/lib/models/dashboard-layout-editor.js.map +1 -0
  75. package/dist/lib/models/remove-part-confirm.d.ts +8 -0
  76. package/dist/lib/models/remove-part-confirm.d.ts.map +1 -0
  77. package/dist/lib/models/remove-part-confirm.js +23 -0
  78. package/dist/lib/models/remove-part-confirm.js.map +1 -0
  79. package/dist/lib/parts/artifact-part.component.js +2 -2
  80. package/dist/lib/parts/artifact-part.component.js.map +1 -1
  81. package/dist/lib/parts/query-part.component.js +2 -2
  82. package/dist/lib/parts/query-part.component.js.map +1 -1
  83. package/dist/lib/parts/view-part.component.js +2 -2
  84. package/dist/lib/parts/view-part.component.js.map +1 -1
  85. package/dist/lib/parts/weburl-part.component.js +2 -2
  86. package/dist/lib/parts/weburl-part.component.js.map +1 -1
  87. package/dist/lib/services/golden-layout-wrapper.service.d.ts +40 -0
  88. package/dist/lib/services/golden-layout-wrapper.service.d.ts.map +1 -1
  89. package/dist/lib/services/golden-layout-wrapper.service.js +117 -9
  90. package/dist/lib/services/golden-layout-wrapper.service.js.map +1 -1
  91. package/dist/lib/services/stack-part-actions.d.ts +11 -0
  92. package/dist/lib/services/stack-part-actions.d.ts.map +1 -0
  93. package/dist/lib/services/stack-part-actions.js +41 -0
  94. package/dist/lib/services/stack-part-actions.js.map +1 -0
  95. package/dist/public-api.d.ts +9 -0
  96. package/dist/public-api.d.ts.map +1 -1
  97. package/dist/public-api.js +13 -0
  98. package/dist/public-api.js.map +1 -1
  99. package/package.json +13 -13
@@ -1,40 +1,41 @@
1
1
  import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
2
2
  import { Subject } from 'rxjs';
3
- import { UUIDsEqual, NormalizeUUID, HighlightSearchMatches } from '@memberjunction/global';
3
+ import { UUIDsEqual, NormalizeUUID, FilterByUUIDs, HighlightSearchMatches } from '@memberjunction/global';
4
+ import { DashboardCategoryPath, FormatDashboardDate } from '../dashboard-card/dashboard-card.helpers';
4
5
  import * as i0 from "@angular/core";
5
- import * as i1 from "@angular/forms";
6
- import * as i2 from "@memberjunction/ng-shared-generic";
7
- import * as i3 from "@memberjunction/ng-ui-components";
6
+ import * as i1 from "@memberjunction/ng-ui-components";
7
+ import * as i2 from "@angular/forms";
8
+ import * as i3 from "@memberjunction/ng-shared-generic";
8
9
  import * as i4 from "../breadcrumb/dashboard-breadcrumb.component";
9
- import * as i5 from "../config-dialogs/confirm-dialog.component";
10
+ import * as i5 from "../dashboard-card/dashboard-card.component";
10
11
  function DashboardBrowserComponent_Conditional_11_Conditional_0_Template(rf, ctx) { if (rf & 1) {
11
12
  const _r1 = i0.ɵɵgetCurrentView();
12
- i0.ɵɵelementStart(0, "button", 28);
13
+ i0.ɵɵelementStart(0, "button", 27);
13
14
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_11_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.EnterSelectionMode()); });
14
- i0.ɵɵelement(1, "i", 29);
15
+ i0.ɵɵelement(1, "i", 28);
15
16
  i0.ɵɵtext(2, " Select ");
16
17
  i0.ɵɵelementEnd();
17
18
  } }
18
19
  function DashboardBrowserComponent_Conditional_11_Conditional_1_Template(rf, ctx) { if (rf & 1) {
19
20
  const _r3 = i0.ɵɵgetCurrentView();
20
- i0.ɵɵelementStart(0, "div", 27)(1, "span", 30);
21
+ i0.ɵɵelementStart(0, "div", 26)(1, "span", 29);
21
22
  i0.ɵɵtext(2);
22
23
  i0.ɵɵelementEnd();
23
- i0.ɵɵelementStart(3, "button", 31);
24
+ i0.ɵɵelementStart(3, "button", 30);
24
25
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_11_Conditional_1_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectAll()); });
25
- i0.ɵɵelement(4, "i", 29);
26
+ i0.ɵɵelement(4, "i", 28);
26
27
  i0.ɵɵelementEnd();
27
- i0.ɵɵelementStart(5, "button", 32);
28
+ i0.ɵɵelementStart(5, "button", 31);
28
29
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_11_Conditional_1_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnMoveSelected()); });
29
- i0.ɵɵelement(6, "i", 33);
30
+ i0.ɵɵelement(6, "i", 32);
30
31
  i0.ɵɵelementEnd();
31
- i0.ɵɵelementStart(7, "button", 34);
32
+ i0.ɵɵelementStart(7, "button", 33);
32
33
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_11_Conditional_1_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteSelected()); });
33
- i0.ɵɵelement(8, "i", 35);
34
+ i0.ɵɵelement(8, "i", 34);
34
35
  i0.ɵɵelementEnd();
35
- i0.ɵɵelementStart(9, "button", 36);
36
+ i0.ɵɵelementStart(9, "button", 35);
36
37
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_11_Conditional_1_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ExitSelectionMode()); });
37
- i0.ɵɵelement(10, "i", 37);
38
+ i0.ɵɵelement(10, "i", 36);
38
39
  i0.ɵɵelementEnd()();
39
40
  } if (rf & 2) {
40
41
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -46,8 +47,8 @@ function DashboardBrowserComponent_Conditional_11_Conditional_1_Template(rf, ctx
46
47
  i0.ɵɵproperty("disabled", !ctx_r1.CanDeleteAnySelected);
47
48
  } }
48
49
  function DashboardBrowserComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
49
- i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_11_Conditional_0_Template, 3, 0, "button", 26);
50
- i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_11_Conditional_1_Template, 11, 3, "div", 27);
50
+ i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_11_Conditional_0_Template, 3, 0, "button", 25);
51
+ i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_11_Conditional_1_Template, 11, 3, "div", 26);
51
52
  } if (rf & 2) {
52
53
  const ctx_r1 = i0.ɵɵnextContext();
53
54
  i0.ɵɵconditional(!ctx_r1.IsSelectionMode && ctx_r1.FilteredDashboards.length > 0 ? 0 : -1);
@@ -56,26 +57,26 @@ function DashboardBrowserComponent_Conditional_11_Template(rf, ctx) { if (rf & 1
56
57
  } }
57
58
  function DashboardBrowserComponent_Conditional_12_Conditional_5_Template(rf, ctx) { if (rf & 1) {
58
59
  const _r5 = i0.ɵɵgetCurrentView();
59
- i0.ɵɵelementStart(0, "div", 41)(1, "button", 42);
60
+ i0.ɵɵelementStart(0, "div", 40)(1, "button", 41);
60
61
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_12_Conditional_5_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCreateDashboard()); });
61
- i0.ɵɵelement(2, "i", 43);
62
+ i0.ɵɵelement(2, "i", 42);
62
63
  i0.ɵɵtext(3, " Dashboard ");
63
64
  i0.ɵɵelementEnd();
64
- i0.ɵɵelementStart(4, "button", 42);
65
+ i0.ɵɵelementStart(4, "button", 41);
65
66
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_12_Conditional_5_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenCreateCategoryDialog()); });
66
- i0.ɵɵelement(5, "i", 44);
67
+ i0.ɵɵelement(5, "i", 43);
67
68
  i0.ɵɵtext(6, " Category ");
68
69
  i0.ɵɵelementEnd()();
69
70
  } }
70
71
  function DashboardBrowserComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
71
72
  const _r4 = i0.ɵɵgetCurrentView();
72
- i0.ɵɵelementStart(0, "div", 10)(1, "button", 38);
73
+ i0.ɵɵelementStart(0, "div", 10)(1, "button", 37);
73
74
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_12_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.ToggleNewMenu(); return i0.ɵɵresetView($event.stopPropagation()); });
74
- i0.ɵɵelement(2, "i", 39);
75
+ i0.ɵɵelement(2, "i", 38);
75
76
  i0.ɵɵtext(3, " New ");
76
- i0.ɵɵelement(4, "i", 40);
77
+ i0.ɵɵelement(4, "i", 39);
77
78
  i0.ɵɵelementEnd();
78
- i0.ɵɵconditionalCreate(5, DashboardBrowserComponent_Conditional_12_Conditional_5_Template, 7, 0, "div", 41);
79
+ i0.ɵɵconditionalCreate(5, DashboardBrowserComponent_Conditional_12_Conditional_5_Template, 7, 0, "div", 40);
79
80
  i0.ɵɵelementEnd();
80
81
  } if (rf & 2) {
81
82
  const ctx_r1 = i0.ɵɵnextContext();
@@ -84,32 +85,32 @@ function DashboardBrowserComponent_Conditional_12_Template(rf, ctx) { if (rf & 1
84
85
  } }
85
86
  function DashboardBrowserComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
86
87
  const _r6 = i0.ɵɵgetCurrentView();
87
- i0.ɵɵelementStart(0, "div", 45);
88
+ i0.ɵɵelementStart(0, "div", 44);
88
89
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_13_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseNewMenu()); });
89
90
  i0.ɵɵelementEnd();
90
91
  } }
91
92
  function DashboardBrowserComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
92
93
  const _r7 = i0.ɵɵgetCurrentView();
93
- i0.ɵɵelementStart(0, "button", 46);
94
+ i0.ɵɵelementStart(0, "button", 45);
94
95
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_18_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ClearSearch()); });
95
- i0.ɵɵelement(1, "i", 37);
96
+ i0.ɵɵelement(1, "i", 36);
96
97
  i0.ɵɵelementEnd();
97
98
  } }
98
99
  function DashboardBrowserComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
99
100
  const _r8 = i0.ɵɵgetCurrentView();
100
- i0.ɵɵelementStart(0, "button", 47);
101
+ i0.ɵɵelementStart(0, "button", 46);
101
102
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_19_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ClearSearch()); });
102
- i0.ɵɵelement(1, "i", 48);
103
+ i0.ɵɵelement(1, "i", 47);
103
104
  i0.ɵɵtext(2, " Clear Search ");
104
105
  i0.ɵɵelementEnd();
105
106
  } }
106
107
  function DashboardBrowserComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
107
108
  i0.ɵɵelementStart(0, "div", 18);
108
- i0.ɵɵelement(1, "mj-loading", 49);
109
+ i0.ɵɵelement(1, "mj-loading", 48);
109
110
  i0.ɵɵelementEnd();
110
111
  } }
111
112
  function DashboardBrowserComponent_Conditional_21_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
112
- i0.ɵɵelement(0, "p", 60);
113
+ i0.ɵɵelement(0, "p", 59);
113
114
  } if (rf & 2) {
114
115
  const category_r10 = i0.ɵɵnextContext().$implicit;
115
116
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -117,20 +118,20 @@ function DashboardBrowserComponent_Conditional_21_For_2_Conditional_9_Template(r
117
118
  } }
118
119
  function DashboardBrowserComponent_Conditional_21_For_2_Template(rf, ctx) { if (rf & 1) {
119
120
  const _r9 = i0.ɵɵgetCurrentView();
120
- i0.ɵɵelementStart(0, "div", 52);
121
+ i0.ɵɵelementStart(0, "div", 51);
121
122
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_21_For_2_Template_div_click_0_listener() { const category_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.NavigateToCategory(category_r10.ID)); })("dblclick", function DashboardBrowserComponent_Conditional_21_For_2_Template_div_dblclick_0_listener($event) { return $event.stopPropagation(); })("dragover", function DashboardBrowserComponent_Conditional_21_For_2_Template_div_dragover_0_listener($event) { const category_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragOverChildCategory(category_r10.ID, $event)); })("dragleave", function DashboardBrowserComponent_Conditional_21_For_2_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragLeaveChildCategory()); })("drop", function DashboardBrowserComponent_Conditional_21_For_2_Template_div_drop_0_listener($event) { const category_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDropOnChildCategory(category_r10.ID, $event)); });
122
- i0.ɵɵelementStart(1, "div", 53)(2, "div", 54);
123
- i0.ɵɵelement(3, "i", 55);
123
+ i0.ɵɵelementStart(1, "div", 52)(2, "div", 53);
124
+ i0.ɵɵelement(3, "i", 54);
124
125
  i0.ɵɵelementEnd();
125
- i0.ɵɵelementStart(4, "div", 56)(5, "button", 57);
126
+ i0.ɵɵelementStart(4, "div", 55)(5, "button", 56);
126
127
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_21_For_2_Template_button_click_5_listener($event) { const category_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteCategory(category_r10, $event)); });
127
- i0.ɵɵelement(6, "i", 35);
128
+ i0.ɵɵelement(6, "i", 34);
128
129
  i0.ɵɵelementEnd()()();
129
- i0.ɵɵelementStart(7, "div", 58);
130
- i0.ɵɵelement(8, "h3", 59);
131
- i0.ɵɵconditionalCreate(9, DashboardBrowserComponent_Conditional_21_For_2_Conditional_9_Template, 1, 1, "p", 60);
132
- i0.ɵɵelementStart(10, "div", 61)(11, "span", 62);
133
- i0.ɵɵelement(12, "i", 63);
130
+ i0.ɵɵelementStart(7, "div", 57);
131
+ i0.ɵɵelement(8, "h3", 58);
132
+ i0.ɵɵconditionalCreate(9, DashboardBrowserComponent_Conditional_21_For_2_Conditional_9_Template, 1, 1, "p", 59);
133
+ i0.ɵɵelementStart(10, "div", 60)(11, "span", 61);
134
+ i0.ɵɵelement(12, "i", 62);
134
135
  i0.ɵɵtext(13, " Category ");
135
136
  i0.ɵɵelementEnd()()()();
136
137
  } if (rf & 2) {
@@ -142,90 +143,21 @@ function DashboardBrowserComponent_Conditional_21_For_2_Template(rf, ctx) { if (
142
143
  i0.ɵɵadvance();
143
144
  i0.ɵɵconditional(category_r10.Description ? 9 : -1);
144
145
  } }
145
- function DashboardBrowserComponent_Conditional_21_For_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
146
- const _r13 = i0.ɵɵgetCurrentView();
147
- i0.ɵɵelementStart(0, "div", 73);
148
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_21_For_4_Conditional_1_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r13); const dashboard_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); ctx_r1.ToggleSelection(dashboard_r12.ID); return i0.ɵɵresetView($event.stopPropagation()); });
149
- i0.ɵɵelementStart(1, "input", 74);
150
- i0.ɵɵlistener("change", function DashboardBrowserComponent_Conditional_21_For_4_Conditional_1_Template_input_change_1_listener($event) { return $event.stopPropagation(); });
151
- i0.ɵɵelementEnd()();
152
- } if (rf & 2) {
153
- const dashboard_r12 = i0.ɵɵnextContext().$implicit;
154
- const ctx_r1 = i0.ɵɵnextContext(2);
155
- i0.ɵɵadvance();
156
- i0.ɵɵproperty("checked", ctx_r1.IsSelected(dashboard_r12.ID));
157
- } }
158
- function DashboardBrowserComponent_Conditional_21_For_4_Conditional_6_Template(rf, ctx) { if (rf & 1) {
159
- const _r14 = i0.ɵɵgetCurrentView();
160
- i0.ɵɵelementStart(0, "button", 75);
161
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_21_For_4_Conditional_6_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r14); const dashboard_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEditDashboard(dashboard_r12, $event)); });
162
- i0.ɵɵelement(1, "i", 76);
163
- i0.ɵɵelementEnd();
164
- } }
165
- function DashboardBrowserComponent_Conditional_21_For_4_Conditional_7_Template(rf, ctx) { if (rf & 1) {
166
- const _r15 = i0.ɵɵgetCurrentView();
167
- i0.ɵɵelementStart(0, "button", 77);
168
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_21_For_4_Conditional_7_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r15); const dashboard_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteDashboard(dashboard_r12, $event)); });
169
- i0.ɵɵelement(1, "i", 35);
170
- i0.ɵɵelementEnd();
171
- } }
172
- function DashboardBrowserComponent_Conditional_21_For_4_Conditional_11_Template(rf, ctx) { if (rf & 1) {
173
- i0.ɵɵelementStart(0, "span", 71);
174
- i0.ɵɵelement(1, "i", 78);
175
- i0.ɵɵelementEnd();
176
- } }
177
- function DashboardBrowserComponent_Conditional_21_For_4_Conditional_12_Template(rf, ctx) { if (rf & 1) {
178
- i0.ɵɵelement(0, "p", 60);
179
- } if (rf & 2) {
180
- const dashboard_r12 = i0.ɵɵnextContext().$implicit;
181
- const ctx_r1 = i0.ɵɵnextContext(2);
182
- i0.ɵɵproperty("innerHTML", ctx_r1.HighlightMatch(dashboard_r12.Description), i0.ɵɵsanitizeHtml);
183
- } }
184
146
  function DashboardBrowserComponent_Conditional_21_For_4_Template(rf, ctx) { if (rf & 1) {
185
147
  const _r11 = i0.ɵɵgetCurrentView();
186
- i0.ɵɵelementStart(0, "div", 64);
187
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_21_For_4_Template_div_click_0_listener($event) { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardClick(dashboard_r12, $event)); })("dblclick", function DashboardBrowserComponent_Conditional_21_For_4_Template_div_dblclick_0_listener($event) { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardDoubleClick(dashboard_r12, $event)); })("dragstart", function DashboardBrowserComponent_Conditional_21_For_4_Template_div_dragstart_0_listener($event) { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart(dashboard_r12, $event)); })("dragend", function DashboardBrowserComponent_Conditional_21_For_4_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); });
188
- i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_21_For_4_Conditional_1_Template, 2, 1, "div", 65);
189
- i0.ɵɵelementStart(2, "div", 53)(3, "div", 66);
190
- i0.ɵɵelement(4, "i", 43);
148
+ i0.ɵɵelementStart(0, "mj-dashboard-card", 63);
149
+ i0.ɵɵlistener("CardClick", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_CardClick_0_listener($event) { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardClick(dashboard_r12, $event.MouseEvent)); })("CardDoubleClick", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_CardDoubleClick_0_listener($event) { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardDoubleClick(dashboard_r12, $event.MouseEvent)); })("ToggleFavorite", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_ToggleFavorite_0_listener() { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnToggleFavorite(dashboard_r12)); })("SelectionToggle", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_SelectionToggle_0_listener() { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleSelection(dashboard_r12.ID)); })("Edit", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_Edit_0_listener() { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEditDashboard(dashboard_r12)); })("Delete", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_Delete_0_listener() { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteDashboard(dashboard_r12)); })("dragstart", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_dragstart_0_listener($event) { const dashboard_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart(dashboard_r12, $event)); })("dragend", function DashboardBrowserComponent_Conditional_21_For_4_Template_mj_dashboard_card_dragend_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); });
191
150
  i0.ɵɵelementEnd();
192
- i0.ɵɵelementStart(5, "div", 56);
193
- i0.ɵɵconditionalCreate(6, DashboardBrowserComponent_Conditional_21_For_4_Conditional_6_Template, 2, 0, "button", 67);
194
- i0.ɵɵconditionalCreate(7, DashboardBrowserComponent_Conditional_21_For_4_Conditional_7_Template, 2, 0, "button", 68);
195
- i0.ɵɵelementEnd()();
196
- i0.ɵɵelementStart(8, "div", 58)(9, "h3", 69);
197
- i0.ɵɵelement(10, "span", 70);
198
- i0.ɵɵconditionalCreate(11, DashboardBrowserComponent_Conditional_21_For_4_Conditional_11_Template, 2, 0, "span", 71);
199
- i0.ɵɵelementEnd();
200
- i0.ɵɵconditionalCreate(12, DashboardBrowserComponent_Conditional_21_For_4_Conditional_12_Template, 1, 1, "p", 60);
201
- i0.ɵɵelementStart(13, "div", 61)(14, "span", 62);
202
- i0.ɵɵelement(15, "i", 72);
203
- i0.ɵɵtext(16);
204
- i0.ɵɵelementEnd()()()();
205
151
  } if (rf & 2) {
206
152
  const dashboard_r12 = ctx.$implicit;
207
153
  const ctx_r1 = i0.ɵɵnextContext(2);
208
- i0.ɵɵclassProp("selected", ctx_r1.IsSelected(dashboard_r12.ID))("dragging", ctx_r1.DraggingId === dashboard_r12.ID);
209
- i0.ɵɵproperty("draggable", ctx_r1.AllowDragDrop);
210
- i0.ɵɵadvance();
211
- i0.ɵɵconditional(ctx_r1.IsSelectionMode ? 1 : -1);
212
- i0.ɵɵadvance(5);
213
- i0.ɵɵconditional(ctx_r1.CanEdit(dashboard_r12.ID) ? 6 : -1);
214
- i0.ɵɵadvance();
215
- i0.ɵɵconditional(ctx_r1.CanDelete(dashboard_r12.ID) ? 7 : -1);
216
- i0.ɵɵadvance(3);
217
- i0.ɵɵproperty("innerHTML", ctx_r1.HighlightMatch(dashboard_r12.Name), i0.ɵɵsanitizeHtml);
218
- i0.ɵɵadvance();
219
- i0.ɵɵconditional(ctx_r1.IsShared(dashboard_r12.ID) ? 11 : -1);
220
- i0.ɵɵadvance();
221
- i0.ɵɵconditional(dashboard_r12.Description ? 12 : -1);
222
- i0.ɵɵadvance(4);
223
- i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatDate(dashboard_r12.__mj_UpdatedAt), " ");
154
+ i0.ɵɵclassProp("dragging", ctx_r1.DraggingId === dashboard_r12.ID);
155
+ i0.ɵɵproperty("draggable", ctx_r1.AllowDragDrop)("Dashboard", dashboard_r12)("IsFavorite", ctx_r1.IsFavorite(dashboard_r12.ID))("ShowFavorite", ctx_r1.ShowFavorites)("IsShared", ctx_r1.IsShared(dashboard_r12.ID))("OwnerLabel", ctx_r1.OwnerLabel(dashboard_r12))("CategoryPath", ctx_r1.CardCategoryPath(dashboard_r12))("HighlightQuery", ctx_r1.SearchText)("Selectable", ctx_r1.IsSelectionMode)("Selected", ctx_r1.IsSelected(dashboard_r12.ID))("CanEdit", ctx_r1.CanEdit(dashboard_r12.ID))("CanDelete", ctx_r1.CanDelete(dashboard_r12.ID));
224
156
  } }
225
157
  function DashboardBrowserComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
226
158
  i0.ɵɵelementStart(0, "div", 19);
227
- i0.ɵɵrepeaterCreate(1, DashboardBrowserComponent_Conditional_21_For_2_Template, 14, 4, "div", 50, i0.ɵɵcomponentInstance().TrackByCategory, true);
228
- i0.ɵɵrepeaterCreate(3, DashboardBrowserComponent_Conditional_21_For_4_Template, 17, 12, "div", 51, i0.ɵɵcomponentInstance().TrackByDashboard, true);
159
+ i0.ɵɵrepeaterCreate(1, DashboardBrowserComponent_Conditional_21_For_2_Template, 14, 4, "div", 49, i0.ɵɵcomponentInstance().TrackByCategory, true);
160
+ i0.ɵɵrepeaterCreate(3, DashboardBrowserComponent_Conditional_21_For_4_Template, 1, 14, "mj-dashboard-card", 50, i0.ɵɵcomponentInstance().TrackByDashboard, true);
229
161
  i0.ɵɵelementEnd();
230
162
  } if (rf & 2) {
231
163
  const ctx_r1 = i0.ɵɵnextContext();
@@ -235,9 +167,9 @@ function DashboardBrowserComponent_Conditional_21_Template(rf, ctx) { if (rf & 1
235
167
  i0.ɵɵrepeater(ctx_r1.FilteredDashboards);
236
168
  } }
237
169
  function DashboardBrowserComponent_Conditional_22_Conditional_2_Template(rf, ctx) { if (rf & 1) {
238
- const _r16 = i0.ɵɵgetCurrentView();
239
- i0.ɵɵelementStart(0, "div", 80)(1, "input", 87);
240
- i0.ɵɵlistener("change", function DashboardBrowserComponent_Conditional_22_Conditional_2_Template_input_change_1_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectedCount === ctx_r1.FilteredDashboards.length ? ctx_r1.ClearSelection() : ctx_r1.SelectAll()); });
170
+ const _r13 = i0.ɵɵgetCurrentView();
171
+ i0.ɵɵelementStart(0, "div", 65)(1, "input", 72);
172
+ i0.ɵɵlistener("change", function DashboardBrowserComponent_Conditional_22_Conditional_2_Template_input_change_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectedCount === ctx_r1.FilteredDashboards.length ? ctx_r1.ClearSelection() : ctx_r1.SelectAll()); });
241
173
  i0.ɵɵelementEnd()();
242
174
  } if (rf & 2) {
243
175
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -245,122 +177,122 @@ function DashboardBrowserComponent_Conditional_22_Conditional_2_Template(rf, ctx
245
177
  i0.ɵɵproperty("checked", ctx_r1.SelectedCount === ctx_r1.FilteredDashboards.length && ctx_r1.FilteredDashboards.length > 0)("indeterminate", ctx_r1.SelectedCount > 0 && ctx_r1.SelectedCount < ctx_r1.FilteredDashboards.length);
246
178
  } }
247
179
  function DashboardBrowserComponent_Conditional_22_For_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
248
- i0.ɵɵelement(0, "div", 80);
180
+ i0.ɵɵelement(0, "div", 65);
249
181
  } }
250
182
  function DashboardBrowserComponent_Conditional_22_For_12_Template(rf, ctx) { if (rf & 1) {
251
- const _r17 = i0.ɵɵgetCurrentView();
252
- i0.ɵɵelementStart(0, "div", 88);
253
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_click_0_listener() { const category_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.NavigateToCategory(category_r18.ID)); })("dragover", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_dragover_0_listener($event) { const category_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragOverChildCategory(category_r18.ID, $event)); })("dragleave", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragLeaveChildCategory()); })("drop", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_drop_0_listener($event) { const category_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDropOnChildCategory(category_r18.ID, $event)); });
254
- i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_22_For_12_Conditional_1_Template, 1, 0, "div", 80);
255
- i0.ɵɵelementStart(2, "div", 81);
256
- i0.ɵɵelement(3, "i", 89)(4, "span", 90);
183
+ const _r14 = i0.ɵɵgetCurrentView();
184
+ i0.ɵɵelementStart(0, "div", 73);
185
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_click_0_listener() { const category_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.NavigateToCategory(category_r15.ID)); })("dragover", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_dragover_0_listener($event) { const category_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragOverChildCategory(category_r15.ID, $event)); })("dragleave", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragLeaveChildCategory()); })("drop", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_drop_0_listener($event) { const category_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDropOnChildCategory(category_r15.ID, $event)); });
186
+ i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_22_For_12_Conditional_1_Template, 1, 0, "div", 65);
187
+ i0.ɵɵelementStart(2, "div", 66);
188
+ i0.ɵɵelement(3, "i", 74)(4, "span", 75);
257
189
  i0.ɵɵelementEnd();
258
- i0.ɵɵelementStart(5, "div", 82);
190
+ i0.ɵɵelementStart(5, "div", 67);
259
191
  i0.ɵɵtext(6, " Category ");
260
192
  i0.ɵɵelementEnd();
261
- i0.ɵɵelement(7, "div", 83);
262
- i0.ɵɵelementStart(8, "div", 91);
193
+ i0.ɵɵelement(7, "div", 68);
194
+ i0.ɵɵelementStart(8, "div", 76);
263
195
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_12_Template_div_click_8_listener($event) { return $event.stopPropagation(); });
264
- i0.ɵɵelementStart(9, "button", 57);
265
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_12_Template_button_click_9_listener($event) { const category_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteCategory(category_r18, $event)); });
266
- i0.ɵɵelement(10, "i", 35);
196
+ i0.ɵɵelementStart(9, "button", 56);
197
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_12_Template_button_click_9_listener($event) { const category_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteCategory(category_r15, $event)); });
198
+ i0.ɵɵelement(10, "i", 34);
267
199
  i0.ɵɵelementEnd()()();
268
200
  } if (rf & 2) {
269
- const category_r18 = ctx.$implicit;
201
+ const category_r15 = ctx.$implicit;
270
202
  const ctx_r1 = i0.ɵɵnextContext(2);
271
- i0.ɵɵclassProp("drop-target", ctx_r1.DragOverChildCategoryId === category_r18.ID);
203
+ i0.ɵɵclassProp("drop-target", ctx_r1.DragOverChildCategoryId === category_r15.ID);
272
204
  i0.ɵɵadvance();
273
205
  i0.ɵɵconditional(ctx_r1.IsSelectionMode ? 1 : -1);
274
206
  i0.ɵɵadvance(3);
275
- i0.ɵɵproperty("innerHTML", ctx_r1.HighlightMatch(category_r18.Name), i0.ɵɵsanitizeHtml);
207
+ i0.ɵɵproperty("innerHTML", ctx_r1.HighlightMatch(category_r15.Name), i0.ɵɵsanitizeHtml);
276
208
  } }
277
209
  function DashboardBrowserComponent_Conditional_22_For_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
278
- const _r21 = i0.ɵɵgetCurrentView();
279
- i0.ɵɵelementStart(0, "div", 94);
210
+ const _r18 = i0.ɵɵgetCurrentView();
211
+ i0.ɵɵelementStart(0, "div", 82);
280
212
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Conditional_1_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
281
- i0.ɵɵelementStart(1, "input", 74);
282
- i0.ɵɵlistener("change", function DashboardBrowserComponent_Conditional_22_For_14_Conditional_1_Template_input_change_1_listener() { i0.ɵɵrestoreView(_r21); const dashboard_r20 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleSelection(dashboard_r20.ID)); });
213
+ i0.ɵɵelementStart(1, "input", 83);
214
+ i0.ɵɵlistener("change", function DashboardBrowserComponent_Conditional_22_For_14_Conditional_1_Template_input_change_1_listener() { i0.ɵɵrestoreView(_r18); const dashboard_r17 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleSelection(dashboard_r17.ID)); });
283
215
  i0.ɵɵelementEnd()();
284
216
  } if (rf & 2) {
285
- const dashboard_r20 = i0.ɵɵnextContext().$implicit;
217
+ const dashboard_r17 = i0.ɵɵnextContext().$implicit;
286
218
  const ctx_r1 = i0.ɵɵnextContext(2);
287
219
  i0.ɵɵadvance();
288
- i0.ɵɵproperty("checked", ctx_r1.IsSelected(dashboard_r20.ID));
220
+ i0.ɵɵproperty("checked", ctx_r1.IsSelected(dashboard_r17.ID));
289
221
  } }
290
222
  function DashboardBrowserComponent_Conditional_22_For_14_Conditional_5_Template(rf, ctx) { if (rf & 1) {
291
- i0.ɵɵelementStart(0, "span", 71);
292
- i0.ɵɵelement(1, "i", 78);
223
+ i0.ɵɵelementStart(0, "span", 79);
224
+ i0.ɵɵelement(1, "i", 84);
293
225
  i0.ɵɵelementEnd();
294
226
  } }
295
227
  function DashboardBrowserComponent_Conditional_22_For_14_Conditional_11_Template(rf, ctx) { if (rf & 1) {
296
- const _r22 = i0.ɵɵgetCurrentView();
297
- i0.ɵɵelementStart(0, "button", 75);
298
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Conditional_11_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r22); const dashboard_r20 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEditDashboard(dashboard_r20, $event)); });
299
- i0.ɵɵelement(1, "i", 76);
228
+ const _r19 = i0.ɵɵgetCurrentView();
229
+ i0.ɵɵelementStart(0, "button", 85);
230
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Conditional_11_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r19); const dashboard_r17 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnEditDashboard(dashboard_r17, $event)); });
231
+ i0.ɵɵelement(1, "i", 86);
300
232
  i0.ɵɵelementEnd();
301
233
  } }
302
234
  function DashboardBrowserComponent_Conditional_22_For_14_Conditional_12_Template(rf, ctx) { if (rf & 1) {
303
- const _r23 = i0.ɵɵgetCurrentView();
304
- i0.ɵɵelementStart(0, "button", 77);
305
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Conditional_12_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r23); const dashboard_r20 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteDashboard(dashboard_r20, $event)); });
306
- i0.ɵɵelement(1, "i", 35);
235
+ const _r20 = i0.ɵɵgetCurrentView();
236
+ i0.ɵɵelementStart(0, "button", 87);
237
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Conditional_12_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r20); const dashboard_r17 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDeleteDashboard(dashboard_r17, $event)); });
238
+ i0.ɵɵelement(1, "i", 34);
307
239
  i0.ɵɵelementEnd();
308
240
  } }
309
241
  function DashboardBrowserComponent_Conditional_22_For_14_Template(rf, ctx) { if (rf & 1) {
310
- const _r19 = i0.ɵɵgetCurrentView();
311
- i0.ɵɵelementStart(0, "div", 92);
312
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_click_0_listener($event) { const dashboard_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardClick(dashboard_r20, $event)); })("dblclick", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_dblclick_0_listener($event) { const dashboard_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardDoubleClick(dashboard_r20, $event)); })("dragstart", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_dragstart_0_listener($event) { const dashboard_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart(dashboard_r20, $event)); })("dragend", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); });
313
- i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_22_For_14_Conditional_1_Template, 2, 1, "div", 80);
314
- i0.ɵɵelementStart(2, "div", 81);
315
- i0.ɵɵelement(3, "i", 93)(4, "span", 90);
316
- i0.ɵɵconditionalCreate(5, DashboardBrowserComponent_Conditional_22_For_14_Conditional_5_Template, 2, 0, "span", 71);
242
+ const _r16 = i0.ɵɵgetCurrentView();
243
+ i0.ɵɵelementStart(0, "div", 77);
244
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_click_0_listener($event) { const dashboard_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardClick(dashboard_r17, $event)); })("dblclick", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_dblclick_0_listener($event) { const dashboard_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDashboardDoubleClick(dashboard_r17, $event)); })("dragstart", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_dragstart_0_listener($event) { const dashboard_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragStart(dashboard_r17, $event)); })("dragend", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); });
245
+ i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_22_For_14_Conditional_1_Template, 2, 1, "div", 65);
246
+ i0.ɵɵelementStart(2, "div", 66);
247
+ i0.ɵɵelement(3, "i", 78)(4, "span", 75);
248
+ i0.ɵɵconditionalCreate(5, DashboardBrowserComponent_Conditional_22_For_14_Conditional_5_Template, 2, 0, "span", 79);
317
249
  i0.ɵɵelementEnd();
318
- i0.ɵɵelementStart(6, "div", 82);
250
+ i0.ɵɵelementStart(6, "div", 67);
319
251
  i0.ɵɵtext(7, " Dashboard ");
320
252
  i0.ɵɵelementEnd();
321
- i0.ɵɵelementStart(8, "div", 83);
253
+ i0.ɵɵelementStart(8, "div", 68);
322
254
  i0.ɵɵtext(9);
323
255
  i0.ɵɵelementEnd();
324
- i0.ɵɵelementStart(10, "div", 91);
256
+ i0.ɵɵelementStart(10, "div", 76);
325
257
  i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_22_For_14_Template_div_click_10_listener($event) { return $event.stopPropagation(); });
326
- i0.ɵɵconditionalCreate(11, DashboardBrowserComponent_Conditional_22_For_14_Conditional_11_Template, 2, 0, "button", 67);
327
- i0.ɵɵconditionalCreate(12, DashboardBrowserComponent_Conditional_22_For_14_Conditional_12_Template, 2, 0, "button", 68);
258
+ i0.ɵɵconditionalCreate(11, DashboardBrowserComponent_Conditional_22_For_14_Conditional_11_Template, 2, 0, "button", 80);
259
+ i0.ɵɵconditionalCreate(12, DashboardBrowserComponent_Conditional_22_For_14_Conditional_12_Template, 2, 0, "button", 81);
328
260
  i0.ɵɵelementEnd()();
329
261
  } if (rf & 2) {
330
- const dashboard_r20 = ctx.$implicit;
262
+ const dashboard_r17 = ctx.$implicit;
331
263
  const ctx_r1 = i0.ɵɵnextContext(2);
332
- i0.ɵɵclassProp("selected", ctx_r1.IsSelected(dashboard_r20.ID))("dragging", ctx_r1.DraggingId === dashboard_r20.ID);
264
+ i0.ɵɵclassProp("selected", ctx_r1.IsSelected(dashboard_r17.ID))("dragging", ctx_r1.DraggingId === dashboard_r17.ID);
333
265
  i0.ɵɵproperty("draggable", ctx_r1.AllowDragDrop);
334
266
  i0.ɵɵadvance();
335
267
  i0.ɵɵconditional(ctx_r1.IsSelectionMode ? 1 : -1);
336
268
  i0.ɵɵadvance(3);
337
- i0.ɵɵproperty("innerHTML", ctx_r1.HighlightMatch(dashboard_r20.Name), i0.ɵɵsanitizeHtml);
269
+ i0.ɵɵproperty("innerHTML", ctx_r1.HighlightMatch(dashboard_r17.Name), i0.ɵɵsanitizeHtml);
338
270
  i0.ɵɵadvance();
339
- i0.ɵɵconditional(ctx_r1.IsShared(dashboard_r20.ID) ? 5 : -1);
271
+ i0.ɵɵconditional(ctx_r1.IsShared(dashboard_r17.ID) ? 5 : -1);
340
272
  i0.ɵɵadvance(4);
341
- i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatDate(dashboard_r20.__mj_UpdatedAt), " ");
273
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.FormatDate(dashboard_r17.__mj_UpdatedAt), " ");
342
274
  i0.ɵɵadvance(2);
343
- i0.ɵɵconditional(ctx_r1.CanEdit(dashboard_r20.ID) ? 11 : -1);
275
+ i0.ɵɵconditional(ctx_r1.CanEdit(dashboard_r17.ID) ? 11 : -1);
344
276
  i0.ɵɵadvance();
345
- i0.ɵɵconditional(ctx_r1.CanDelete(dashboard_r20.ID) ? 12 : -1);
277
+ i0.ɵɵconditional(ctx_r1.CanDelete(dashboard_r17.ID) ? 12 : -1);
346
278
  } }
347
279
  function DashboardBrowserComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
348
- i0.ɵɵelementStart(0, "div", 20)(1, "div", 79);
349
- i0.ɵɵconditionalCreate(2, DashboardBrowserComponent_Conditional_22_Conditional_2_Template, 2, 2, "div", 80);
350
- i0.ɵɵelementStart(3, "div", 81);
280
+ i0.ɵɵelementStart(0, "div", 20)(1, "div", 64);
281
+ i0.ɵɵconditionalCreate(2, DashboardBrowserComponent_Conditional_22_Conditional_2_Template, 2, 2, "div", 65);
282
+ i0.ɵɵelementStart(3, "div", 66);
351
283
  i0.ɵɵtext(4, "Name");
352
284
  i0.ɵɵelementEnd();
353
- i0.ɵɵelementStart(5, "div", 82);
285
+ i0.ɵɵelementStart(5, "div", 67);
354
286
  i0.ɵɵtext(6, "Type");
355
287
  i0.ɵɵelementEnd();
356
- i0.ɵɵelementStart(7, "div", 83);
288
+ i0.ɵɵelementStart(7, "div", 68);
357
289
  i0.ɵɵtext(8, "Modified");
358
290
  i0.ɵɵelementEnd();
359
- i0.ɵɵelementStart(9, "div", 84);
291
+ i0.ɵɵelementStart(9, "div", 69);
360
292
  i0.ɵɵtext(10, "Actions");
361
293
  i0.ɵɵelementEnd()();
362
- i0.ɵɵrepeaterCreate(11, DashboardBrowserComponent_Conditional_22_For_12_Template, 11, 4, "div", 85, i0.ɵɵcomponentInstance().TrackByCategory, true);
363
- i0.ɵɵrepeaterCreate(13, DashboardBrowserComponent_Conditional_22_For_14_Template, 13, 11, "div", 86, i0.ɵɵcomponentInstance().TrackByDashboard, true);
294
+ i0.ɵɵrepeaterCreate(11, DashboardBrowserComponent_Conditional_22_For_12_Template, 11, 4, "div", 70, i0.ɵɵcomponentInstance().TrackByCategory, true);
295
+ i0.ɵɵrepeaterCreate(13, DashboardBrowserComponent_Conditional_22_For_14_Template, 13, 11, "div", 71, i0.ɵɵcomponentInstance().TrackByDashboard, true);
364
296
  i0.ɵɵelementEnd();
365
297
  } if (rf & 2) {
366
298
  const ctx_r1 = i0.ɵɵnextContext();
@@ -372,21 +304,21 @@ function DashboardBrowserComponent_Conditional_22_Template(rf, ctx) { if (rf & 1
372
304
  i0.ɵɵrepeater(ctx_r1.FilteredDashboards);
373
305
  } }
374
306
  function DashboardBrowserComponent_Conditional_23_Conditional_0_Template(rf, ctx) { if (rf & 1) {
375
- const _r24 = i0.ɵɵgetCurrentView();
376
- i0.ɵɵelementStart(0, "mj-empty-state", 99);
377
- i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_0_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCreateDashboard()); });
378
- i0.ɵɵelementStart(1, "div", 100)(2, "div", 101);
379
- i0.ɵɵelement(3, "i", 102);
307
+ const _r21 = i0.ɵɵgetCurrentView();
308
+ i0.ɵɵelementStart(0, "mj-empty-state", 90);
309
+ i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_0_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCreateDashboard()); });
310
+ i0.ɵɵelementStart(1, "div", 91)(2, "div", 92);
311
+ i0.ɵɵelement(3, "i", 93);
380
312
  i0.ɵɵelementStart(4, "span");
381
313
  i0.ɵɵtext(5, "Customizable layouts");
382
314
  i0.ɵɵelementEnd()();
383
- i0.ɵɵelementStart(6, "div", 101);
384
- i0.ɵɵelement(7, "i", 103);
315
+ i0.ɵɵelementStart(6, "div", 92);
316
+ i0.ɵɵelement(7, "i", 94);
385
317
  i0.ɵɵelementStart(8, "span");
386
318
  i0.ɵɵtext(9, "Connect to your data");
387
319
  i0.ɵɵelementEnd()();
388
- i0.ɵɵelementStart(10, "div", 101);
389
- i0.ɵɵelement(11, "i", 78);
320
+ i0.ɵɵelementStart(10, "div", 92);
321
+ i0.ɵɵelement(11, "i", 84);
390
322
  i0.ɵɵelementStart(12, "span");
391
323
  i0.ɵɵtext(13, "Share with your team");
392
324
  i0.ɵɵelementEnd()()()();
@@ -394,73 +326,91 @@ function DashboardBrowserComponent_Conditional_23_Conditional_0_Template(rf, ctx
394
326
  const ctx_r1 = i0.ɵɵnextContext(2);
395
327
  i0.ɵɵproperty("ActionText", ctx_r1.ShowCreateButton ? "Create Your First Dashboard" : "");
396
328
  } }
329
+ function DashboardBrowserComponent_Conditional_23_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
330
+ i0.ɵɵelement(0, "mj-empty-state", 95);
331
+ } if (rf & 2) {
332
+ const ctx_r1 = i0.ɵɵnextContext(3);
333
+ i0.ɵɵproperty("Icon", ctx_r1.FlatEmptyIcon)("Title", ctx_r1.FlatEmptyTitle)("Message", ctx_r1.FlatEmptyMessage);
334
+ } }
397
335
  function DashboardBrowserComponent_Conditional_23_Conditional_1_Template(rf, ctx) { if (rf & 1) {
398
- const _r25 = i0.ɵɵgetCurrentView();
399
- i0.ɵɵelementStart(0, "mj-empty-state", 104);
400
- i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_1_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCreateDashboard()); });
401
- i0.ɵɵelementEnd();
336
+ i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_23_Conditional_1_Conditional_0_Template, 1, 3, "mj-empty-state", 95);
402
337
  } if (rf & 2) {
403
338
  const ctx_r1 = i0.ɵɵnextContext(2);
339
+ i0.ɵɵconditional(!ctx_r1.SearchText && !ctx_r1.FlatEmptyWelcome ? 0 : -1);
340
+ } }
341
+ function DashboardBrowserComponent_Conditional_23_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
342
+ const _r22 = i0.ɵɵgetCurrentView();
343
+ i0.ɵɵelementStart(0, "mj-empty-state", 98);
344
+ i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_2_Conditional_0_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnCreateDashboard()); });
345
+ i0.ɵɵelementEnd();
346
+ } if (rf & 2) {
347
+ const ctx_r1 = i0.ɵɵnextContext(3);
404
348
  i0.ɵɵproperty("ActionText", ctx_r1.ShowCreateButton ? "Create Dashboard" : "");
405
349
  } }
406
- function DashboardBrowserComponent_Conditional_23_Conditional_2_Template(rf, ctx) { if (rf & 1) {
407
- const _r26 = i0.ɵɵgetCurrentView();
408
- i0.ɵɵelementStart(0, "mj-empty-state", 105);
409
- i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_2_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCreateDashboard()); });
350
+ function DashboardBrowserComponent_Conditional_23_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
351
+ const _r23 = i0.ɵɵgetCurrentView();
352
+ i0.ɵɵelementStart(0, "mj-empty-state", 99);
353
+ i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_2_Conditional_1_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnCreateDashboard()); });
410
354
  i0.ɵɵelementEnd();
411
355
  } if (rf & 2) {
412
- const ctx_r1 = i0.ɵɵnextContext(2);
356
+ const ctx_r1 = i0.ɵɵnextContext(3);
413
357
  i0.ɵɵproperty("ActionText", ctx_r1.ShowCreateButton ? "Create Dashboard" : "");
414
358
  } }
359
+ function DashboardBrowserComponent_Conditional_23_Conditional_2_Template(rf, ctx) { if (rf & 1) {
360
+ i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_23_Conditional_2_Conditional_0_Template, 1, 1, "mj-empty-state", 96);
361
+ i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_23_Conditional_2_Conditional_1_Template, 1, 1, "mj-empty-state", 97);
362
+ } if (rf & 2) {
363
+ const ctx_r1 = i0.ɵɵnextContext(2);
364
+ i0.ɵɵconditional(!ctx_r1.IsAtRoot && !ctx_r1.SearchText ? 0 : -1);
365
+ i0.ɵɵadvance();
366
+ i0.ɵɵconditional(ctx_r1.IsAtRoot && ctx_r1.Dashboards.length > 0 && !ctx_r1.SearchText ? 1 : -1);
367
+ } }
415
368
  function DashboardBrowserComponent_Conditional_23_Conditional_3_Template(rf, ctx) { if (rf & 1) {
416
- const _r27 = i0.ɵɵgetCurrentView();
417
- i0.ɵɵelementStart(0, "mj-empty-state", 106);
418
- i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r27); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ClearSearch()); });
369
+ const _r24 = i0.ɵɵgetCurrentView();
370
+ i0.ɵɵelementStart(0, "mj-empty-state", 100);
371
+ i0.ɵɵlistener("Action", function DashboardBrowserComponent_Conditional_23_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ClearSearch()); });
419
372
  i0.ɵɵelementEnd();
420
373
  } if (rf & 2) {
421
374
  const ctx_r1 = i0.ɵɵnextContext(2);
422
375
  i0.ɵɵproperty("Message", ctx_r1.NoResultsMessage);
423
376
  } }
424
377
  function DashboardBrowserComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
425
- i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_23_Conditional_0_Template, 14, 1, "mj-empty-state", 95);
426
- i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_23_Conditional_1_Template, 1, 1, "mj-empty-state", 96);
427
- i0.ɵɵconditionalCreate(2, DashboardBrowserComponent_Conditional_23_Conditional_2_Template, 1, 1, "mj-empty-state", 97);
428
- i0.ɵɵconditionalCreate(3, DashboardBrowserComponent_Conditional_23_Conditional_3_Template, 1, 1, "mj-empty-state", 98);
378
+ i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_23_Conditional_0_Template, 14, 1, "mj-empty-state", 88);
379
+ i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_23_Conditional_1_Template, 1, 1)(2, DashboardBrowserComponent_Conditional_23_Conditional_2_Template, 2, 2);
380
+ i0.ɵɵconditionalCreate(3, DashboardBrowserComponent_Conditional_23_Conditional_3_Template, 1, 1, "mj-empty-state", 89);
429
381
  } if (rf & 2) {
430
382
  const ctx_r1 = i0.ɵɵnextContext();
431
- i0.ɵɵconditional(ctx_r1.IsAtRoot && ctx_r1.Dashboards.length === 0 ? 0 : -1);
432
- i0.ɵɵadvance();
433
- i0.ɵɵconditional(!ctx_r1.IsAtRoot && !ctx_r1.SearchText ? 1 : -1);
434
- i0.ɵɵadvance();
435
- i0.ɵɵconditional(ctx_r1.IsAtRoot && ctx_r1.Dashboards.length > 0 && !ctx_r1.SearchText ? 2 : -1);
383
+ i0.ɵɵconditional(ctx_r1.ShowWelcome ? 0 : -1);
436
384
  i0.ɵɵadvance();
385
+ i0.ɵɵconditional(ctx_r1.FlatMode ? 1 : 2);
386
+ i0.ɵɵadvance(2);
437
387
  i0.ɵɵconditional(ctx_r1.SearchText ? 3 : -1);
438
388
  } }
439
389
  function DashboardBrowserComponent_Conditional_24_For_8_Template(rf, ctx) { if (rf & 1) {
440
- const _r29 = i0.ɵɵgetCurrentView();
441
- i0.ɵɵelementStart(0, "div", 109);
442
- i0.ɵɵlistener("dragover", function DashboardBrowserComponent_Conditional_24_For_8_Template_div_dragover_0_listener($event) { const cat_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragOverCategory(cat_r30.ID, $event)); })("dragleave", function DashboardBrowserComponent_Conditional_24_For_8_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r29); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragLeaveCategory()); })("drop", function DashboardBrowserComponent_Conditional_24_For_8_Template_div_drop_0_listener($event) { const cat_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDropOnCategory(cat_r30.ID, $event)); });
443
- i0.ɵɵelement(1, "i", 55);
390
+ const _r26 = i0.ɵɵgetCurrentView();
391
+ i0.ɵɵelementStart(0, "div", 103);
392
+ i0.ɵɵlistener("dragover", function DashboardBrowserComponent_Conditional_24_For_8_Template_div_dragover_0_listener($event) { const cat_r27 = i0.ɵɵrestoreView(_r26).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragOverCategory(cat_r27.ID, $event)); })("dragleave", function DashboardBrowserComponent_Conditional_24_For_8_Template_div_dragleave_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDragLeaveCategory()); })("drop", function DashboardBrowserComponent_Conditional_24_For_8_Template_div_drop_0_listener($event) { const cat_r27 = i0.ɵɵrestoreView(_r26).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnDropOnCategory(cat_r27.ID, $event)); });
393
+ i0.ɵɵelement(1, "i", 54);
444
394
  i0.ɵɵtext(2);
445
395
  i0.ɵɵelementEnd();
446
396
  } if (rf & 2) {
447
- const cat_r30 = ctx.$implicit;
397
+ const cat_r27 = ctx.$implicit;
448
398
  const ctx_r1 = i0.ɵɵnextContext(2);
449
- i0.ɵɵclassProp("active", ctx_r1.DropTargetCategoryId === cat_r30.ID);
399
+ i0.ɵɵclassProp("active", ctx_r1.DropTargetCategoryId === cat_r27.ID);
450
400
  i0.ɵɵadvance(2);
451
- i0.ɵɵtextInterpolate1(" ", cat_r30.Name, " ");
401
+ i0.ɵɵtextInterpolate1(" ", cat_r27.Name, " ");
452
402
  } }
453
403
  function DashboardBrowserComponent_Conditional_24_Template(rf, ctx) { if (rf & 1) {
454
- const _r28 = i0.ɵɵgetCurrentView();
455
- i0.ɵɵelementStart(0, "div", 21)(1, "div", 107);
404
+ const _r25 = i0.ɵɵgetCurrentView();
405
+ i0.ɵɵelementStart(0, "div", 21)(1, "div", 101);
456
406
  i0.ɵɵtext(2, "Drop to move to category:");
457
407
  i0.ɵɵelementEnd();
458
- i0.ɵɵelementStart(3, "div", 108)(4, "div", 109);
459
- i0.ɵɵlistener("dragover", function DashboardBrowserComponent_Conditional_24_Template_div_dragover_4_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOverCategory(null, $event)); })("dragleave", function DashboardBrowserComponent_Conditional_24_Template_div_dragleave_4_listener() { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeaveCategory()); })("drop", function DashboardBrowserComponent_Conditional_24_Template_div_drop_4_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDropOnCategory(null, $event)); });
460
- i0.ɵɵelement(5, "i", 33);
408
+ i0.ɵɵelementStart(3, "div", 102)(4, "div", 103);
409
+ i0.ɵɵlistener("dragover", function DashboardBrowserComponent_Conditional_24_Template_div_dragover_4_listener($event) { i0.ɵɵrestoreView(_r25); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragOverCategory(null, $event)); })("dragleave", function DashboardBrowserComponent_Conditional_24_Template_div_dragleave_4_listener() { i0.ɵɵrestoreView(_r25); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDragLeaveCategory()); })("drop", function DashboardBrowserComponent_Conditional_24_Template_div_drop_4_listener($event) { i0.ɵɵrestoreView(_r25); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnDropOnCategory(null, $event)); });
410
+ i0.ɵɵelement(5, "i", 32);
461
411
  i0.ɵɵtext(6, " Uncategorized ");
462
412
  i0.ɵɵelementEnd();
463
- i0.ɵɵrepeaterCreate(7, DashboardBrowserComponent_Conditional_24_For_8_Template, 3, 3, "div", 110, i0.ɵɵcomponentInstance().TrackByCategory, true);
413
+ i0.ɵɵrepeaterCreate(7, DashboardBrowserComponent_Conditional_24_For_8_Template, 3, 3, "div", 104, i0.ɵɵcomponentInstance().TrackByCategory, true);
464
414
  i0.ɵɵelementEnd()();
465
415
  } if (rf & 2) {
466
416
  const ctx_r1 = i0.ɵɵnextContext();
@@ -469,43 +419,43 @@ function DashboardBrowserComponent_Conditional_24_Template(rf, ctx) { if (rf & 1
469
419
  i0.ɵɵadvance(3);
470
420
  i0.ɵɵrepeater(ctx_r1.Categories);
471
421
  } }
472
- function DashboardBrowserComponent_Conditional_26_For_15_Template(rf, ctx) { if (rf & 1) {
473
- const _r32 = i0.ɵɵgetCurrentView();
474
- i0.ɵɵelementStart(0, "div", 117);
475
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_For_15_Template_div_click_0_listener() { const cat_r33 = i0.ɵɵrestoreView(_r32).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ConfirmMove(cat_r33.ID)); });
476
- i0.ɵɵelement(1, "i", 55);
422
+ function DashboardBrowserComponent_Conditional_25_For_15_Template(rf, ctx) { if (rf & 1) {
423
+ const _r29 = i0.ɵɵgetCurrentView();
424
+ i0.ɵɵelementStart(0, "div", 111);
425
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_25_For_15_Template_div_click_0_listener() { const cat_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ConfirmMove(cat_r30.ID)); });
426
+ i0.ɵɵelement(1, "i", 54);
477
427
  i0.ɵɵtext(2);
478
428
  i0.ɵɵelementEnd();
479
429
  } if (rf & 2) {
480
- const cat_r33 = ctx.$implicit;
430
+ const cat_r30 = ctx.$implicit;
481
431
  i0.ɵɵadvance(2);
482
- i0.ɵɵtextInterpolate1(" ", cat_r33.Name, " ");
432
+ i0.ɵɵtextInterpolate1(" ", cat_r30.Name, " ");
483
433
  } }
484
- function DashboardBrowserComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
485
- const _r31 = i0.ɵɵgetCurrentView();
486
- i0.ɵɵelementStart(0, "div", 111);
487
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMoveDialog()); });
488
- i0.ɵɵelementStart(1, "div", 112);
489
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
490
- i0.ɵɵelementStart(2, "div", 113)(3, "h3");
434
+ function DashboardBrowserComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
435
+ const _r28 = i0.ɵɵgetCurrentView();
436
+ i0.ɵɵelementStart(0, "div", 105);
437
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_25_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMoveDialog()); });
438
+ i0.ɵɵelementStart(1, "div", 106);
439
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_25_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
440
+ i0.ɵɵelementStart(2, "div", 107)(3, "h3");
491
441
  i0.ɵɵtext(4, "Move to Category");
492
442
  i0.ɵɵelementEnd();
493
- i0.ɵɵelementStart(5, "button", 114);
494
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMoveDialog()); });
495
- i0.ɵɵelement(6, "i", 37);
443
+ i0.ɵɵelementStart(5, "button", 108);
444
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_25_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMoveDialog()); });
445
+ i0.ɵɵelement(6, "i", 36);
496
446
  i0.ɵɵelementEnd()();
497
- i0.ɵɵelementStart(7, "div", 115)(8, "p");
447
+ i0.ɵɵelementStart(7, "div", 109)(8, "p");
498
448
  i0.ɵɵtext(9);
499
449
  i0.ɵɵelementEnd();
500
- i0.ɵɵelementStart(10, "div", 116)(11, "div", 117);
501
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_div_click_11_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmMove(null)); });
502
- i0.ɵɵelement(12, "i", 33);
450
+ i0.ɵɵelementStart(10, "div", 110)(11, "div", 111);
451
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_25_Template_div_click_11_listener() { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmMove(null)); });
452
+ i0.ɵɵelement(12, "i", 32);
503
453
  i0.ɵɵtext(13, " Uncategorized ");
504
454
  i0.ɵɵelementEnd();
505
- i0.ɵɵrepeaterCreate(14, DashboardBrowserComponent_Conditional_26_For_15_Template, 3, 1, "div", 118, i0.ɵɵcomponentInstance().TrackByCategory, true);
455
+ i0.ɵɵrepeaterCreate(14, DashboardBrowserComponent_Conditional_25_For_15_Template, 3, 1, "div", 112, i0.ɵɵcomponentInstance().TrackByCategory, true);
506
456
  i0.ɵɵelementEnd()();
507
- i0.ɵɵelementStart(16, "div", 119)(17, "button", 120);
508
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMoveDialog()); });
457
+ i0.ɵɵelementStart(16, "div", 113)(17, "button", 114);
458
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_25_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseMoveDialog()); });
509
459
  i0.ɵɵtext(18, "Cancel");
510
460
  i0.ɵɵelementEnd()()()();
511
461
  } if (rf & 2) {
@@ -515,40 +465,40 @@ function DashboardBrowserComponent_Conditional_26_Template(rf, ctx) { if (rf & 1
515
465
  i0.ɵɵadvance(5);
516
466
  i0.ɵɵrepeater(ctx_r1.Categories);
517
467
  } }
518
- function DashboardBrowserComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
519
- const _r34 = i0.ɵɵgetCurrentView();
520
- i0.ɵɵelementStart(0, "div", 121);
521
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseCreateCategoryDialog()); });
522
- i0.ɵɵelementStart(1, "div", 122);
523
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
524
- i0.ɵɵelementStart(2, "div", 113)(3, "h3");
525
- i0.ɵɵelement(4, "i", 44);
468
+ function DashboardBrowserComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
469
+ const _r31 = i0.ɵɵgetCurrentView();
470
+ i0.ɵɵelementStart(0, "div", 115);
471
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseCreateCategoryDialog()); });
472
+ i0.ɵɵelementStart(1, "div", 116);
473
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
474
+ i0.ɵɵelementStart(2, "div", 107)(3, "h3");
475
+ i0.ɵɵelement(4, "i", 43);
526
476
  i0.ɵɵtext(5, " Create Category ");
527
477
  i0.ɵɵelementEnd();
528
- i0.ɵɵelementStart(6, "button", 114);
529
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseCreateCategoryDialog()); });
530
- i0.ɵɵelement(7, "i", 37);
478
+ i0.ɵɵelementStart(6, "button", 108);
479
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseCreateCategoryDialog()); });
480
+ i0.ɵɵelement(7, "i", 36);
531
481
  i0.ɵɵelementEnd()();
532
- i0.ɵɵelementStart(8, "div", 115)(9, "div", 123)(10, "label", 124);
482
+ i0.ɵɵelementStart(8, "div", 109)(9, "div", 117)(10, "label", 118);
533
483
  i0.ɵɵtext(11, "Name *");
534
484
  i0.ɵɵelementEnd();
535
- i0.ɵɵelementStart(12, "input", 125);
536
- i0.ɵɵtwoWayListener("ngModelChange", function DashboardBrowserComponent_Conditional_27_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.NewCategoryName, $event) || (ctx_r1.NewCategoryName = $event); return i0.ɵɵresetView($event); });
537
- i0.ɵɵlistener("keyup.enter", function DashboardBrowserComponent_Conditional_27_Template_input_keyup_enter_12_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmCreateCategory()); });
485
+ i0.ɵɵelementStart(12, "input", 119);
486
+ i0.ɵɵtwoWayListener("ngModelChange", function DashboardBrowserComponent_Conditional_26_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.NewCategoryName, $event) || (ctx_r1.NewCategoryName = $event); return i0.ɵɵresetView($event); });
487
+ i0.ɵɵlistener("keyup.enter", function DashboardBrowserComponent_Conditional_26_Template_input_keyup_enter_12_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmCreateCategory()); });
538
488
  i0.ɵɵelementEnd()();
539
- i0.ɵɵelementStart(13, "div", 123)(14, "label", 126);
489
+ i0.ɵɵelementStart(13, "div", 117)(14, "label", 120);
540
490
  i0.ɵɵtext(15, "Description");
541
491
  i0.ɵɵelementEnd();
542
- i0.ɵɵelementStart(16, "textarea", 127);
543
- i0.ɵɵtwoWayListener("ngModelChange", function DashboardBrowserComponent_Conditional_27_Template_textarea_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.NewCategoryDescription, $event) || (ctx_r1.NewCategoryDescription = $event); return i0.ɵɵresetView($event); });
492
+ i0.ɵɵelementStart(16, "textarea", 121);
493
+ i0.ɵɵtwoWayListener("ngModelChange", function DashboardBrowserComponent_Conditional_26_Template_textarea_ngModelChange_16_listener($event) { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.NewCategoryDescription, $event) || (ctx_r1.NewCategoryDescription = $event); return i0.ɵɵresetView($event); });
544
494
  i0.ɵɵelementEnd()()();
545
- i0.ɵɵelementStart(17, "div", 119)(18, "button", 128);
546
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmCreateCategory()); });
547
- i0.ɵɵelement(19, "i", 39);
495
+ i0.ɵɵelementStart(17, "div", 113)(18, "button", 122);
496
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmCreateCategory()); });
497
+ i0.ɵɵelement(19, "i", 38);
548
498
  i0.ɵɵtext(20, " Create ");
549
499
  i0.ɵɵelementEnd();
550
- i0.ɵɵelementStart(21, "button", 120);
551
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r34); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseCreateCategoryDialog()); });
500
+ i0.ɵɵelementStart(21, "button", 114);
501
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_26_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseCreateCategoryDialog()); });
552
502
  i0.ɵɵtext(22, "Cancel");
553
503
  i0.ɵɵelementEnd()()()();
554
504
  } if (rf & 2) {
@@ -560,68 +510,68 @@ function DashboardBrowserComponent_Conditional_27_Template(rf, ctx) { if (rf & 1
560
510
  i0.ɵɵadvance(2);
561
511
  i0.ɵɵproperty("disabled", !ctx_r1.NewCategoryName.trim());
562
512
  } }
563
- function DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_0_Template(rf, ctx) { if (rf & 1) {
564
- i0.ɵɵelementStart(0, "p", 139);
565
- i0.ɵɵelement(1, "i", 141);
513
+ function DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_0_Template(rf, ctx) { if (rf & 1) {
514
+ i0.ɵɵelementStart(0, "p", 133);
515
+ i0.ɵɵelement(1, "i", 135);
566
516
  i0.ɵɵtext(2, " This category contains: ");
567
517
  i0.ɵɵelementEnd();
568
518
  } }
569
- function DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
519
+ function DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
570
520
  i0.ɵɵelementStart(0, "li");
571
- i0.ɵɵelement(1, "i", 43);
521
+ i0.ɵɵelement(1, "i", 42);
572
522
  i0.ɵɵtext(2);
573
523
  i0.ɵɵelementEnd();
574
524
  } if (rf & 2) {
575
- const counts_r37 = i0.ɵɵnextContext(2);
525
+ const counts_r34 = i0.ɵɵnextContext(2);
576
526
  i0.ɵɵadvance(2);
577
- i0.ɵɵtextInterpolate2(" ", counts_r37.dashboards, " dashboard", counts_r37.dashboards !== 1 ? "s" : "", " ");
527
+ i0.ɵɵtextInterpolate2(" ", counts_r34.dashboards, " dashboard", counts_r34.dashboards !== 1 ? "s" : "", " ");
578
528
  } }
579
- function DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
529
+ function DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
580
530
  i0.ɵɵelementStart(0, "li");
581
- i0.ɵɵelement(1, "i", 55);
531
+ i0.ɵɵelement(1, "i", 54);
582
532
  i0.ɵɵtext(2);
583
533
  i0.ɵɵelementEnd();
584
534
  } if (rf & 2) {
585
- const counts_r37 = i0.ɵɵnextContext(2);
535
+ const counts_r34 = i0.ɵɵnextContext(2);
586
536
  i0.ɵɵadvance(2);
587
- i0.ɵɵtextInterpolate2(" ", counts_r37.categories, " sub-categor", counts_r37.categories !== 1 ? "ies" : "y", " ");
537
+ i0.ɵɵtextInterpolate2(" ", counts_r34.categories, " sub-categor", counts_r34.categories !== 1 ? "ies" : "y", " ");
588
538
  } }
589
- function DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
590
- i0.ɵɵelementStart(0, "ul", 140);
591
- i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_1_Conditional_1_Template, 3, 2, "li");
592
- i0.ɵɵconditionalCreate(2, DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_1_Conditional_2_Template, 3, 2, "li");
539
+ function DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
540
+ i0.ɵɵelementStart(0, "ul", 134);
541
+ i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_1_Conditional_1_Template, 3, 2, "li");
542
+ i0.ɵɵconditionalCreate(2, DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_1_Conditional_2_Template, 3, 2, "li");
593
543
  i0.ɵɵelementEnd();
594
544
  } if (rf & 2) {
595
- const counts_r37 = i0.ɵɵnextContext();
545
+ const counts_r34 = i0.ɵɵnextContext();
596
546
  i0.ɵɵadvance();
597
- i0.ɵɵconditional(counts_r37.dashboards > 0 ? 1 : -1);
547
+ i0.ɵɵconditional(counts_r34.dashboards > 0 ? 1 : -1);
598
548
  i0.ɵɵadvance();
599
- i0.ɵɵconditional(counts_r37.categories > 0 ? 2 : -1);
549
+ i0.ɵɵconditional(counts_r34.categories > 0 ? 2 : -1);
600
550
  } }
601
- function DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Template(rf, ctx) { if (rf & 1) {
602
- i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_0_Template, 3, 0, "p", 139);
603
- i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Conditional_1_Template, 3, 2, "ul", 140);
551
+ function DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Template(rf, ctx) { if (rf & 1) {
552
+ i0.ɵɵconditionalCreate(0, DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_0_Template, 3, 0, "p", 133);
553
+ i0.ɵɵconditionalCreate(1, DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Conditional_1_Template, 3, 2, "ul", 134);
604
554
  } if (rf & 2) {
605
- const counts_r37 = ctx;
606
- i0.ɵɵconditional(counts_r37.dashboards > 0 || counts_r37.categories > 0 ? 0 : -1);
555
+ const counts_r34 = ctx;
556
+ i0.ɵɵconditional(counts_r34.dashboards > 0 || counts_r34.categories > 0 ? 0 : -1);
607
557
  i0.ɵɵadvance();
608
- i0.ɵɵconditional(counts_r37.dashboards > 0 || counts_r37.categories > 0 ? 1 : -1);
558
+ i0.ɵɵconditional(counts_r34.dashboards > 0 || counts_r34.categories > 0 ? 1 : -1);
609
559
  } }
610
- function DashboardBrowserComponent_Conditional_28_Conditional_8_Template(rf, ctx) { if (rf & 1) {
611
- const _r36 = i0.ɵɵgetCurrentView();
612
- i0.ɵɵelementStart(0, "div", 115)(1, "div", 134)(2, "p");
560
+ function DashboardBrowserComponent_Conditional_27_Conditional_8_Template(rf, ctx) { if (rf & 1) {
561
+ const _r33 = i0.ɵɵgetCurrentView();
562
+ i0.ɵɵelementStart(0, "div", 109)(1, "div", 128)(2, "p");
613
563
  i0.ɵɵtext(3, " You are about to delete the category ");
614
564
  i0.ɵɵelementStart(4, "strong");
615
565
  i0.ɵɵtext(5);
616
566
  i0.ɵɵelementEnd();
617
567
  i0.ɵɵtext(6, ". ");
618
568
  i0.ɵɵelementEnd();
619
- i0.ɵɵconditionalCreate(7, DashboardBrowserComponent_Conditional_28_Conditional_8_Conditional_7_Template, 2, 2);
569
+ i0.ɵɵconditionalCreate(7, DashboardBrowserComponent_Conditional_27_Conditional_8_Conditional_7_Template, 2, 2);
620
570
  i0.ɵɵelementEnd();
621
- i0.ɵɵelementStart(8, "div", 135)(9, "label", 136)(10, "input", 137);
622
- i0.ɵɵtwoWayListener("ngModelChange", function DashboardBrowserComponent_Conditional_28_Conditional_8_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r36); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.DeleteCategoryIncludeContents, $event) || (ctx_r1.DeleteCategoryIncludeContents = $event); return i0.ɵɵresetView($event); });
571
+ i0.ɵɵelementStart(8, "div", 129)(9, "label", 130)(10, "input", 131);
572
+ i0.ɵɵtwoWayListener("ngModelChange", function DashboardBrowserComponent_Conditional_27_Conditional_8_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.DeleteCategoryIncludeContents, $event) || (ctx_r1.DeleteCategoryIncludeContents = $event); return i0.ɵɵresetView($event); });
623
573
  i0.ɵɵelementEnd();
624
- i0.ɵɵelementStart(11, "span", 138);
574
+ i0.ɵɵelementStart(11, "span", 132);
625
575
  i0.ɵɵtext(12, " I understand this will permanently delete this category and all its contents. This action cannot be undone. ");
626
576
  i0.ɵɵelementEnd()()()();
627
577
  } if (rf & 2) {
@@ -634,28 +584,28 @@ function DashboardBrowserComponent_Conditional_28_Conditional_8_Template(rf, ctx
634
584
  i0.ɵɵadvance(3);
635
585
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.DeleteCategoryIncludeContents);
636
586
  } }
637
- function DashboardBrowserComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
638
- const _r35 = i0.ɵɵgetCurrentView();
639
- i0.ɵɵelementStart(0, "div", 129);
640
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_28_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseDeleteCategoryConfirm()); });
641
- i0.ɵɵelementStart(1, "div", 130);
642
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_28_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
643
- i0.ɵɵelementStart(2, "div", 131)(3, "h3");
644
- i0.ɵɵelement(4, "i", 132);
587
+ function DashboardBrowserComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
588
+ const _r32 = i0.ɵɵgetCurrentView();
589
+ i0.ɵɵelementStart(0, "div", 123);
590
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseDeleteCategoryConfirm()); });
591
+ i0.ɵɵelementStart(1, "div", 124);
592
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
593
+ i0.ɵɵelementStart(2, "div", 125)(3, "h3");
594
+ i0.ɵɵelement(4, "i", 126);
645
595
  i0.ɵɵtext(5, " Delete Category ");
646
596
  i0.ɵɵelementEnd();
647
- i0.ɵɵelementStart(6, "button", 114);
648
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_28_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseDeleteCategoryConfirm()); });
649
- i0.ɵɵelement(7, "i", 37);
597
+ i0.ɵɵelementStart(6, "button", 108);
598
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseDeleteCategoryConfirm()); });
599
+ i0.ɵɵelement(7, "i", 36);
650
600
  i0.ɵɵelementEnd()();
651
- i0.ɵɵconditionalCreate(8, DashboardBrowserComponent_Conditional_28_Conditional_8_Template, 13, 3, "div", 115);
652
- i0.ɵɵelementStart(9, "div", 119)(10, "button", 133);
653
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_28_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmDeleteCategory()); });
654
- i0.ɵɵelement(11, "i", 35);
601
+ i0.ɵɵconditionalCreate(8, DashboardBrowserComponent_Conditional_27_Conditional_8_Template, 13, 3, "div", 109);
602
+ i0.ɵɵelementStart(9, "div", 113)(10, "button", 127);
603
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ConfirmDeleteCategory()); });
604
+ i0.ɵɵelement(11, "i", 34);
655
605
  i0.ɵɵtext(12, " Delete Category ");
656
606
  i0.ɵɵelementEnd();
657
- i0.ɵɵelementStart(13, "button", 120);
658
- i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_28_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r35); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseDeleteCategoryConfirm()); });
607
+ i0.ɵɵelementStart(13, "button", 114);
608
+ i0.ɵɵlistener("click", function DashboardBrowserComponent_Conditional_27_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r32); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseDeleteCategoryConfirm()); });
659
609
  i0.ɵɵtext(14, "Cancel");
660
610
  i0.ɵɵelementEnd()()()();
661
611
  } if (rf & 2) {
@@ -665,6 +615,15 @@ function DashboardBrowserComponent_Conditional_28_Template(rf, ctx) { if (rf & 1
665
615
  i0.ɵɵadvance(2);
666
616
  i0.ɵɵproperty("disabled", !ctx_r1.DeleteCategoryIncludeContents);
667
617
  } }
618
+ /** The texts of the delete confirm: names one dashboard, counts several. */
619
+ function deleteDashboardsConfirm(dashboards) {
620
+ const count = dashboards.length;
621
+ return {
622
+ title: count === 1 ? 'Delete dashboard' : `Delete ${count} dashboards`,
623
+ message: count === 1 ? `Delete "${dashboards[0].Name}"?` : `Delete ${count} dashboards?`,
624
+ detail: 'This action cannot be undone.',
625
+ };
626
+ }
668
627
  /**
669
628
  * Generic dashboard browser component.
670
629
  * Displays dashboards in card or list view with multi-select, filtering, and bulk actions.
@@ -674,6 +633,7 @@ function DashboardBrowserComponent_Conditional_28_Template(rf, ctx) { if (rf & 1
674
633
  */
675
634
  export class DashboardBrowserComponent {
676
635
  cdr;
636
+ confirmService;
677
637
  // ========================================
678
638
  // Inputs
679
639
  // ========================================
@@ -708,6 +668,23 @@ export class DashboardBrowserComponent {
708
668
  get SelectedCategoryId() {
709
669
  return this._selectedCategoryId;
710
670
  }
671
+ _flatMode = false;
672
+ /**
673
+ * When true, shows every dashboard in `Dashboards` in one flat list and ignores
674
+ * `SelectedCategoryId`: no folder scoping, no folder cards, the breadcrumb stays at the
675
+ * root, and new dashboards and categories are created at the root. Search and the
676
+ * Config-type rule still apply. When false (the default), shows the sub-folders and
677
+ * dashboards of the selected folder.
678
+ */
679
+ set FlatMode(value) {
680
+ if (value !== this._flatMode) {
681
+ this._flatMode = value;
682
+ this.applyFilters();
683
+ }
684
+ }
685
+ get FlatMode() {
686
+ return this._flatMode;
687
+ }
711
688
  /** Initial view mode */
712
689
  _viewMode = 'cards';
713
690
  set ViewMode(value) {
@@ -759,6 +736,39 @@ export class DashboardBrowserComponent {
759
736
  get EffectiveCategoryMap() {
760
737
  return this._effectiveCategoryMap;
761
738
  }
739
+ /** IDs of the user's favorite dashboards. Their cards show a filled star. */
740
+ _favoriteIds = new Set();
741
+ set FavoriteIds(value) {
742
+ this._favoriteIds = new Set((value ?? []).map(id => NormalizeUUID(id)));
743
+ this.cdr.markForCheck();
744
+ }
745
+ get FavoriteIds() {
746
+ return [...this._favoriteIds];
747
+ }
748
+ /** Whether cards show the favorite star. Turn it on when the host handles DashboardFavoriteToggle. */
749
+ ShowFavorites = false;
750
+ /**
751
+ * Map of dashboard ID to the owner text its card shows ("You", or a name). A dashboard whose ID
752
+ * is not in the map shows no owner. IDs match in any letter case.
753
+ */
754
+ _ownerLabels = new Map();
755
+ ownerLabelById = new Map();
756
+ set OwnerLabels(value) {
757
+ this._ownerLabels = value ?? new Map();
758
+ this.ownerLabelById = new Map([...this._ownerLabels].map(([id, label]) => [NormalizeUUID(id), label]));
759
+ this.cdr.markForCheck();
760
+ }
761
+ get OwnerLabels() {
762
+ return this._ownerLabels;
763
+ }
764
+ /** Icon of the empty state of a flat list with no dashboards and no search. */
765
+ FlatEmptyIcon = 'fa-solid fa-layer-group';
766
+ /** Title of the empty state of a flat list with no dashboards and no search. */
767
+ FlatEmptyTitle = 'No dashboards to show';
768
+ /** Message of the empty state of a flat list with no dashboards and no search. */
769
+ FlatEmptyMessage = 'There are no dashboards in this list yet.';
770
+ /** When true, an empty flat list with no search shows the first-run welcome instead. */
771
+ FlatEmptyWelcome = false;
762
772
  // ========================================
763
773
  // Outputs
764
774
  // ========================================
@@ -766,7 +776,7 @@ export class DashboardBrowserComponent {
766
776
  DashboardOpen = new EventEmitter();
767
777
  /** Emitted when a dashboard is opened for editing */
768
778
  DashboardEdit = new EventEmitter();
769
- /** Emitted when dashboards are requested for deletion */
779
+ /** Emitted after the user confirms a delete. The host deletes the dashboards and does not ask again. */
770
780
  DashboardDelete = new EventEmitter();
771
781
  /** Emitted when dashboards are requested to move to a folder */
772
782
  DashboardMove = new EventEmitter();
@@ -782,6 +792,8 @@ export class DashboardBrowserComponent {
782
792
  ViewModeChange = new EventEmitter();
783
793
  /** Emitted when view preference should be persisted */
784
794
  ViewPreferenceChange = new EventEmitter();
795
+ /** Emitted when the user stars or unstars a dashboard on its card */
796
+ DashboardFavoriteToggle = new EventEmitter();
785
797
  // ========================================
786
798
  // State
787
799
  // ========================================
@@ -791,14 +803,10 @@ export class DashboardBrowserComponent {
791
803
  SearchText = '';
792
804
  /** Set of selected dashboard IDs */
793
805
  SelectedIds = new Set();
794
- /** Last clicked dashboard ID (for shift-click range selection) */
806
+ /** The last dashboard clicked in selection mode: where a Shift-click range starts */
795
807
  lastClickedId = null;
796
- /** Whether delete confirmation dialog is visible */
797
- ShowDeleteConfirm = false;
798
808
  /** Whether move-to-folder dialog is visible */
799
809
  ShowMoveDialog = false;
800
- /** Dashboards pending deletion (for confirm dialog) */
801
- DashboardsPendingDelete = [];
802
810
  /** Currently dragging dashboard ID */
803
811
  DraggingId = null;
804
812
  /** Drop target category ID */
@@ -828,8 +836,9 @@ export class DashboardBrowserComponent {
828
836
  // ========================================
829
837
  // Constructor
830
838
  // ========================================
831
- constructor(cdr) {
839
+ constructor(cdr, confirmService) {
832
840
  this.cdr = cdr;
841
+ this.confirmService = confirmService;
833
842
  }
834
843
  // ========================================
835
844
  // Lifecycle
@@ -884,6 +893,14 @@ export class DashboardBrowserComponent {
884
893
  get NoResultsMessage() {
885
894
  return `No dashboards or folders match "${this.SearchText}". Try a different search term.`;
886
895
  }
896
+ /**
897
+ * Whether an empty browser shows the first-run welcome: in flat mode when the host asks for it
898
+ * (FlatEmptyWelcome) and there is no search; in folder mode at the root when there are no
899
+ * dashboards at all.
900
+ */
901
+ get ShowWelcome() {
902
+ return this._flatMode ? this.FlatEmptyWelcome && !this.SearchText : this.IsAtRoot && this._dashboards.length === 0;
903
+ }
887
904
  /**
888
905
  * Handle category filter change
889
906
  */
@@ -943,38 +960,28 @@ export class DashboardBrowserComponent {
943
960
  // Public Methods - Selection
944
961
  // ========================================
945
962
  /**
946
- * Handle dashboard click with multi-select support
963
+ * Handles a click on a dashboard. Outside selection mode every click opens the dashboard, and a
964
+ * Shift, Ctrl or Cmd click asks for a separate tab (`OpenInNewTab`). In selection mode a
965
+ * Shift-click selects the range from the last dashboard clicked in selection mode (just this one
966
+ * when there is none yet), a Ctrl or Cmd click toggles the dashboard, and a plain click clears
967
+ * the selection and opens the dashboard.
947
968
  */
948
969
  OnDashboardClick(dashboard, event) {
949
- if (!this.AllowMultiSelect) {
950
- // Single select mode - just open the dashboard
951
- this.DashboardOpen.emit({ Dashboard: dashboard, OpenInNewTab: event.ctrlKey || event.metaKey });
970
+ if (!this.AllowMultiSelect || !this.IsSelectionMode) {
971
+ this.SelectedIds.clear();
972
+ this.DashboardOpen.emit({ Dashboard: dashboard, OpenInNewTab: event.shiftKey || event.ctrlKey || event.metaKey });
973
+ this.cdr.markForCheck();
952
974
  return;
953
975
  }
954
976
  if (event.shiftKey && this.lastClickedId) {
955
- // Shift-click: range selection
956
977
  this.selectRange(this.lastClickedId, dashboard.ID);
957
978
  }
958
- else if (event.ctrlKey || event.metaKey) {
959
- // Ctrl/Cmd-click: toggle selection
979
+ else if (event.shiftKey || event.ctrlKey || event.metaKey) {
960
980
  this.ToggleSelection(dashboard.ID);
961
981
  }
962
982
  else {
963
- // Normal click: if not selected, open; if selected with others, open
964
- if (this.SelectedIds.size <= 1) {
965
- this.SelectedIds.clear();
966
- this.DashboardOpen.emit({ Dashboard: dashboard, OpenInNewTab: false });
967
- }
968
- else if (this.SelectedIds.has(dashboard.ID)) {
969
- // Clicking on one of multiple selected items - open just this one
970
- this.SelectedIds.clear();
971
- this.DashboardOpen.emit({ Dashboard: dashboard, OpenInNewTab: false });
972
- }
973
- else {
974
- // Clicking on unselected item - clear selection and open
975
- this.SelectedIds.clear();
976
- this.DashboardOpen.emit({ Dashboard: dashboard, OpenInNewTab: false });
977
- }
983
+ this.SelectedIds.clear();
984
+ this.DashboardOpen.emit({ Dashboard: dashboard, OpenInNewTab: false });
978
985
  }
979
986
  this.lastClickedId = dashboard.ID;
980
987
  this.cdr.markForCheck();
@@ -1072,7 +1079,7 @@ export class DashboardBrowserComponent {
1072
1079
  */
1073
1080
  OnCreateDashboard() {
1074
1081
  this.CloseNewMenu();
1075
- this.DashboardCreate.emit({ CategoryId: this.SelectedCategoryId });
1082
+ this.DashboardCreate.emit({ CategoryId: this.folderIdForNewItems });
1076
1083
  }
1077
1084
  /**
1078
1085
  * Open the create category dialog
@@ -1100,66 +1107,44 @@ export class DashboardBrowserComponent {
1100
1107
  if (!this.NewCategoryName.trim())
1101
1108
  return;
1102
1109
  this.CategoryCreate.emit({
1103
- ParentCategoryId: this.SelectedCategoryId,
1110
+ ParentCategoryId: this.folderIdForNewItems,
1104
1111
  Name: this.NewCategoryName.trim(),
1105
1112
  Description: this.NewCategoryDescription.trim() || null
1106
1113
  });
1107
1114
  this.CloseCreateCategoryDialog();
1108
1115
  }
1109
1116
  /**
1110
- * Open edit dialog for single dashboard via context menu
1117
+ * Asks the host to edit one dashboard. A click event, when given, does not also reach the row or card.
1111
1118
  */
1112
1119
  OnEditDashboard(dashboard, event) {
1113
- event.stopPropagation();
1120
+ event?.stopPropagation();
1114
1121
  this.DashboardEdit.emit({ Dashboard: dashboard });
1115
1122
  }
1116
1123
  /**
1117
- * Request to delete a single dashboard
1124
+ * Asks the user to confirm deleting one dashboard, then emits DashboardDelete. A click event, when
1125
+ * given, does not also reach the row or card.
1118
1126
  */
1119
- OnDeleteDashboard(dashboard, event) {
1120
- event.stopPropagation();
1121
- this.DashboardsPendingDelete = [dashboard];
1122
- this.ShowDeleteConfirm = true;
1123
- this.cdr.markForCheck();
1127
+ async OnDeleteDashboard(dashboard, event) {
1128
+ event?.stopPropagation();
1129
+ await this.confirmAndDelete([dashboard]);
1124
1130
  }
1125
- /**
1126
- * Request to delete selected dashboards.
1127
- * Only includes dashboards the user has permission to delete.
1128
- */
1129
- OnDeleteSelected() {
1130
- if (this.SelectedIds.size === 0)
1131
- return;
1132
- // Only include dashboards the user can delete
1133
- this.DashboardsPendingDelete = this.GetDeletableSelectedDashboards();
1134
- if (this.DashboardsPendingDelete.length === 0) {
1135
- // No deletable dashboards selected
1136
- return;
1137
- }
1138
- this.ShowDeleteConfirm = true;
1139
- this.cdr.markForCheck();
1131
+ /** Emits DashboardFavoriteToggle for the dashboard whose star the user clicked. */
1132
+ OnToggleFavorite(dashboard) {
1133
+ this.DashboardFavoriteToggle.emit({ Dashboard: dashboard });
1140
1134
  }
1141
- /**
1142
- * Confirm deletion
1143
- */
1144
- ConfirmDelete() {
1145
- if (this.DashboardsPendingDelete.length > 0) {
1146
- this.DashboardDelete.emit({ Dashboards: this.DashboardsPendingDelete });
1147
- // Clear selection for deleted items
1148
- for (const d of this.DashboardsPendingDelete) {
1149
- this.SelectedIds.delete(d.ID);
1150
- }
1151
- }
1152
- this.CloseDeleteConfirm();
1153
- // Exit selection mode after bulk operation
1154
- this.ExitSelectionMode();
1135
+ /** Asks the user to confirm deleting the selected dashboards they may delete, then emits DashboardDelete. */
1136
+ async OnDeleteSelected() {
1137
+ const deletable = this.GetDeletableSelectedDashboards();
1138
+ if (deletable.length === 0)
1139
+ return;
1140
+ await this.confirmAndDelete(deletable);
1155
1141
  }
1156
- /**
1157
- * Cancel deletion
1158
- */
1159
- CloseDeleteConfirm() {
1160
- this.ShowDeleteConfirm = false;
1161
- this.DashboardsPendingDelete = [];
1162
- this.cdr.markForCheck();
1142
+ /** Emits DashboardDelete and leaves selection mode when the user confirms; keeps everything when they cancel. */
1143
+ async confirmAndDelete(dashboards) {
1144
+ if (!(await this.confirmService.ConfirmDelete(deleteDashboardsConfirm(dashboards))))
1145
+ return;
1146
+ this.DashboardDelete.emit({ Dashboards: dashboards });
1147
+ this.ExitSelectionMode(); // clears SelectedIds and calls markForCheck
1163
1148
  }
1164
1149
  /**
1165
1150
  * Open move-to-folder dialog for selected dashboards
@@ -1334,8 +1319,7 @@ export class DashboardBrowserComponent {
1334
1319
  try {
1335
1320
  const dragData = JSON.parse(data);
1336
1321
  if (dragData.type === 'dashboards' && dragData.ids?.length > 0) {
1337
- const draggedIds = new Set(dragData.ids.map((id) => NormalizeUUID(id)));
1338
- const dashboards = this.Dashboards.filter(d => draggedIds.has(NormalizeUUID(d.ID)));
1322
+ const dashboards = FilterByUUIDs(this.Dashboards, dragData.ids);
1339
1323
  if (dashboards.length > 0) {
1340
1324
  this.DashboardMove.emit({
1341
1325
  Dashboards: dashboards,
@@ -1365,27 +1349,22 @@ export class DashboardBrowserComponent {
1365
1349
  return category?.Name || 'Unknown';
1366
1350
  }
1367
1351
  /**
1368
- * Format date for display
1352
+ * Format date for display: "Today", "Yesterday", "N days ago" (under a week), else the local date
1369
1353
  */
1370
1354
  FormatDate(date) {
1371
- if (!date)
1372
- return '';
1373
- const d = new Date(date);
1374
- const now = new Date();
1375
- const diffMs = now.getTime() - d.getTime();
1376
- const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
1377
- if (diffDays === 0) {
1378
- return 'Today';
1379
- }
1380
- else if (diffDays === 1) {
1381
- return 'Yesterday';
1382
- }
1383
- else if (diffDays < 7) {
1384
- return `${diffDays} days ago`;
1385
- }
1386
- else {
1387
- return d.toLocaleDateString();
1388
- }
1355
+ return FormatDashboardDate(date);
1356
+ }
1357
+ /** True when the dashboard is one of the user's favorites (FavoriteIds). */
1358
+ IsFavorite(dashboardId) {
1359
+ return this._favoriteIds.has(NormalizeUUID(dashboardId));
1360
+ }
1361
+ /** The owner text of the dashboard's card (from OwnerLabels), or null for none. */
1362
+ OwnerLabel(dashboard) {
1363
+ return this.ownerLabelById.get(NormalizeUUID(dashboard.ID)) ?? null;
1364
+ }
1365
+ /** The category path a card shows: only in flat mode, where the folder is not otherwise visible. */
1366
+ CardCategoryPath(dashboard) {
1367
+ return this._flatMode ? DashboardCategoryPath(this.GetEffectiveCategoryId(dashboard), this._categories) : null;
1389
1368
  }
1390
1369
  /**
1391
1370
  * Track by function for ngFor
@@ -1506,8 +1485,7 @@ export class DashboardBrowserComponent {
1506
1485
  try {
1507
1486
  const dragData = JSON.parse(data);
1508
1487
  if (dragData.type === 'dashboards' && dragData.ids?.length > 0) {
1509
- const draggedIds = new Set(dragData.ids.map((id) => NormalizeUUID(id)));
1510
- const dashboards = this.Dashboards.filter(d => draggedIds.has(NormalizeUUID(d.ID)));
1488
+ const dashboards = FilterByUUIDs(this.Dashboards, dragData.ids);
1511
1489
  if (dashboards.length > 0) {
1512
1490
  this.DashboardMove.emit({
1513
1491
  Dashboards: dashboards,
@@ -1531,8 +1509,7 @@ export class DashboardBrowserComponent {
1531
1509
  * Handle drop from breadcrumb component
1532
1510
  */
1533
1511
  OnBreadcrumbDrop(event) {
1534
- const droppedIds = new Set(event.DashboardIds.map(id => NormalizeUUID(id)));
1535
- const dashboards = this.Dashboards.filter(d => droppedIds.has(NormalizeUUID(d.ID)));
1512
+ const dashboards = FilterByUUIDs(this.Dashboards, event.DashboardIds);
1536
1513
  if (dashboards.length > 0) {
1537
1514
  this.DashboardMove.emit({
1538
1515
  Dashboards: dashboards,
@@ -1545,6 +1522,10 @@ export class DashboardBrowserComponent {
1545
1522
  // ========================================
1546
1523
  // Private Methods
1547
1524
  // ========================================
1525
+ /** The folder new dashboards and categories go into: the selected one, or the root in flat mode. */
1526
+ get folderIdForNewItems() {
1527
+ return this._flatMode ? null : this.SelectedCategoryId;
1528
+ }
1548
1529
  applyFilters() {
1549
1530
  let filtered = [...this._dashboards];
1550
1531
  // Filter out non-Config dashboards (Code and Dynamic Code types are not viewable/editable in browser)
@@ -1555,16 +1536,18 @@ export class DashboardBrowserComponent {
1555
1536
  filtered = filtered.filter(d => d.Name.toLowerCase().includes(search) ||
1556
1537
  (d.Description || '').toLowerCase().includes(search));
1557
1538
  }
1558
- // Filter by current folder (category)
1539
+ // Filter by current folder (category); flat mode skips this and shows every dashboard
1559
1540
  // When at root (null), show only uncategorized dashboards
1560
1541
  // When in a category, show only dashboards directly in that category
1561
1542
  // Uses effective category (from EffectiveCategoryMap) for shared dashboards
1562
- if (this._selectedCategoryId) {
1563
- filtered = filtered.filter(d => this.GetEffectiveCategoryId(d) === this._selectedCategoryId);
1564
- }
1565
- else {
1566
- // At root level, show only uncategorized dashboards (effective CategoryID is null or empty)
1567
- filtered = filtered.filter(d => !this.GetEffectiveCategoryId(d));
1543
+ if (!this._flatMode) {
1544
+ if (this._selectedCategoryId) {
1545
+ filtered = filtered.filter(d => this.GetEffectiveCategoryId(d) === this._selectedCategoryId);
1546
+ }
1547
+ else {
1548
+ // At root level, show only uncategorized dashboards (effective CategoryID is null or empty)
1549
+ filtered = filtered.filter(d => !this.GetEffectiveCategoryId(d));
1550
+ }
1568
1551
  }
1569
1552
  this.FilteredDashboards = filtered;
1570
1553
  this.updateChildCategories();
@@ -1575,9 +1558,12 @@ export class DashboardBrowserComponent {
1575
1558
  * Update the list of child categories for the current folder
1576
1559
  */
1577
1560
  updateChildCategories() {
1578
- // Find categories that are children of the current category
1561
+ // Find categories that are children of the current category (none in flat mode)
1579
1562
  // Handle both null and undefined ParentID for root-level categories
1580
- if (this._selectedCategoryId) {
1563
+ if (this._flatMode) {
1564
+ this.ChildCategories = [];
1565
+ }
1566
+ else if (this._selectedCategoryId) {
1581
1567
  this.ChildCategories = this.Categories.filter(c => UUIDsEqual(c.ParentID, this._selectedCategoryId));
1582
1568
  }
1583
1569
  else {
@@ -1599,7 +1585,7 @@ export class DashboardBrowserComponent {
1599
1585
  */
1600
1586
  updateBreadcrumbs() {
1601
1587
  this.Breadcrumbs = [];
1602
- if (!this._selectedCategoryId)
1588
+ if (!this._selectedCategoryId || this._flatMode)
1603
1589
  return;
1604
1590
  // Build the path from current category to root
1605
1591
  const path = [];
@@ -1639,8 +1625,8 @@ export class DashboardBrowserComponent {
1639
1625
  this.SelectedIds.add(this.FilteredDashboards[i].ID);
1640
1626
  }
1641
1627
  }
1642
- static ɵfac = function DashboardBrowserComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || DashboardBrowserComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
1643
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DashboardBrowserComponent, selectors: [["mj-dashboard-browser"]], inputs: { Dashboards: "Dashboards", Categories: "Categories", SelectedCategoryId: "SelectedCategoryId", ViewMode: "ViewMode", IsLoading: "IsLoading", ShowCreateButton: "ShowCreateButton", AllowMultiSelect: "AllowMultiSelect", AllowDragDrop: "AllowDragDrop", Title: "Title", IconClass: "IconClass", DashboardPermissions: "DashboardPermissions", EffectiveCategoryMap: "EffectiveCategoryMap" }, outputs: { DashboardOpen: "DashboardOpen", DashboardEdit: "DashboardEdit", DashboardDelete: "DashboardDelete", DashboardMove: "DashboardMove", DashboardCreate: "DashboardCreate", CategoryCreate: "CategoryCreate", CategoryDelete: "CategoryDelete", CategoryChange: "CategoryChange", ViewModeChange: "ViewModeChange", ViewPreferenceChange: "ViewPreferenceChange" }, standalone: false, decls: 29, vars: 30, consts: [[1, "dashboard-browser"], [1, "browser-toolbar"], ["Size", "large", 3, "Navigate", "DashboardDrop", "Categories", "CurrentCategoryId", "RootIcon", "RootLabel", "AllowDragDrop"], [1, "toolbar-actions"], [1, "dashboard-count"], [1, "view-toggle"], ["title", "Card View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-grip"], ["title", "List View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-list"], [1, "new-dropdown"], [1, "dropdown-backdrop"], [1, "browser-filters"], [1, "search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search dashboards...", 3, "ngModelChange", "input", "ngModel"], [1, "clear-btn"], [1, "clear-filters-btn"], [1, "loading-overlay"], [1, "dashboard-grid"], [1, "dashboard-list"], [1, "category-drop-zones"], ["type", "danger", "confirmText", "Delete", "cancelText", "Cancel", 3, "confirmed", "cancelled", "visible", "title", "message"], [1, "move-dialog-overlay"], [1, "create-category-dialog-overlay"], [1, "delete-category-dialog-overlay"], ["title", "Select multiple dashboards", 1, "select-mode-btn"], [1, "selection-toolbar"], ["title", "Select multiple dashboards", 1, "select-mode-btn", 3, "click"], [1, "fa-solid", "fa-check-double"], [1, "selected-count"], ["title", "Select all", 1, "action-btn", 3, "click"], ["title", "Move to folder", 1, "action-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-folder-open"], ["title", "Delete selected", 1, "action-btn", "danger", 3, "click", "disabled"], [1, "fa-solid", "fa-trash"], ["title", "Exit selection mode", 1, "action-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-caret-down", "dropdown-caret"], [1, "dropdown-menu"], [1, "dropdown-item", 3, "click"], [1, "fa-solid", "fa-chart-line"], [1, "fa-solid", "fa-folder-plus"], [1, "dropdown-backdrop", 3, "click"], [1, "clear-btn", 3, "click"], [1, "clear-filters-btn", 3, "click"], [1, "fa-solid", "fa-filter-circle-xmark"], ["text", "Loading dashboards..."], [1, "dashboard-card", "category-card", 3, "drop-target"], [1, "dashboard-card", 3, "selected", "dragging", "draggable"], [1, "dashboard-card", "category-card", 3, "click", "dblclick", "dragover", "dragleave", "drop"], [1, "card-header"], [1, "card-icon", "folder-icon"], [1, "fa-solid", "fa-folder"], [1, "card-actions"], ["title", "Delete category", 1, "action-btn", "danger", 3, "click"], [1, "card-content"], [1, "card-title", 3, "innerHTML"], [1, "card-description", 3, "innerHTML"], [1, "card-meta"], [1, "meta-item"], [1, "fa-solid", "fa-folder-tree"], [1, "dashboard-card", 3, "click", "dblclick", "dragstart", "dragend", "draggable"], [1, "card-select-area"], [1, "card-icon"], ["title", "Edit", 1, "action-btn"], ["title", "Delete", 1, "action-btn", "danger"], [1, "card-title"], [3, "innerHTML"], ["title", "Shared with you", 1, "shared-badge"], [1, "fa-solid", "fa-clock"], [1, "card-select-area", 3, "click"], ["type", "checkbox", 3, "change", "checked"], ["title", "Edit", 1, "action-btn", 3, "click"], [1, "fa-solid", "fa-edit"], ["title", "Delete", 1, "action-btn", "danger", 3, "click"], [1, "fa-solid", "fa-share-nodes"], [1, "list-header"], [1, "list-col", "checkbox-col"], [1, "list-col", "name-col"], [1, "list-col", "type-col"], [1, "list-col", "date-col"], [1, "list-col", "actions-col"], [1, "list-row", "category-row", 3, "drop-target"], [1, "list-row", 3, "selected", "dragging", "draggable"], ["type", "checkbox", 3, "change", "checked", "indeterminate"], [1, "list-row", "category-row", 3, "click", "dragover", "dragleave", "drop"], [1, "fa-solid", "fa-folder", "row-icon", "folder-icon"], [1, "dashboard-name", 3, "innerHTML"], [1, "list-col", "actions-col", 3, "click"], [1, "list-row", 3, "click", "dblclick", "dragstart", "dragend", "draggable"], [1, "fa-solid", "fa-chart-line", "row-icon"], [1, "list-col", "checkbox-col", 3, "click"], ["Size", "large", "Icon", "fa-solid fa-gauge-high", "Title", "Welcome to Dashboards", "Message", "Create custom dashboards to visualize your data, track key metrics, and monitor important information all in one place.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "ActionText"], ["Variant", "warning", "Icon", "fa-solid fa-folder-open", "Title", "This folder is empty", "Message", "Add dashboards or create sub-folders to organize your content.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "ActionText"], ["Icon", "fa-solid fa-folder-tree", "Title", "No uncategorized dashboards", "Message", "All your dashboards are organized into folders. Browse the folders above or create a new dashboard here.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "ActionText"], ["Variant", "no-results", "Icon", "fa-solid fa-magnifying-glass", "Title", "No results found", "ActionText", "Clear Search", "ActionIcon", "fa-solid fa-times", "ActionVariant", "secondary", 1, "dashboard-empty", 3, "Message"], ["Size", "large", "Icon", "fa-solid fa-gauge-high", "Title", "Welcome to Dashboards", "Message", "Create custom dashboards to visualize your data, track key metrics, and monitor important information all in one place.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "Action", "ActionText"], [1, "empty-features"], [1, "feature-item"], [1, "fa-solid", "fa-table-cells"], [1, "fa-solid", "fa-database"], ["Variant", "warning", "Icon", "fa-solid fa-folder-open", "Title", "This folder is empty", "Message", "Add dashboards or create sub-folders to organize your content.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "Action", "ActionText"], ["Icon", "fa-solid fa-folder-tree", "Title", "No uncategorized dashboards", "Message", "All your dashboards are organized into folders. Browse the folders above or create a new dashboard here.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "Action", "ActionText"], ["Variant", "no-results", "Icon", "fa-solid fa-magnifying-glass", "Title", "No results found", "ActionText", "Clear Search", "ActionIcon", "fa-solid fa-times", "ActionVariant", "secondary", 1, "dashboard-empty", 3, "Action", "Message"], [1, "drop-zone-header"], [1, "drop-zones"], [1, "drop-zone", 3, "dragover", "dragleave", "drop"], [1, "drop-zone", 3, "active"], [1, "move-dialog-overlay", 3, "click"], [1, "move-dialog", 3, "click"], [1, "dialog-header"], [1, "close-btn", 3, "click"], [1, "dialog-content"], [1, "category-list"], [1, "category-option", 3, "click"], [1, "category-option"], [1, "dialog-footer"], [1, "btn-secondary", 3, "click"], [1, "create-category-dialog-overlay", 3, "click"], [1, "create-category-dialog", 3, "click"], [1, "form-field"], ["for", "category-name"], ["type", "text", "id", "category-name", "placeholder", "Enter category name", 3, "ngModelChange", "keyup.enter", "ngModel"], ["for", "category-description"], ["id", "category-description", "placeholder", "Optional description", "rows", "3", 3, "ngModelChange", "ngModel"], [1, "btn-primary", 3, "click", "disabled"], [1, "delete-category-dialog-overlay", 3, "click"], [1, "delete-category-dialog", 3, "click"], [1, "dialog-header", "danger"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "btn-danger", 3, "click", "disabled"], [1, "warning-message"], [1, "confirmation-checkbox"], [1, "checkbox-label"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "checkbox-text"], [1, "content-warning"], [1, "content-list"], [1, "fa-solid", "fa-warning"]], template: function DashboardBrowserComponent_Template(rf, ctx) { if (rf & 1) {
1628
+ static ɵfac = function DashboardBrowserComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || DashboardBrowserComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.MJConfirmService)); };
1629
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DashboardBrowserComponent, selectors: [["mj-dashboard-browser"]], inputs: { Dashboards: "Dashboards", Categories: "Categories", SelectedCategoryId: "SelectedCategoryId", FlatMode: "FlatMode", ViewMode: "ViewMode", IsLoading: "IsLoading", ShowCreateButton: "ShowCreateButton", AllowMultiSelect: "AllowMultiSelect", AllowDragDrop: "AllowDragDrop", Title: "Title", IconClass: "IconClass", DashboardPermissions: "DashboardPermissions", EffectiveCategoryMap: "EffectiveCategoryMap", FavoriteIds: "FavoriteIds", ShowFavorites: "ShowFavorites", OwnerLabels: "OwnerLabels", FlatEmptyIcon: "FlatEmptyIcon", FlatEmptyTitle: "FlatEmptyTitle", FlatEmptyMessage: "FlatEmptyMessage", FlatEmptyWelcome: "FlatEmptyWelcome" }, outputs: { DashboardOpen: "DashboardOpen", DashboardEdit: "DashboardEdit", DashboardDelete: "DashboardDelete", DashboardMove: "DashboardMove", DashboardCreate: "DashboardCreate", CategoryCreate: "CategoryCreate", CategoryDelete: "CategoryDelete", CategoryChange: "CategoryChange", ViewModeChange: "ViewModeChange", ViewPreferenceChange: "ViewPreferenceChange", DashboardFavoriteToggle: "DashboardFavoriteToggle" }, standalone: false, decls: 28, vars: 26, consts: [[1, "dashboard-browser"], [1, "browser-toolbar"], ["Size", "large", 3, "Navigate", "DashboardDrop", "Categories", "CurrentCategoryId", "RootIcon", "RootLabel", "AllowDragDrop"], [1, "toolbar-actions"], [1, "dashboard-count"], [1, "view-toggle"], ["title", "Card View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-grip"], ["title", "List View", 1, "toggle-btn", 3, "click"], [1, "fa-solid", "fa-list"], [1, "new-dropdown"], [1, "dropdown-backdrop"], [1, "browser-filters"], [1, "search-box"], [1, "fa-solid", "fa-search"], ["type", "text", "placeholder", "Search dashboards...", 3, "ngModelChange", "input", "ngModel"], [1, "clear-btn"], [1, "clear-filters-btn"], [1, "loading-overlay"], [1, "dashboard-grid"], [1, "dashboard-list"], [1, "category-drop-zones"], [1, "move-dialog-overlay"], [1, "create-category-dialog-overlay"], [1, "delete-category-dialog-overlay"], ["title", "Select multiple dashboards", 1, "select-mode-btn"], [1, "selection-toolbar"], ["title", "Select multiple dashboards", 1, "select-mode-btn", 3, "click"], [1, "fa-solid", "fa-check-double"], [1, "selected-count"], ["title", "Select all", 1, "action-btn", 3, "click"], ["title", "Move to folder", 1, "action-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-folder-open"], ["title", "Delete selected", 1, "action-btn", "danger", 3, "click", "disabled"], [1, "fa-solid", "fa-trash"], ["title", "Exit selection mode", 1, "action-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "fa-solid", "fa-caret-down", "dropdown-caret"], [1, "dropdown-menu"], [1, "dropdown-item", 3, "click"], [1, "fa-solid", "fa-chart-line"], [1, "fa-solid", "fa-folder-plus"], [1, "dropdown-backdrop", 3, "click"], [1, "clear-btn", 3, "click"], [1, "clear-filters-btn", 3, "click"], [1, "fa-solid", "fa-filter-circle-xmark"], ["text", "Loading dashboards..."], [1, "dashboard-card", "category-card", 3, "drop-target"], [1, "dashboard-card-host", 3, "dragging", "draggable", "Dashboard", "IsFavorite", "ShowFavorite", "IsShared", "OwnerLabel", "CategoryPath", "HighlightQuery", "Selectable", "Selected", "CanEdit", "CanDelete"], [1, "dashboard-card", "category-card", 3, "click", "dblclick", "dragover", "dragleave", "drop"], [1, "card-header"], [1, "card-icon", "folder-icon"], [1, "fa-solid", "fa-folder"], [1, "card-actions"], ["title", "Delete category", 1, "action-btn", "danger", 3, "click"], [1, "card-content"], [1, "card-title", 3, "innerHTML"], [1, "card-description", 3, "innerHTML"], [1, "card-meta"], [1, "meta-item"], [1, "fa-solid", "fa-folder-tree"], [1, "dashboard-card-host", 3, "CardClick", "CardDoubleClick", "ToggleFavorite", "SelectionToggle", "Edit", "Delete", "dragstart", "dragend", "draggable", "Dashboard", "IsFavorite", "ShowFavorite", "IsShared", "OwnerLabel", "CategoryPath", "HighlightQuery", "Selectable", "Selected", "CanEdit", "CanDelete"], [1, "list-header"], [1, "list-col", "checkbox-col"], [1, "list-col", "name-col"], [1, "list-col", "type-col"], [1, "list-col", "date-col"], [1, "list-col", "actions-col"], [1, "list-row", "category-row", 3, "drop-target"], [1, "list-row", 3, "selected", "dragging", "draggable"], ["type", "checkbox", 3, "change", "checked", "indeterminate"], [1, "list-row", "category-row", 3, "click", "dragover", "dragleave", "drop"], [1, "fa-solid", "fa-folder", "row-icon", "folder-icon"], [1, "dashboard-name", 3, "innerHTML"], [1, "list-col", "actions-col", 3, "click"], [1, "list-row", 3, "click", "dblclick", "dragstart", "dragend", "draggable"], [1, "fa-solid", "fa-chart-line", "row-icon"], ["title", "Shared with you", 1, "shared-badge"], ["title", "Edit", 1, "action-btn"], ["title", "Delete", 1, "action-btn", "danger"], [1, "list-col", "checkbox-col", 3, "click"], ["type", "checkbox", 3, "change", "checked"], [1, "fa-solid", "fa-share-nodes"], ["title", "Edit", 1, "action-btn", 3, "click"], [1, "fa-solid", "fa-edit"], ["title", "Delete", 1, "action-btn", "danger", 3, "click"], ["Size", "large", "Icon", "fa-solid fa-gauge-high", "Title", "Welcome to Dashboards", "Message", "Create custom dashboards to visualize your data, track key metrics, and monitor important information all in one place.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "ActionText"], ["Variant", "no-results", "Icon", "fa-solid fa-magnifying-glass", "Title", "No results found", "ActionText", "Clear Search", "ActionIcon", "fa-solid fa-times", "ActionVariant", "secondary", 1, "dashboard-empty", 3, "Message"], ["Size", "large", "Icon", "fa-solid fa-gauge-high", "Title", "Welcome to Dashboards", "Message", "Create custom dashboards to visualize your data, track key metrics, and monitor important information all in one place.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "Action", "ActionText"], [1, "empty-features"], [1, "feature-item"], [1, "fa-solid", "fa-table-cells"], [1, "fa-solid", "fa-database"], [1, "dashboard-empty", 3, "Icon", "Title", "Message"], ["Variant", "warning", "Icon", "fa-solid fa-folder-open", "Title", "This folder is empty", "Message", "Add dashboards or create sub-folders to organize your content.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "ActionText"], ["Icon", "fa-solid fa-folder-tree", "Title", "No uncategorized dashboards", "Message", "All your dashboards are organized into folders. Browse the folders above or create a new dashboard here.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "ActionText"], ["Variant", "warning", "Icon", "fa-solid fa-folder-open", "Title", "This folder is empty", "Message", "Add dashboards or create sub-folders to organize your content.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "Action", "ActionText"], ["Icon", "fa-solid fa-folder-tree", "Title", "No uncategorized dashboards", "Message", "All your dashboards are organized into folders. Browse the folders above or create a new dashboard here.", "ActionIcon", "fa-solid fa-plus", 1, "dashboard-empty", 3, "Action", "ActionText"], ["Variant", "no-results", "Icon", "fa-solid fa-magnifying-glass", "Title", "No results found", "ActionText", "Clear Search", "ActionIcon", "fa-solid fa-times", "ActionVariant", "secondary", 1, "dashboard-empty", 3, "Action", "Message"], [1, "drop-zone-header"], [1, "drop-zones"], [1, "drop-zone", 3, "dragover", "dragleave", "drop"], [1, "drop-zone", 3, "active"], [1, "move-dialog-overlay", 3, "click"], [1, "move-dialog", 3, "click"], [1, "dialog-header"], [1, "close-btn", 3, "click"], [1, "dialog-content"], [1, "category-list"], [1, "category-option", 3, "click"], [1, "category-option"], [1, "dialog-footer"], [1, "btn-secondary", 3, "click"], [1, "create-category-dialog-overlay", 3, "click"], [1, "create-category-dialog", 3, "click"], [1, "form-field"], ["for", "category-name"], ["type", "text", "id", "category-name", "placeholder", "Enter category name", 3, "ngModelChange", "keyup.enter", "ngModel"], ["for", "category-description"], ["id", "category-description", "placeholder", "Optional description", "rows", "3", 3, "ngModelChange", "ngModel"], [1, "btn-primary", 3, "click", "disabled"], [1, "delete-category-dialog-overlay", 3, "click"], [1, "delete-category-dialog", 3, "click"], [1, "dialog-header", "danger"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "btn-danger", 3, "click", "disabled"], [1, "warning-message"], [1, "confirmation-checkbox"], [1, "checkbox-label"], ["type", "checkbox", 3, "ngModelChange", "ngModel"], [1, "checkbox-text"], [1, "content-warning"], [1, "content-list"], [1, "fa-solid", "fa-warning"]], template: function DashboardBrowserComponent_Template(rf, ctx) { if (rf & 1) {
1644
1630
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "mj-dashboard-breadcrumb", 2);
1645
1631
  i0.ɵɵlistener("Navigate", function DashboardBrowserComponent_Template_mj_dashboard_breadcrumb_Navigate_2_listener($event) { return ctx.NavigateToCategory($event.CategoryId); })("DashboardDrop", function DashboardBrowserComponent_Template_mj_dashboard_breadcrumb_DashboardDrop_2_listener($event) { return ctx.OnBreadcrumbDrop($event); });
1646
1632
  i0.ɵɵelementEnd();
@@ -1672,19 +1658,16 @@ export class DashboardBrowserComponent {
1672
1658
  i0.ɵɵconditionalCreate(20, DashboardBrowserComponent_Conditional_20_Template, 2, 0, "div", 18);
1673
1659
  i0.ɵɵconditionalCreate(21, DashboardBrowserComponent_Conditional_21_Template, 5, 0, "div", 19);
1674
1660
  i0.ɵɵconditionalCreate(22, DashboardBrowserComponent_Conditional_22_Template, 15, 1, "div", 20);
1675
- i0.ɵɵconditionalCreate(23, DashboardBrowserComponent_Conditional_23_Template, 4, 4);
1661
+ i0.ɵɵconditionalCreate(23, DashboardBrowserComponent_Conditional_23_Template, 4, 3);
1676
1662
  i0.ɵɵconditionalCreate(24, DashboardBrowserComponent_Conditional_24_Template, 9, 2, "div", 21);
1677
- i0.ɵɵelementStart(25, "mj-confirm-dialog", 22);
1678
- i0.ɵɵlistener("confirmed", function DashboardBrowserComponent_Template_mj_confirm_dialog_confirmed_25_listener() { return ctx.ConfirmDelete(); })("cancelled", function DashboardBrowserComponent_Template_mj_confirm_dialog_cancelled_25_listener() { return ctx.CloseDeleteConfirm(); });
1679
- i0.ɵɵelementEnd();
1680
- i0.ɵɵconditionalCreate(26, DashboardBrowserComponent_Conditional_26_Template, 19, 2, "div", 23);
1681
- i0.ɵɵconditionalCreate(27, DashboardBrowserComponent_Conditional_27_Template, 23, 3, "div", 24);
1682
- i0.ɵɵconditionalCreate(28, DashboardBrowserComponent_Conditional_28_Template, 15, 2, "div", 25);
1663
+ i0.ɵɵconditionalCreate(25, DashboardBrowserComponent_Conditional_25_Template, 19, 2, "div", 22);
1664
+ i0.ɵɵconditionalCreate(26, DashboardBrowserComponent_Conditional_26_Template, 23, 3, "div", 23);
1665
+ i0.ɵɵconditionalCreate(27, DashboardBrowserComponent_Conditional_27_Template, 15, 2, "div", 24);
1683
1666
  i0.ɵɵelementEnd();
1684
1667
  } if (rf & 2) {
1685
1668
  i0.ɵɵclassProp("loading", ctx.IsLoading);
1686
1669
  i0.ɵɵadvance(2);
1687
- i0.ɵɵproperty("Categories", ctx.Categories)("CurrentCategoryId", ctx.SelectedCategoryId)("RootIcon", ctx.IconClass)("RootLabel", ctx.Title)("AllowDragDrop", ctx.AllowDragDrop && (ctx.DraggingId !== null || ctx.IsSelectionMode));
1670
+ i0.ɵɵproperty("Categories", ctx.Categories)("CurrentCategoryId", ctx.FlatMode ? null : ctx.SelectedCategoryId)("RootIcon", ctx.IconClass)("RootLabel", ctx.Title)("AllowDragDrop", ctx.AllowDragDrop && (ctx.DraggingId !== null || ctx.IsSelectionMode));
1688
1671
  i0.ɵɵadvance(3);
1689
1672
  i0.ɵɵtextInterpolate1("", ctx.FilteredDashboards.length, " dashboards");
1690
1673
  i0.ɵɵadvance(2);
@@ -1714,24 +1697,24 @@ export class DashboardBrowserComponent {
1714
1697
  i0.ɵɵadvance();
1715
1698
  i0.ɵɵconditional(ctx.DraggingId && ctx.Categories.length > 0 ? 24 : -1);
1716
1699
  i0.ɵɵadvance();
1717
- i0.ɵɵproperty("title", i0.ɵɵinterpolate1("Delete Dashboard", ctx.DashboardsPendingDelete.length > 1 ? "s" : ""))("visible", ctx.ShowDeleteConfirm)("message", ctx.DashboardsPendingDelete.length === 1 ? "Are you sure you want to delete '" + ctx.DashboardsPendingDelete[0].Name + "'? This action cannot be undone." : "Are you sure you want to delete " + ctx.DashboardsPendingDelete.length + " dashboards? This action cannot be undone.");
1700
+ i0.ɵɵconditional(ctx.ShowMoveDialog ? 25 : -1);
1718
1701
  i0.ɵɵadvance();
1719
- i0.ɵɵconditional(ctx.ShowMoveDialog ? 26 : -1);
1702
+ i0.ɵɵconditional(ctx.ShowCreateCategoryDialog ? 26 : -1);
1720
1703
  i0.ɵɵadvance();
1721
- i0.ɵɵconditional(ctx.ShowCreateCategoryDialog ? 27 : -1);
1722
- i0.ɵɵadvance();
1723
- i0.ɵɵconditional(ctx.ShowDeleteCategoryConfirm ? 28 : -1);
1724
- } }, dependencies: [i1.DefaultValueAccessor, i1.CheckboxControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.MJEmptyStateComponent, i4.DashboardBreadcrumbComponent, i5.ConfirmDialogComponent], styles: ["\n\n.dashboard-browser[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n position: relative;\n}\n\n\n.browser-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 24px 0 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n}\n\n.toolbar-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-count[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 13px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n}\n\n\n.browser-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n\n.view-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n}\n\n.toggle-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.toggle-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.toggle-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n\n.select-mode-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.select-mode-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.select-mode-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n.selection-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 6px;\n}\n\n.selection-toolbar[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.selection-toolbar[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%]:disabled:hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.selected-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n min-width: 70px;\n}\n\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.action-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.action-btn.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n\n.browser-filters[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-box[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n flex: 1;\n max-width: 400px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n padding: 0 12px;\n}\n\n.search-box[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.search-box[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n}\n\n.search-box[_ngcontent-%COMP%] .clear-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n border-radius: 50%;\n}\n\n.search-box[_ngcontent-%COMP%] .clear-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.category-filter[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n padding: 10px 32px 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n outline: none;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n}\n\n.clear-filters-btn[_ngcontent-%COMP%], \n.select-all-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.clear-filters-btn[_ngcontent-%COMP%]:hover, \n.select-all-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n\n.dashboard-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 24px;\n overflow-y: auto;\n}\n\n.dashboard-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n cursor: pointer;\n transition: all 0.2s;\n border: 2px solid transparent;\n position: relative;\n}\n\n.dashboard-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n transform: translateY(-2px);\n}\n\n.dashboard-card.selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.dashboard-card.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.card-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n}\n\n\n.card-select-area[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 2;\n padding: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s;\n}\n\n.card-select-area[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n}\n\n.dashboard-card.selected[_ngcontent-%COMP%] .card-select-area[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.card-select-area[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n}\n\n.card-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-left: auto;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.dashboard-card[_ngcontent-%COMP%]:hover .card-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.card-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n\n.shared-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.card-description[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n\n.dashboard-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n background: var(--mj-bg-surface);\n margin: 16px 24px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.list-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.list-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.list-row[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.list-row.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.list-row.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n.list-col[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n}\n\n.checkbox-col[_ngcontent-%COMP%] {\n width: 40px;\n}\n\n.checkbox-col[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.name-col[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 200px;\n gap: 10px;\n display: flex;\n align-items: center;\n}\n\n.name-col[_ngcontent-%COMP%] .shared-badge[_ngcontent-%COMP%] {\n margin-left: 4px;\n}\n\n.row-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.dashboard-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.category-col[_ngcontent-%COMP%], \n.type-col[_ngcontent-%COMP%] {\n width: 120px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.date-col[_ngcontent-%COMP%] {\n width: 120px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.actions-col[_ngcontent-%COMP%] {\n width: 80px;\n justify-content: flex-end;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.list-row[_ngcontent-%COMP%]:hover .actions-col[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n\n\n\n.dashboard-empty[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 400px;\n}\n\n\n.empty-features[_ngcontent-%COMP%] {\n display: flex;\n gap: 32px;\n margin-top: var(--mj-space-5);\n padding-top: 24px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.feature-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.feature-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n\n.category-drop-zones[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 1000;\n}\n\n.drop-zone-header[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n text-align: center;\n}\n\n.drop-zones[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n justify-content: center;\n}\n\n.drop-zone[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.drop-zone[_ngcontent-%COMP%]:hover, \n.drop-zone.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n}\n\n\n.move-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.move-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n overflow-y: auto;\n}\n\n.dialog-content[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.category-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.category-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.category-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.category-option[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n\n.new-dropdown[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.dropdown-caret[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-left: 4px;\n}\n\n.dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n overflow: hidden;\n}\n\n.dropdown-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 12px 16px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 14px;\n cursor: pointer;\n text-align: left;\n transition: background 0.15s;\n}\n\n.dropdown-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.dropdown-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n width: 16px;\n text-align: center;\n}\n\n.dropdown-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n z-index: 1000;\n}\n\n\n.create-category-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.form-field[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.form-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%], \n.form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s, box-shadow 0.15s;\n box-sizing: border-box;\n}\n\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus, \n.form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 80px;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] .btn-primary[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n margin-left: auto;\n}\n\n\n.breadcrumb-nav[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-wrap: wrap;\n}\n\n.breadcrumb-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s;\n}\n\n.breadcrumb-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.breadcrumb-item.current[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 500;\n cursor: default;\n}\n\n.breadcrumb-item.current[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n.breadcrumb-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.breadcrumb-item.root[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.breadcrumb-separator[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 10px;\n}\n\n\n.category-card[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.category-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n}\n\n.folder-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-warning) !important;\n}\n\n.category-row[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.category-row[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface)) !important;\n}\n\n.category-row[_ngcontent-%COMP%] .folder-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n\n.dashboard-card.category-card.drop-target[_ngcontent-%COMP%], \n.list-row.category-row.drop-target[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n\nmark[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n color: inherit;\n padding: 0 2px;\n border-radius: 2px;\n}\n\n\n.delete-category-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 480px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header.danger[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-bottom-color: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header.danger[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header.danger[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.warning-message[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.warning-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n}\n\n.warning-message[_ngcontent-%COMP%] .content-warning[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 16px;\n}\n\n.warning-message[_ngcontent-%COMP%] .content-list[_ngcontent-%COMP%] {\n margin: 8px 0 0 0;\n padding-left: 24px;\n color: var(--mj-text-secondary);\n}\n\n.warning-message[_ngcontent-%COMP%] .content-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin: 6px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.warning-message[_ngcontent-%COMP%] .content-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n width: 16px;\n text-align: center;\n}\n\n.confirmation-checkbox[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 8px;\n padding: 16px;\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n accent-color: var(--mj-status-error);\n}\n\n.checkbox-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 85%, black);\n}\n\n.btn-danger[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-disabled);\n cursor: not-allowed;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n margin-left: auto;\n}"], changeDetection: 0 });
1704
+ i0.ɵɵconditional(ctx.ShowDeleteCategoryConfirm ? 27 : -1);
1705
+ } }, dependencies: [i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.LoadingComponent, i1.MJEmptyStateComponent, i4.DashboardBreadcrumbComponent, i5.DashboardCardComponent], styles: ["\n\n.dashboard-browser[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n position: relative;\n}\n\n\n.browser-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 24px 0 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n}\n\n.toolbar-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-count[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 13px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n}\n\n\n.browser-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n\n.view-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n}\n\n.toggle-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.toggle-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.toggle-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n\n.select-mode-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.select-mode-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.select-mode-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n.selection-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 6px;\n}\n\n.selection-toolbar[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.selection-toolbar[_ngcontent-%COMP%] .action-btn[_ngcontent-%COMP%]:disabled:hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.selected-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n min-width: 70px;\n}\n\n\n.btn-primary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.action-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.action-btn.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n\n.browser-filters[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-box[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n flex: 1;\n max-width: 400px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n padding: 0 12px;\n}\n\n.search-box[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.search-box[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n}\n\n.search-box[_ngcontent-%COMP%] .clear-btn[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n border-radius: 50%;\n}\n\n.search-box[_ngcontent-%COMP%] .clear-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.category-filter[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n padding: 10px 32px 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n outline: none;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n}\n\n.clear-filters-btn[_ngcontent-%COMP%], \n.select-all-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.clear-filters-btn[_ngcontent-%COMP%]:hover, \n.select-all-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n.loading-overlay[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n\n.dashboard-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 24px;\n overflow-y: auto;\n}\n\n\n.dashboard-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition:\n border-color var(--mj-transition-fast),\n box-shadow var(--mj-transition-fast),\n transform var(--mj-transition-fast);\n position: relative;\n}\n\n.dashboard-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dashboard-card[_ngcontent-%COMP%] {\n transition: none;\n }\n\n .dashboard-card[_ngcontent-%COMP%]:hover {\n transform: none;\n }\n}\n\n\n.dashboard-card-host.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.card-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n}\n\n.card-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-left: auto;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.dashboard-card[_ngcontent-%COMP%]:hover .card-actions[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.card-content[_ngcontent-%COMP%] {\n padding: 16px;\n}\n\n.card-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n\n.shared-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.card-description[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n\n.dashboard-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n background: var(--mj-bg-surface);\n margin: 16px 24px;\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.list-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.list-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.list-row[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.list-row.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.list-row.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n.list-col[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n}\n\n.checkbox-col[_ngcontent-%COMP%] {\n width: 40px;\n}\n\n.checkbox-col[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.name-col[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 200px;\n gap: 10px;\n display: flex;\n align-items: center;\n}\n\n.name-col[_ngcontent-%COMP%] .shared-badge[_ngcontent-%COMP%] {\n margin-left: 4px;\n}\n\n.row-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.dashboard-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.category-col[_ngcontent-%COMP%], \n.type-col[_ngcontent-%COMP%] {\n width: 120px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.date-col[_ngcontent-%COMP%] {\n width: 120px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.actions-col[_ngcontent-%COMP%] {\n width: 80px;\n justify-content: flex-end;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.list-row[_ngcontent-%COMP%]:hover .actions-col[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n\n\n\n.dashboard-empty[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 400px;\n}\n\n\n.empty-features[_ngcontent-%COMP%] {\n display: flex;\n gap: 32px;\n margin-top: var(--mj-space-5);\n padding-top: 24px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.feature-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.feature-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n\n.category-drop-zones[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 1000;\n}\n\n.drop-zone-header[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n text-align: center;\n}\n\n.drop-zones[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n justify-content: center;\n}\n\n.drop-zone[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.drop-zone[_ngcontent-%COMP%]:hover, \n.drop-zone.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n}\n\n\n.move-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.move-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n overflow-y: auto;\n}\n\n.dialog-content[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.category-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.category-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.category-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.category-option[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n\n.new-dropdown[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.dropdown-caret[_ngcontent-%COMP%] {\n font-size: 10px;\n margin-left: 4px;\n}\n\n.dropdown-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n overflow: hidden;\n}\n\n.dropdown-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 12px 16px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 14px;\n cursor: pointer;\n text-align: left;\n transition: background 0.15s;\n}\n\n.dropdown-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.dropdown-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n width: 16px;\n text-align: center;\n}\n\n.dropdown-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n z-index: 1000;\n}\n\n\n.create-category-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.form-field[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.form-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%], \n.form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s, box-shadow 0.15s;\n box-sizing: border-box;\n}\n\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus, \n.form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 80px;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] .btn-primary[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.create-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n margin-left: auto;\n}\n\n\n.breadcrumb-nav[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-wrap: wrap;\n}\n\n.breadcrumb-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s;\n}\n\n.breadcrumb-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.breadcrumb-item.current[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-weight: 500;\n cursor: default;\n}\n\n.breadcrumb-item.current[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n.breadcrumb-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.breadcrumb-item.root[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.breadcrumb-separator[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 10px;\n}\n\n\n.category-card[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.category-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n}\n\n.folder-icon[_ngcontent-%COMP%] {\n background: var(--mj-status-warning) !important;\n}\n\n.category-row[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.category-row[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface)) !important;\n}\n\n.category-row[_ngcontent-%COMP%] .folder-icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n\n.dashboard-card.category-card.drop-target[_ngcontent-%COMP%], \n.list-row.category-row.drop-target[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n\n\n\n[_nghost-%COMP%] mark {\n background: color-mix(in srgb, var(--mj-status-warning) 35%, transparent);\n color: inherit;\n border-radius: 2px;\n padding: 0 1px;\n}\n\n\n.delete-category-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 480px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header.danger[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-bottom-color: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header.danger[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header.danger[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.warning-message[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.warning-message[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n}\n\n.warning-message[_ngcontent-%COMP%] .content-warning[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 16px;\n}\n\n.warning-message[_ngcontent-%COMP%] .content-list[_ngcontent-%COMP%] {\n margin: 8px 0 0 0;\n padding-left: 24px;\n color: var(--mj-text-secondary);\n}\n\n.warning-message[_ngcontent-%COMP%] .content-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n margin: 6px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.warning-message[_ngcontent-%COMP%] .content-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n width: 16px;\n text-align: center;\n}\n\n.confirmation-checkbox[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 8px;\n padding: 16px;\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n accent-color: var(--mj-status-error);\n}\n\n.checkbox-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 85%, black);\n}\n\n.btn-danger[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-disabled);\n cursor: not-allowed;\n}\n\n.delete-category-dialog[_ngcontent-%COMP%] .dialog-footer[_ngcontent-%COMP%] .btn-secondary[_ngcontent-%COMP%] {\n margin-left: auto;\n}"], changeDetection: 0 });
1725
1706
  }
1726
1707
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DashboardBrowserComponent, [{
1727
1708
  type: Component,
1728
- args: [{ standalone: false, selector: 'mj-dashboard-browser', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Dashboard Browser Component -->\n<div class=\"dashboard-browser\" [class.loading]=\"IsLoading\">\n <!-- Toolbar Row: Breadcrumb + Actions -->\n <div class=\"browser-toolbar\">\n <!-- Breadcrumb Navigation -->\n <mj-dashboard-breadcrumb\n [Categories]=\"Categories\"\n [CurrentCategoryId]=\"SelectedCategoryId\"\n [RootIcon]=\"IconClass\"\n [RootLabel]=\"Title\"\n [AllowDragDrop]=\"AllowDragDrop && (DraggingId !== null || IsSelectionMode)\"\n Size=\"large\"\n (Navigate)=\"NavigateToCategory($event.CategoryId)\"\n (DashboardDrop)=\"OnBreadcrumbDrop($event)\">\n </mj-dashboard-breadcrumb>\n\n <!-- Right-side Actions -->\n <div class=\"toolbar-actions\">\n <!-- Dashboard count -->\n <span class=\"dashboard-count\">{{ FilteredDashboards.length }} dashboards</span>\n\n <!-- View Toggle -->\n <div class=\"view-toggle\">\n <button\n class=\"toggle-btn\"\n [class.active]=\"ViewMode === 'cards'\"\n (click)=\"SetViewMode('cards')\"\n title=\"Card View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button\n class=\"toggle-btn\"\n [class.active]=\"ViewMode === 'list'\"\n (click)=\"SetViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n\n <!-- Selection Mode Toggle & Bulk Actions -->\n @if (AllowMultiSelect) {\n <!-- Enter Selection Mode Button (when not in selection mode) -->\n @if (!IsSelectionMode && FilteredDashboards.length > 0) {\n <button\n class=\"select-mode-btn\"\n (click)=\"EnterSelectionMode()\"\n title=\"Select multiple dashboards\">\n <i class=\"fa-solid fa-check-double\"></i>\n Select\n </button>\n }\n <!-- Selection Mode Toolbar (when in selection mode) -->\n @if (IsSelectionMode) {\n <div class=\"selection-toolbar\">\n <span class=\"selected-count\">{{ SelectedCount }} selected</span>\n <button class=\"action-btn\" (click)=\"SelectAll()\" title=\"Select all\">\n <i class=\"fa-solid fa-check-double\"></i>\n </button>\n <button class=\"action-btn\" (click)=\"OnMoveSelected()\" title=\"Move to folder\" [disabled]=\"SelectedCount === 0\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </button>\n <button class=\"action-btn danger\" (click)=\"OnDeleteSelected()\" title=\"Delete selected\" [disabled]=\"!CanDeleteAnySelected\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n <button class=\"action-btn\" (click)=\"ExitSelectionMode()\" title=\"Exit selection mode\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n }\n\n <!-- New Dropdown Button -->\n @if (ShowCreateButton) {\n <div class=\"new-dropdown\">\n <button\n class=\"btn-primary\"\n (click)=\"ToggleNewMenu(); $event.stopPropagation()\">\n <i class=\"fa-solid fa-plus\"></i>\n New\n <i class=\"fa-solid fa-caret-down dropdown-caret\"></i>\n </button>\n @if (ShowNewMenu) {\n <div class=\"dropdown-menu\">\n <button class=\"dropdown-item\" (click)=\"OnCreateDashboard()\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Dashboard\n </button>\n <button class=\"dropdown-item\" (click)=\"OpenCreateCategoryDialog()\">\n <i class=\"fa-solid fa-folder-plus\"></i>\n Category\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Click-away overlay for dropdown -->\n @if (ShowNewMenu) {\n <div class=\"dropdown-backdrop\" (click)=\"CloseNewMenu()\"></div>\n }\n\n <!-- Filters -->\n <div class=\"browser-filters\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n [(ngModel)]=\"SearchText\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search dashboards...\">\n @if (SearchText) {\n <button\n class=\"clear-btn\"\n (click)=\"ClearSearch()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n @if (SearchText) {\n <button\n class=\"clear-filters-btn\"\n (click)=\"ClearSearch()\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n Clear Search\n </button>\n }\n </div>\n\n <!-- Loading Overlay -->\n @if (IsLoading) {\n <div class=\"loading-overlay\">\n <mj-loading text=\"Loading dashboards...\"></mj-loading>\n </div>\n }\n\n <!-- Card View -->\n @if (ViewMode === 'cards' && (FilteredChildCategories.length > 0 || FilteredDashboards.length > 0)) {\n <div class=\"dashboard-grid\">\n <!-- Category Folders -->\n @for (category of FilteredChildCategories; track TrackByCategory($index, category)) {\n <div\n class=\"dashboard-card category-card\"\n [class.drop-target]=\"DragOverChildCategoryId === category.ID\"\n (click)=\"NavigateToCategory(category.ID)\"\n (dblclick)=\"$event.stopPropagation()\"\n (dragover)=\"OnDragOverChildCategory(category.ID, $event)\"\n (dragleave)=\"OnDragLeaveChildCategory()\"\n (drop)=\"OnDropOnChildCategory(category.ID, $event)\">\n <div class=\"card-header\">\n <div class=\"card-icon folder-icon\">\n <i class=\"fa-solid fa-folder\"></i>\n </div>\n <div class=\"card-actions\">\n <button\n class=\"action-btn danger\"\n title=\"Delete category\"\n (click)=\"OnDeleteCategory(category, $event)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n <div class=\"card-content\">\n <h3 class=\"card-title\" [innerHTML]=\"HighlightMatch(category.Name)\"></h3>\n @if (category.Description) {\n <p class=\"card-description\" [innerHTML]=\"HighlightMatch(category.Description)\">\n </p>\n }\n <div class=\"card-meta\">\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n Category\n </span>\n </div>\n </div>\n </div>\n }\n <!-- Dashboard Cards -->\n @for (dashboard of FilteredDashboards; track TrackByDashboard($index, dashboard)) {\n <div\n class=\"dashboard-card\"\n [class.selected]=\"IsSelected(dashboard.ID)\"\n [class.dragging]=\"DraggingId === dashboard.ID\"\n [draggable]=\"AllowDragDrop\"\n (click)=\"OnDashboardClick(dashboard, $event)\"\n (dblclick)=\"OnDashboardDoubleClick(dashboard, $event)\"\n (dragstart)=\"OnDragStart(dashboard, $event)\"\n (dragend)=\"OnDragEnd()\">\n <!-- Selection checkbox in top-right corner -->\n @if (IsSelectionMode) {\n <div\n class=\"card-select-area\"\n (click)=\"ToggleSelection(dashboard.ID); $event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"IsSelected(dashboard.ID)\"\n (change)=\"$event.stopPropagation()\">\n </div>\n }\n <div class=\"card-header\">\n <div class=\"card-icon\">\n <i class=\"fa-solid fa-chart-line\"></i>\n </div>\n <div class=\"card-actions\">\n @if (CanEdit(dashboard.ID)) {\n <button\n class=\"action-btn\"\n title=\"Edit\"\n (click)=\"OnEditDashboard(dashboard, $event)\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n }\n @if (CanDelete(dashboard.ID)) {\n <button\n class=\"action-btn danger\"\n title=\"Delete\"\n (click)=\"OnDeleteDashboard(dashboard, $event)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n <div class=\"card-content\">\n <h3 class=\"card-title\">\n <span [innerHTML]=\"HighlightMatch(dashboard.Name)\"></span>\n @if (IsShared(dashboard.ID)) {\n <span class=\"shared-badge\" title=\"Shared with you\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n </span>\n }\n </h3>\n @if (dashboard.Description) {\n <p class=\"card-description\" [innerHTML]=\"HighlightMatch(dashboard.Description)\">\n </p>\n }\n <div class=\"card-meta\">\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ FormatDate(dashboard.__mj_UpdatedAt) }}\n </span>\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- List View -->\n @if (ViewMode === 'list' && (FilteredChildCategories.length > 0 || FilteredDashboards.length > 0)) {\n <div class=\"dashboard-list\">\n <div class=\"list-header\">\n @if (IsSelectionMode) {\n <div class=\"list-col checkbox-col\">\n <input\n type=\"checkbox\"\n [checked]=\"SelectedCount === FilteredDashboards.length && FilteredDashboards.length > 0\"\n [indeterminate]=\"SelectedCount > 0 && SelectedCount < FilteredDashboards.length\"\n (change)=\"SelectedCount === FilteredDashboards.length ? ClearSelection() : SelectAll()\">\n </div>\n }\n <div class=\"list-col name-col\">Name</div>\n <div class=\"list-col type-col\">Type</div>\n <div class=\"list-col date-col\">Modified</div>\n <div class=\"list-col actions-col\">Actions</div>\n </div>\n <!-- Category Rows -->\n @for (category of FilteredChildCategories; track TrackByCategory($index, category)) {\n <div\n class=\"list-row category-row\"\n [class.drop-target]=\"DragOverChildCategoryId === category.ID\"\n (click)=\"NavigateToCategory(category.ID)\"\n (dragover)=\"OnDragOverChildCategory(category.ID, $event)\"\n (dragleave)=\"OnDragLeaveChildCategory()\"\n (drop)=\"OnDropOnChildCategory(category.ID, $event)\">\n @if (IsSelectionMode) {\n <div class=\"list-col checkbox-col\">\n <!-- Empty placeholder for alignment -->\n </div>\n }\n <div class=\"list-col name-col\">\n <i class=\"fa-solid fa-folder row-icon folder-icon\"></i>\n <span class=\"dashboard-name\" [innerHTML]=\"HighlightMatch(category.Name)\"></span>\n </div>\n <div class=\"list-col type-col\">\n Category\n </div>\n <div class=\"list-col date-col\">\n <!-- No date for categories -->\n </div>\n <div class=\"list-col actions-col\" (click)=\"$event.stopPropagation()\">\n <button\n class=\"action-btn danger\"\n title=\"Delete category\"\n (click)=\"OnDeleteCategory(category, $event)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n }\n <!-- Dashboard Rows -->\n @for (dashboard of FilteredDashboards; track TrackByDashboard($index, dashboard)) {\n <div\n class=\"list-row\"\n [class.selected]=\"IsSelected(dashboard.ID)\"\n [class.dragging]=\"DraggingId === dashboard.ID\"\n [draggable]=\"AllowDragDrop\"\n (click)=\"OnDashboardClick(dashboard, $event)\"\n (dblclick)=\"OnDashboardDoubleClick(dashboard, $event)\"\n (dragstart)=\"OnDragStart(dashboard, $event)\"\n (dragend)=\"OnDragEnd()\">\n @if (IsSelectionMode) {\n <div class=\"list-col checkbox-col\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"IsSelected(dashboard.ID)\"\n (change)=\"ToggleSelection(dashboard.ID)\">\n </div>\n }\n <div class=\"list-col name-col\">\n <i class=\"fa-solid fa-chart-line row-icon\"></i>\n <span class=\"dashboard-name\" [innerHTML]=\"HighlightMatch(dashboard.Name)\"></span>\n @if (IsShared(dashboard.ID)) {\n <span class=\"shared-badge\" title=\"Shared with you\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n </span>\n }\n </div>\n <div class=\"list-col type-col\">\n Dashboard\n </div>\n <div class=\"list-col date-col\">\n {{ FormatDate(dashboard.__mj_UpdatedAt) }}\n </div>\n <div class=\"list-col actions-col\" (click)=\"$event.stopPropagation()\">\n @if (CanEdit(dashboard.ID)) {\n <button\n class=\"action-btn\"\n title=\"Edit\"\n (click)=\"OnEditDashboard(dashboard, $event)\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n }\n @if (CanDelete(dashboard.ID)) {\n <button\n class=\"action-btn danger\"\n title=\"Delete\"\n (click)=\"OnDeleteDashboard(dashboard, $event)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (FilteredDashboards.length === 0 && FilteredChildCategories.length === 0 && !IsLoading) {\n <!-- First-time user experience (no dashboards at all) -->\n @if (IsAtRoot && Dashboards.length === 0) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Size=\"large\"\n Icon=\"fa-solid fa-gauge-high\"\n Title=\"Welcome to Dashboards\"\n Message=\"Create custom dashboards to visualize your data, track key metrics, and monitor important information all in one place.\"\n [ActionText]=\"ShowCreateButton ? 'Create Your First Dashboard' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnCreateDashboard()\">\n <div class=\"empty-features\">\n <div class=\"feature-item\">\n <i class=\"fa-solid fa-table-cells\"></i>\n <span>Customizable layouts</span>\n </div>\n <div class=\"feature-item\">\n <i class=\"fa-solid fa-database\"></i>\n <span>Connect to your data</span>\n </div>\n <div class=\"feature-item\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share with your team</span>\n </div>\n </div>\n </mj-empty-state>\n }\n <!-- Folder is empty -->\n @if (!IsAtRoot && !SearchText) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Variant=\"warning\"\n Icon=\"fa-solid fa-folder-open\"\n Title=\"This folder is empty\"\n Message=\"Add dashboards or create sub-folders to organize your content.\"\n [ActionText]=\"ShowCreateButton ? 'Create Dashboard' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnCreateDashboard()\" />\n }\n <!-- Root has dashboards but none uncategorized -->\n @if (IsAtRoot && Dashboards.length > 0 && !SearchText) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Icon=\"fa-solid fa-folder-tree\"\n Title=\"No uncategorized dashboards\"\n Message=\"All your dashboards are organized into folders. Browse the folders above or create a new dashboard here.\"\n [ActionText]=\"ShowCreateButton ? 'Create Dashboard' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnCreateDashboard()\" />\n }\n <!-- Search returned no results -->\n @if (SearchText) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No results found\"\n [Message]=\"NoResultsMessage\"\n ActionText=\"Clear Search\"\n ActionIcon=\"fa-solid fa-times\"\n ActionVariant=\"secondary\"\n (Action)=\"ClearSearch()\" />\n }\n }\n\n <!-- Category Drop Zones (for drag and drop) -->\n @if (DraggingId && Categories.length > 0) {\n <div class=\"category-drop-zones\">\n <div class=\"drop-zone-header\">Drop to move to category:</div>\n <div class=\"drop-zones\">\n <div\n class=\"drop-zone\"\n [class.active]=\"DropTargetCategoryId === null\"\n (dragover)=\"OnDragOverCategory(null, $event)\"\n (dragleave)=\"OnDragLeaveCategory()\"\n (drop)=\"OnDropOnCategory(null, $event)\">\n <i class=\"fa-solid fa-folder-open\"></i>\n Uncategorized\n </div>\n @for (cat of Categories; track TrackByCategory($index, cat)) {\n <div\n class=\"drop-zone\"\n [class.active]=\"DropTargetCategoryId === cat.ID\"\n (dragover)=\"OnDragOverCategory(cat.ID, $event)\"\n (dragleave)=\"OnDragLeaveCategory()\"\n (drop)=\"OnDropOnCategory(cat.ID, $event)\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ cat.Name }}\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Delete Confirmation Dialog -->\n <mj-confirm-dialog\n [visible]=\"ShowDeleteConfirm\"\n type=\"danger\"\n title=\"Delete Dashboard{{ DashboardsPendingDelete.length > 1 ? 's' : '' }}\"\n [message]=\"DashboardsPendingDelete.length === 1\n ? 'Are you sure you want to delete \\'' + DashboardsPendingDelete[0].Name + '\\'? This action cannot be undone.'\n : 'Are you sure you want to delete ' + DashboardsPendingDelete.length + ' dashboards? This action cannot be undone.'\"\n confirmText=\"Delete\"\n cancelText=\"Cancel\"\n (confirmed)=\"ConfirmDelete()\"\n (cancelled)=\"CloseDeleteConfirm()\">\n </mj-confirm-dialog>\n\n <!-- Move to Folder Dialog -->\n @if (ShowMoveDialog) {\n <div class=\"move-dialog-overlay\" (click)=\"CloseMoveDialog()\">\n <div class=\"move-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"dialog-header\">\n <h3>Move to Category</h3>\n <button class=\"close-btn\" (click)=\"CloseMoveDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"dialog-content\">\n <p>Move {{ SelectedCount }} dashboard{{ SelectedCount > 1 ? 's' : '' }} to:</p>\n <div class=\"category-list\">\n <div\n class=\"category-option\"\n (click)=\"ConfirmMove(null)\">\n <i class=\"fa-solid fa-folder-open\"></i>\n Uncategorized\n </div>\n @for (cat of Categories; track TrackByCategory($index, cat)) {\n <div\n class=\"category-option\"\n (click)=\"ConfirmMove(cat.ID)\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ cat.Name }}\n </div>\n }\n </div>\n </div>\n <div class=\"dialog-footer\">\n <button class=\"btn-secondary\" (click)=\"CloseMoveDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n\n <!-- Create Category Dialog -->\n @if (ShowCreateCategoryDialog) {\n <div class=\"create-category-dialog-overlay\" (click)=\"CloseCreateCategoryDialog()\">\n <div class=\"create-category-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"dialog-header\">\n <h3>\n <i class=\"fa-solid fa-folder-plus\"></i>\n Create Category\n </h3>\n <button class=\"close-btn\" (click)=\"CloseCreateCategoryDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"dialog-content\">\n <div class=\"form-field\">\n <label for=\"category-name\">Name *</label>\n <input\n type=\"text\"\n id=\"category-name\"\n [(ngModel)]=\"NewCategoryName\"\n placeholder=\"Enter category name\"\n (keyup.enter)=\"ConfirmCreateCategory()\">\n </div>\n <div class=\"form-field\">\n <label for=\"category-description\">Description</label>\n <textarea\n id=\"category-description\"\n [(ngModel)]=\"NewCategoryDescription\"\n placeholder=\"Optional description\"\n rows=\"3\"></textarea>\n </div>\n </div>\n <div class=\"dialog-footer\">\n <button\n class=\"btn-primary\"\n (click)=\"ConfirmCreateCategory()\"\n [disabled]=\"!NewCategoryName.trim()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create\n </button>\n <button class=\"btn-secondary\" (click)=\"CloseCreateCategoryDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n\n <!-- Delete Category Confirmation Dialog -->\n @if (ShowDeleteCategoryConfirm) {\n <div class=\"delete-category-dialog-overlay\" (click)=\"CloseDeleteCategoryConfirm()\">\n <div class=\"delete-category-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"dialog-header danger\">\n <h3>\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n Delete Category\n </h3>\n <button class=\"close-btn\" (click)=\"CloseDeleteCategoryConfirm()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n @if (CategoryPendingDelete) {\n <div class=\"dialog-content\">\n <div class=\"warning-message\">\n <p>\n You are about to delete the category <strong>\"{{ CategoryPendingDelete.Name }}\"</strong>.\n </p>\n @if (GetCategoryContentCount(CategoryPendingDelete); as counts) {\n @if (counts.dashboards > 0 || counts.categories > 0) {\n <p class=\"content-warning\">\n <i class=\"fa-solid fa-warning\"></i>\n This category contains:\n </p>\n }\n @if (counts.dashboards > 0 || counts.categories > 0) {\n <ul class=\"content-list\">\n @if (counts.dashboards > 0) {\n <li>\n <i class=\"fa-solid fa-chart-line\"></i>\n {{ counts.dashboards }} dashboard{{ counts.dashboards !== 1 ? 's' : '' }}\n </li>\n }\n @if (counts.categories > 0) {\n <li>\n <i class=\"fa-solid fa-folder\"></i>\n {{ counts.categories }} sub-categor{{ counts.categories !== 1 ? 'ies' : 'y' }}\n </li>\n }\n </ul>\n }\n }\n </div>\n <div class=\"confirmation-checkbox\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"DeleteCategoryIncludeContents\">\n <span class=\"checkbox-text\">\n I understand this will permanently delete this category and all its contents. This action cannot be undone.\n </span>\n </label>\n </div>\n </div>\n }\n <div class=\"dialog-footer\">\n <button\n class=\"btn-danger\"\n (click)=\"ConfirmDeleteCategory()\"\n [disabled]=\"!DeleteCategoryIncludeContents\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete Category\n </button>\n <button class=\"btn-secondary\" (click)=\"CloseDeleteCategoryConfirm()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: ["/* Dashboard Browser Component Styles */\n\n.dashboard-browser {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n position: relative;\n}\n\n/* Browser Toolbar */\n.browser-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 24px 0 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n}\n\n.toolbar-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-count {\n color: var(--mj-text-secondary);\n font-size: 13px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n}\n\n/* Legacy header styles (kept for compatibility) */\n.browser-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-left h2 {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.header-left h2 i {\n color: var(--mj-brand-primary);\n}\n\n.header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n}\n\n.toggle-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.toggle-btn:hover {\n color: var(--mj-text-primary);\n}\n\n.toggle-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* Selection Mode Button */\n.select-mode-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.select-mode-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.select-mode-btn i {\n font-size: 12px;\n}\n\n/* Selection Toolbar (replaces bulk-actions) */\n.selection-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 6px;\n}\n\n.selection-toolbar .action-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.selection-toolbar .action-btn:disabled:hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.selected-count {\n font-size: 13px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n min-width: 70px;\n}\n\n/* Buttons */\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-secondary:hover {\n background: var(--mj-border-default);\n}\n\n.action-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.action-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.action-btn.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n/* Filters */\n.browser-filters {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-box {\n display: flex;\n align-items: center;\n flex: 1;\n max-width: 400px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n padding: 0 12px;\n}\n\n.search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.search-box input {\n flex: 1;\n border: none;\n background: transparent;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n}\n\n.search-box .clear-btn {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n border-radius: 50%;\n}\n\n.search-box .clear-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.category-filter select {\n padding: 10px 32px 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n outline: none;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n}\n\n.clear-filters-btn,\n.select-all-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.clear-filters-btn:hover,\n.select-all-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Loading Overlay */\n.loading-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n/* Card Grid */\n.dashboard-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 24px;\n overflow-y: auto;\n}\n\n.dashboard-card {\n background: var(--mj-bg-surface);\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n cursor: pointer;\n transition: all 0.2s;\n border: 2px solid transparent;\n position: relative;\n}\n\n.dashboard-card:hover {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n transform: translateY(-2px);\n}\n\n.dashboard-card.selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.dashboard-card.dragging {\n opacity: 0.5;\n}\n\n.card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.card-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n}\n\n/* Selection area in top-right corner of card */\n.card-select-area {\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 2;\n padding: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s;\n}\n\n.card-select-area:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n}\n\n.dashboard-card.selected .card-select-area {\n background: var(--mj-brand-primary);\n}\n\n.card-select-area input {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n}\n\n.card-actions {\n display: flex;\n gap: 4px;\n margin-left: auto;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.dashboard-card:hover .card-actions {\n opacity: 1;\n}\n\n.card-content {\n padding: 16px;\n}\n\n.card-title {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* Shared Badge */\n.shared-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.card-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.card-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* List View */\n.dashboard-list {\n flex: 1;\n overflow-y: auto;\n background: var(--mj-bg-surface);\n margin: 16px 24px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.list-header {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.list-row {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.list-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.list-row.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.list-row.dragging {\n opacity: 0.5;\n}\n\n.list-col {\n display: flex;\n align-items: center;\n}\n\n.checkbox-col {\n width: 40px;\n}\n\n.checkbox-col input {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.name-col {\n flex: 1;\n min-width: 200px;\n gap: 10px;\n display: flex;\n align-items: center;\n}\n\n.name-col .shared-badge {\n margin-left: 4px;\n}\n\n.row-icon {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.dashboard-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.category-col,\n.type-col {\n width: 120px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.date-col {\n width: 120px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.actions-col {\n width: 80px;\n justify-content: flex-end;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.list-row:hover .actions-col {\n opacity: 1;\n}\n\n/* Empty State */\n/* Empty state fills the browser pane (flex-fill \u2014 mj-empty-state centers\n its content but does not grow on its own). */\n.dashboard-empty {\n flex: 1;\n min-height: 400px;\n}\n\n/* Feature highlights projected into the first-time onboarding empty state */\n.empty-features {\n display: flex;\n gap: 32px;\n margin-top: var(--mj-space-5);\n padding-top: 24px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.feature-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.feature-item i {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n/* Category Drop Zones */\n.category-drop-zones {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 1000;\n}\n\n.drop-zone-header {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n text-align: center;\n}\n\n.drop-zones {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n justify-content: center;\n}\n\n.drop-zone {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.drop-zone:hover,\n.drop-zone.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n}\n\n/* Move Dialog */\n.move-dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.move-dialog {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.dialog-header h3 {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.dialog-content {\n padding: 20px;\n overflow-y: auto;\n}\n\n.dialog-content p {\n margin: 0 0 16px 0;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.category-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.category-option {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.category-option:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.category-option i {\n color: var(--mj-brand-primary);\n}\n\n.dialog-footer {\n display: flex;\n justify-content: flex-end;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* New Dropdown */\n.new-dropdown {\n position: relative;\n}\n\n.dropdown-caret {\n font-size: 10px;\n margin-left: 4px;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n overflow: hidden;\n}\n\n.dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 12px 16px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 14px;\n cursor: pointer;\n text-align: left;\n transition: background 0.15s;\n}\n\n.dropdown-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.dropdown-item i {\n color: var(--mj-brand-primary);\n width: 16px;\n text-align: center;\n}\n\n.dropdown-backdrop {\n position: fixed;\n inset: 0;\n z-index: 1000;\n}\n\n/* Create Category Dialog */\n.create-category-dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.create-category-dialog {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.create-category-dialog .dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog .dialog-header h3 {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.create-category-dialog .dialog-header h3 i {\n color: var(--mj-brand-primary);\n}\n\n.create-category-dialog .dialog-content {\n padding: 20px;\n}\n\n.form-field {\n margin-bottom: 16px;\n}\n\n.form-field:last-child {\n margin-bottom: 0;\n}\n\n.form-field label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-field input,\n.form-field textarea {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s, box-shadow 0.15s;\n box-sizing: border-box;\n}\n\n.form-field input:focus,\n.form-field textarea:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.form-field textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n.create-category-dialog .dialog-footer {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog .dialog-footer .btn-primary {\n flex: 0 0 auto;\n}\n\n.create-category-dialog .dialog-footer .btn-secondary {\n flex: 0 0 auto;\n margin-left: auto;\n}\n\n/* Breadcrumb Navigation */\n.breadcrumb-nav {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-wrap: wrap;\n}\n\n.breadcrumb-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s;\n}\n\n.breadcrumb-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.breadcrumb-item.current {\n color: var(--mj-text-primary);\n font-weight: 500;\n cursor: default;\n}\n\n.breadcrumb-item.current:hover {\n background: transparent;\n}\n\n.breadcrumb-item i {\n font-size: 12px;\n}\n\n.breadcrumb-item.root i {\n font-size: 14px;\n}\n\n.breadcrumb-separator {\n color: var(--mj-text-disabled);\n font-size: 10px;\n}\n\n/* Category Cards */\n.category-card {\n cursor: pointer;\n}\n\n.category-card:hover {\n border-color: var(--mj-brand-primary);\n}\n\n.folder-icon {\n background: var(--mj-status-warning) !important;\n}\n\n.category-row {\n background: var(--mj-bg-surface-card);\n}\n\n.category-row:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface)) !important;\n}\n\n.category-row .folder-icon {\n color: var(--mj-status-warning);\n}\n\n/* Drop target highlighting for category cards/rows */\n.dashboard-card.category-card.drop-target,\n.list-row.category-row.drop-target {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Search text highlighting */\nmark {\n background: var(--mj-status-warning);\n color: inherit;\n padding: 0 2px;\n border-radius: 2px;\n}\n\n/* Delete Category Dialog */\n.delete-category-dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.delete-category-dialog {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 480px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.delete-category-dialog .dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.delete-category-dialog .dialog-header.danger {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-bottom-color: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.delete-category-dialog .dialog-header.danger h3 {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog .dialog-header.danger h3 i {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog .dialog-header h3 {\n margin: 0;\n font-size: 18px;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.delete-category-dialog .dialog-content {\n padding: 20px;\n}\n\n.warning-message {\n margin-bottom: 20px;\n}\n\n.warning-message p {\n margin: 0 0 12px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n}\n\n.warning-message .content-warning {\n color: var(--mj-status-error);\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 16px;\n}\n\n.warning-message .content-list {\n margin: 8px 0 0 0;\n padding-left: 24px;\n color: var(--mj-text-secondary);\n}\n\n.warning-message .content-list li {\n margin: 6px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.warning-message .content-list li i {\n color: var(--mj-text-disabled);\n width: 16px;\n text-align: center;\n}\n\n.confirmation-checkbox {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 8px;\n padding: 16px;\n}\n\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label input {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n accent-color: var(--mj-status-error);\n}\n\n.checkbox-text {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.delete-category-dialog .dialog-footer {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.btn-danger {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 85%, black);\n}\n\n.btn-danger:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-disabled);\n cursor: not-allowed;\n}\n\n.delete-category-dialog .dialog-footer .btn-secondary {\n margin-left: auto;\n}\n"] }]
1729
- }], () => [{ type: i0.ChangeDetectorRef }], { Dashboards: [{
1709
+ args: [{ standalone: false, selector: 'mj-dashboard-browser', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Dashboard Browser Component -->\n<div class=\"dashboard-browser\" [class.loading]=\"IsLoading\">\n <!-- Toolbar Row: Breadcrumb + Actions -->\n <div class=\"browser-toolbar\">\n <!-- Breadcrumb Navigation -->\n <mj-dashboard-breadcrumb\n [Categories]=\"Categories\"\n [CurrentCategoryId]=\"FlatMode ? null : SelectedCategoryId\"\n [RootIcon]=\"IconClass\"\n [RootLabel]=\"Title\"\n [AllowDragDrop]=\"AllowDragDrop && (DraggingId !== null || IsSelectionMode)\"\n Size=\"large\"\n (Navigate)=\"NavigateToCategory($event.CategoryId)\"\n (DashboardDrop)=\"OnBreadcrumbDrop($event)\">\n </mj-dashboard-breadcrumb>\n\n <!-- Right-side Actions -->\n <div class=\"toolbar-actions\">\n <!-- Dashboard count -->\n <span class=\"dashboard-count\">{{ FilteredDashboards.length }} dashboards</span>\n\n <!-- View Toggle -->\n <div class=\"view-toggle\">\n <button\n class=\"toggle-btn\"\n [class.active]=\"ViewMode === 'cards'\"\n (click)=\"SetViewMode('cards')\"\n title=\"Card View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button\n class=\"toggle-btn\"\n [class.active]=\"ViewMode === 'list'\"\n (click)=\"SetViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n\n <!-- Selection Mode Toggle & Bulk Actions -->\n @if (AllowMultiSelect) {\n <!-- Enter Selection Mode Button (when not in selection mode) -->\n @if (!IsSelectionMode && FilteredDashboards.length > 0) {\n <button\n class=\"select-mode-btn\"\n (click)=\"EnterSelectionMode()\"\n title=\"Select multiple dashboards\">\n <i class=\"fa-solid fa-check-double\"></i>\n Select\n </button>\n }\n <!-- Selection Mode Toolbar (when in selection mode) -->\n @if (IsSelectionMode) {\n <div class=\"selection-toolbar\">\n <span class=\"selected-count\">{{ SelectedCount }} selected</span>\n <button class=\"action-btn\" (click)=\"SelectAll()\" title=\"Select all\">\n <i class=\"fa-solid fa-check-double\"></i>\n </button>\n <button class=\"action-btn\" (click)=\"OnMoveSelected()\" title=\"Move to folder\" [disabled]=\"SelectedCount === 0\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </button>\n <button class=\"action-btn danger\" (click)=\"OnDeleteSelected()\" title=\"Delete selected\" [disabled]=\"!CanDeleteAnySelected\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n <button class=\"action-btn\" (click)=\"ExitSelectionMode()\" title=\"Exit selection mode\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n }\n\n <!-- New Dropdown Button -->\n @if (ShowCreateButton) {\n <div class=\"new-dropdown\">\n <button\n class=\"btn-primary\"\n (click)=\"ToggleNewMenu(); $event.stopPropagation()\">\n <i class=\"fa-solid fa-plus\"></i>\n New\n <i class=\"fa-solid fa-caret-down dropdown-caret\"></i>\n </button>\n @if (ShowNewMenu) {\n <div class=\"dropdown-menu\">\n <button class=\"dropdown-item\" (click)=\"OnCreateDashboard()\">\n <i class=\"fa-solid fa-chart-line\"></i>\n Dashboard\n </button>\n <button class=\"dropdown-item\" (click)=\"OpenCreateCategoryDialog()\">\n <i class=\"fa-solid fa-folder-plus\"></i>\n Category\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Click-away overlay for dropdown -->\n @if (ShowNewMenu) {\n <div class=\"dropdown-backdrop\" (click)=\"CloseNewMenu()\"></div>\n }\n\n <!-- Filters -->\n <div class=\"browser-filters\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-search\"></i>\n <input\n type=\"text\"\n [(ngModel)]=\"SearchText\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search dashboards...\">\n @if (SearchText) {\n <button\n class=\"clear-btn\"\n (click)=\"ClearSearch()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n\n @if (SearchText) {\n <button\n class=\"clear-filters-btn\"\n (click)=\"ClearSearch()\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n Clear Search\n </button>\n }\n </div>\n\n <!-- Loading Overlay -->\n @if (IsLoading) {\n <div class=\"loading-overlay\">\n <mj-loading text=\"Loading dashboards...\"></mj-loading>\n </div>\n }\n\n <!-- Card View -->\n @if (ViewMode === 'cards' && (FilteredChildCategories.length > 0 || FilteredDashboards.length > 0)) {\n <div class=\"dashboard-grid\">\n <!-- Category Folders -->\n @for (category of FilteredChildCategories; track TrackByCategory($index, category)) {\n <div\n class=\"dashboard-card category-card\"\n [class.drop-target]=\"DragOverChildCategoryId === category.ID\"\n (click)=\"NavigateToCategory(category.ID)\"\n (dblclick)=\"$event.stopPropagation()\"\n (dragover)=\"OnDragOverChildCategory(category.ID, $event)\"\n (dragleave)=\"OnDragLeaveChildCategory()\"\n (drop)=\"OnDropOnChildCategory(category.ID, $event)\">\n <div class=\"card-header\">\n <div class=\"card-icon folder-icon\">\n <i class=\"fa-solid fa-folder\"></i>\n </div>\n <div class=\"card-actions\">\n <button\n class=\"action-btn danger\"\n title=\"Delete category\"\n (click)=\"OnDeleteCategory(category, $event)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n <div class=\"card-content\">\n <h3 class=\"card-title\" [innerHTML]=\"HighlightMatch(category.Name)\"></h3>\n @if (category.Description) {\n <p class=\"card-description\" [innerHTML]=\"HighlightMatch(category.Description)\">\n </p>\n }\n <div class=\"card-meta\">\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-folder-tree\"></i>\n Category\n </span>\n </div>\n </div>\n </div>\n }\n <!-- Dashboard Cards -->\n @for (dashboard of FilteredDashboards; track TrackByDashboard($index, dashboard)) {\n <mj-dashboard-card\n class=\"dashboard-card-host\"\n [class.dragging]=\"DraggingId === dashboard.ID\"\n [draggable]=\"AllowDragDrop\"\n [Dashboard]=\"dashboard\"\n [IsFavorite]=\"IsFavorite(dashboard.ID)\"\n [ShowFavorite]=\"ShowFavorites\"\n [IsShared]=\"IsShared(dashboard.ID)\"\n [OwnerLabel]=\"OwnerLabel(dashboard)\"\n [CategoryPath]=\"CardCategoryPath(dashboard)\"\n [HighlightQuery]=\"SearchText\"\n [Selectable]=\"IsSelectionMode\"\n [Selected]=\"IsSelected(dashboard.ID)\"\n [CanEdit]=\"CanEdit(dashboard.ID)\"\n [CanDelete]=\"CanDelete(dashboard.ID)\"\n (CardClick)=\"OnDashboardClick(dashboard, $event.MouseEvent)\"\n (CardDoubleClick)=\"OnDashboardDoubleClick(dashboard, $event.MouseEvent)\"\n (ToggleFavorite)=\"OnToggleFavorite(dashboard)\"\n (SelectionToggle)=\"ToggleSelection(dashboard.ID)\"\n (Edit)=\"OnEditDashboard(dashboard)\"\n (Delete)=\"OnDeleteDashboard(dashboard)\"\n (dragstart)=\"OnDragStart(dashboard, $event)\"\n (dragend)=\"OnDragEnd()\">\n </mj-dashboard-card>\n }\n </div>\n }\n\n <!-- List View -->\n @if (ViewMode === 'list' && (FilteredChildCategories.length > 0 || FilteredDashboards.length > 0)) {\n <div class=\"dashboard-list\">\n <div class=\"list-header\">\n @if (IsSelectionMode) {\n <div class=\"list-col checkbox-col\">\n <input\n type=\"checkbox\"\n [checked]=\"SelectedCount === FilteredDashboards.length && FilteredDashboards.length > 0\"\n [indeterminate]=\"SelectedCount > 0 && SelectedCount < FilteredDashboards.length\"\n (change)=\"SelectedCount === FilteredDashboards.length ? ClearSelection() : SelectAll()\">\n </div>\n }\n <div class=\"list-col name-col\">Name</div>\n <div class=\"list-col type-col\">Type</div>\n <div class=\"list-col date-col\">Modified</div>\n <div class=\"list-col actions-col\">Actions</div>\n </div>\n <!-- Category Rows -->\n @for (category of FilteredChildCategories; track TrackByCategory($index, category)) {\n <div\n class=\"list-row category-row\"\n [class.drop-target]=\"DragOverChildCategoryId === category.ID\"\n (click)=\"NavigateToCategory(category.ID)\"\n (dragover)=\"OnDragOverChildCategory(category.ID, $event)\"\n (dragleave)=\"OnDragLeaveChildCategory()\"\n (drop)=\"OnDropOnChildCategory(category.ID, $event)\">\n @if (IsSelectionMode) {\n <div class=\"list-col checkbox-col\">\n <!-- Empty placeholder for alignment -->\n </div>\n }\n <div class=\"list-col name-col\">\n <i class=\"fa-solid fa-folder row-icon folder-icon\"></i>\n <span class=\"dashboard-name\" [innerHTML]=\"HighlightMatch(category.Name)\"></span>\n </div>\n <div class=\"list-col type-col\">\n Category\n </div>\n <div class=\"list-col date-col\">\n <!-- No date for categories -->\n </div>\n <div class=\"list-col actions-col\" (click)=\"$event.stopPropagation()\">\n <button\n class=\"action-btn danger\"\n title=\"Delete category\"\n (click)=\"OnDeleteCategory(category, $event)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n }\n <!-- Dashboard Rows -->\n @for (dashboard of FilteredDashboards; track TrackByDashboard($index, dashboard)) {\n <div\n class=\"list-row\"\n [class.selected]=\"IsSelected(dashboard.ID)\"\n [class.dragging]=\"DraggingId === dashboard.ID\"\n [draggable]=\"AllowDragDrop\"\n (click)=\"OnDashboardClick(dashboard, $event)\"\n (dblclick)=\"OnDashboardDoubleClick(dashboard, $event)\"\n (dragstart)=\"OnDragStart(dashboard, $event)\"\n (dragend)=\"OnDragEnd()\">\n @if (IsSelectionMode) {\n <div class=\"list-col checkbox-col\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n [checked]=\"IsSelected(dashboard.ID)\"\n (change)=\"ToggleSelection(dashboard.ID)\">\n </div>\n }\n <div class=\"list-col name-col\">\n <i class=\"fa-solid fa-chart-line row-icon\"></i>\n <span class=\"dashboard-name\" [innerHTML]=\"HighlightMatch(dashboard.Name)\"></span>\n @if (IsShared(dashboard.ID)) {\n <span class=\"shared-badge\" title=\"Shared with you\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n </span>\n }\n </div>\n <div class=\"list-col type-col\">\n Dashboard\n </div>\n <div class=\"list-col date-col\">\n {{ FormatDate(dashboard.__mj_UpdatedAt) }}\n </div>\n <div class=\"list-col actions-col\" (click)=\"$event.stopPropagation()\">\n @if (CanEdit(dashboard.ID)) {\n <button\n class=\"action-btn\"\n title=\"Edit\"\n (click)=\"OnEditDashboard(dashboard, $event)\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n }\n @if (CanDelete(dashboard.ID)) {\n <button\n class=\"action-btn danger\"\n title=\"Delete\"\n (click)=\"OnDeleteDashboard(dashboard, $event)\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (FilteredDashboards.length === 0 && FilteredChildCategories.length === 0 && !IsLoading) {\n <!-- First-time user experience: no dashboards at all, or a flat list whose host asks for it -->\n @if (ShowWelcome) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Size=\"large\"\n Icon=\"fa-solid fa-gauge-high\"\n Title=\"Welcome to Dashboards\"\n Message=\"Create custom dashboards to visualize your data, track key metrics, and monitor important information all in one place.\"\n [ActionText]=\"ShowCreateButton ? 'Create Your First Dashboard' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnCreateDashboard()\">\n <div class=\"empty-features\">\n <div class=\"feature-item\">\n <i class=\"fa-solid fa-table-cells\"></i>\n <span>Customizable layouts</span>\n </div>\n <div class=\"feature-item\">\n <i class=\"fa-solid fa-database\"></i>\n <span>Connect to your data</span>\n </div>\n <div class=\"feature-item\">\n <i class=\"fa-solid fa-share-nodes\"></i>\n <span>Share with your team</span>\n </div>\n </div>\n </mj-empty-state>\n }\n @if (FlatMode) {\n <!-- Flat list has nothing to show: the host's empty state -->\n @if (!SearchText && !FlatEmptyWelcome) {\n <mj-empty-state\n class=\"dashboard-empty\"\n [Icon]=\"FlatEmptyIcon\"\n [Title]=\"FlatEmptyTitle\"\n [Message]=\"FlatEmptyMessage\" />\n }\n } @else {\n <!-- Folder is empty -->\n @if (!IsAtRoot && !SearchText) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Variant=\"warning\"\n Icon=\"fa-solid fa-folder-open\"\n Title=\"This folder is empty\"\n Message=\"Add dashboards or create sub-folders to organize your content.\"\n [ActionText]=\"ShowCreateButton ? 'Create Dashboard' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnCreateDashboard()\" />\n }\n <!-- Root has dashboards but none uncategorized -->\n @if (IsAtRoot && Dashboards.length > 0 && !SearchText) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Icon=\"fa-solid fa-folder-tree\"\n Title=\"No uncategorized dashboards\"\n Message=\"All your dashboards are organized into folders. Browse the folders above or create a new dashboard here.\"\n [ActionText]=\"ShowCreateButton ? 'Create Dashboard' : ''\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"OnCreateDashboard()\" />\n }\n }\n <!-- Search returned no results -->\n @if (SearchText) {\n <mj-empty-state\n class=\"dashboard-empty\"\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No results found\"\n [Message]=\"NoResultsMessage\"\n ActionText=\"Clear Search\"\n ActionIcon=\"fa-solid fa-times\"\n ActionVariant=\"secondary\"\n (Action)=\"ClearSearch()\" />\n }\n }\n\n <!-- Category Drop Zones (for drag and drop) -->\n @if (DraggingId && Categories.length > 0) {\n <div class=\"category-drop-zones\">\n <div class=\"drop-zone-header\">Drop to move to category:</div>\n <div class=\"drop-zones\">\n <div\n class=\"drop-zone\"\n [class.active]=\"DropTargetCategoryId === null\"\n (dragover)=\"OnDragOverCategory(null, $event)\"\n (dragleave)=\"OnDragLeaveCategory()\"\n (drop)=\"OnDropOnCategory(null, $event)\">\n <i class=\"fa-solid fa-folder-open\"></i>\n Uncategorized\n </div>\n @for (cat of Categories; track TrackByCategory($index, cat)) {\n <div\n class=\"drop-zone\"\n [class.active]=\"DropTargetCategoryId === cat.ID\"\n (dragover)=\"OnDragOverCategory(cat.ID, $event)\"\n (dragleave)=\"OnDragLeaveCategory()\"\n (drop)=\"OnDropOnCategory(cat.ID, $event)\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ cat.Name }}\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Move to Folder Dialog -->\n @if (ShowMoveDialog) {\n <div class=\"move-dialog-overlay\" (click)=\"CloseMoveDialog()\">\n <div class=\"move-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"dialog-header\">\n <h3>Move to Category</h3>\n <button class=\"close-btn\" (click)=\"CloseMoveDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"dialog-content\">\n <p>Move {{ SelectedCount }} dashboard{{ SelectedCount > 1 ? 's' : '' }} to:</p>\n <div class=\"category-list\">\n <div\n class=\"category-option\"\n (click)=\"ConfirmMove(null)\">\n <i class=\"fa-solid fa-folder-open\"></i>\n Uncategorized\n </div>\n @for (cat of Categories; track TrackByCategory($index, cat)) {\n <div\n class=\"category-option\"\n (click)=\"ConfirmMove(cat.ID)\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ cat.Name }}\n </div>\n }\n </div>\n </div>\n <div class=\"dialog-footer\">\n <button class=\"btn-secondary\" (click)=\"CloseMoveDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n\n <!-- Create Category Dialog -->\n @if (ShowCreateCategoryDialog) {\n <div class=\"create-category-dialog-overlay\" (click)=\"CloseCreateCategoryDialog()\">\n <div class=\"create-category-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"dialog-header\">\n <h3>\n <i class=\"fa-solid fa-folder-plus\"></i>\n Create Category\n </h3>\n <button class=\"close-btn\" (click)=\"CloseCreateCategoryDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"dialog-content\">\n <div class=\"form-field\">\n <label for=\"category-name\">Name *</label>\n <input\n type=\"text\"\n id=\"category-name\"\n [(ngModel)]=\"NewCategoryName\"\n placeholder=\"Enter category name\"\n (keyup.enter)=\"ConfirmCreateCategory()\">\n </div>\n <div class=\"form-field\">\n <label for=\"category-description\">Description</label>\n <textarea\n id=\"category-description\"\n [(ngModel)]=\"NewCategoryDescription\"\n placeholder=\"Optional description\"\n rows=\"3\"></textarea>\n </div>\n </div>\n <div class=\"dialog-footer\">\n <button\n class=\"btn-primary\"\n (click)=\"ConfirmCreateCategory()\"\n [disabled]=\"!NewCategoryName.trim()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create\n </button>\n <button class=\"btn-secondary\" (click)=\"CloseCreateCategoryDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n\n <!-- Delete Category Confirmation Dialog -->\n @if (ShowDeleteCategoryConfirm) {\n <div class=\"delete-category-dialog-overlay\" (click)=\"CloseDeleteCategoryConfirm()\">\n <div class=\"delete-category-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"dialog-header danger\">\n <h3>\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n Delete Category\n </h3>\n <button class=\"close-btn\" (click)=\"CloseDeleteCategoryConfirm()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n @if (CategoryPendingDelete) {\n <div class=\"dialog-content\">\n <div class=\"warning-message\">\n <p>\n You are about to delete the category <strong>\"{{ CategoryPendingDelete.Name }}\"</strong>.\n </p>\n @if (GetCategoryContentCount(CategoryPendingDelete); as counts) {\n @if (counts.dashboards > 0 || counts.categories > 0) {\n <p class=\"content-warning\">\n <i class=\"fa-solid fa-warning\"></i>\n This category contains:\n </p>\n }\n @if (counts.dashboards > 0 || counts.categories > 0) {\n <ul class=\"content-list\">\n @if (counts.dashboards > 0) {\n <li>\n <i class=\"fa-solid fa-chart-line\"></i>\n {{ counts.dashboards }} dashboard{{ counts.dashboards !== 1 ? 's' : '' }}\n </li>\n }\n @if (counts.categories > 0) {\n <li>\n <i class=\"fa-solid fa-folder\"></i>\n {{ counts.categories }} sub-categor{{ counts.categories !== 1 ? 'ies' : 'y' }}\n </li>\n }\n </ul>\n }\n }\n </div>\n <div class=\"confirmation-checkbox\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n [(ngModel)]=\"DeleteCategoryIncludeContents\">\n <span class=\"checkbox-text\">\n I understand this will permanently delete this category and all its contents. This action cannot be undone.\n </span>\n </label>\n </div>\n </div>\n }\n <div class=\"dialog-footer\">\n <button\n class=\"btn-danger\"\n (click)=\"ConfirmDeleteCategory()\"\n [disabled]=\"!DeleteCategoryIncludeContents\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete Category\n </button>\n <button class=\"btn-secondary\" (click)=\"CloseDeleteCategoryConfirm()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: ["/* Dashboard Browser Component Styles */\n\n.dashboard-browser {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-page);\n position: relative;\n}\n\n/* Browser Toolbar */\n.browser-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 24px 0 0;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 16px;\n}\n\n.toolbar-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-count {\n color: var(--mj-text-secondary);\n font-size: 13px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n}\n\n/* Legacy header styles (kept for compatibility) */\n.browser-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.header-left {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.header-left h2 {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.header-left h2 i {\n color: var(--mj-brand-primary);\n}\n\n.header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: 6px;\n padding: 2px;\n}\n\n.toggle-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.toggle-btn:hover {\n color: var(--mj-text-primary);\n}\n\n.toggle-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n/* Selection Mode Button */\n.select-mode-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border: none;\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.select-mode-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.select-mode-btn i {\n font-size: 12px;\n}\n\n/* Selection Toolbar (replaces bulk-actions) */\n.selection-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-radius: 6px;\n}\n\n.selection-toolbar .action-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.selection-toolbar .action-btn:disabled:hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.selected-count {\n font-size: 13px;\n color: var(--mj-brand-primary);\n font-weight: 500;\n min-width: 70px;\n}\n\n/* Buttons */\n.btn-primary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-secondary:hover {\n background: var(--mj-border-default);\n}\n\n.action-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.action-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.action-btn.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n/* Filters */\n.browser-filters {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-box {\n display: flex;\n align-items: center;\n flex: 1;\n max-width: 400px;\n background: var(--mj-bg-surface-card);\n border-radius: 6px;\n padding: 0 12px;\n}\n\n.search-box i {\n color: var(--mj-text-disabled);\n font-size: 14px;\n}\n\n.search-box input {\n flex: 1;\n border: none;\n background: transparent;\n padding: 10px 12px;\n font-size: 14px;\n outline: none;\n}\n\n.search-box .clear-btn {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-disabled);\n cursor: pointer;\n border-radius: 50%;\n}\n\n.search-box .clear-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.category-filter select {\n padding: 10px 32px 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n outline: none;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 10px center;\n}\n\n.clear-filters-btn,\n.select-all-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: all 0.15s;\n}\n\n.clear-filters-btn:hover,\n.select-all-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* Loading Overlay */\n.loading-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 90%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n}\n\n/* Card Grid */\n.dashboard-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 20px;\n padding: 24px;\n overflow-y: auto;\n}\n\n/* Folder cards: the same frame as the dashboard cards (mj-dashboard-card) */\n.dashboard-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition:\n border-color var(--mj-transition-fast),\n box-shadow var(--mj-transition-fast),\n transform var(--mj-transition-fast);\n position: relative;\n}\n\n.dashboard-card:hover {\n border-color: var(--mj-border-strong);\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dashboard-card {\n transition: none;\n }\n\n .dashboard-card:hover {\n transform: none;\n }\n}\n\n/* A dashboard card being dragged */\n.dashboard-card-host.dragging {\n opacity: 0.5;\n}\n\n.card-header {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.card-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 8px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n}\n\n.card-actions {\n display: flex;\n gap: 4px;\n margin-left: auto;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.dashboard-card:hover .card-actions {\n opacity: 1;\n}\n\n.card-content {\n padding: 16px;\n}\n\n.card-title {\n margin: 0 0 8px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* Shared Badge */\n.shared-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 10px;\n flex-shrink: 0;\n}\n\n.card-description {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.card-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--mj-text-disabled);\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n/* List View */\n.dashboard-list {\n flex: 1;\n overflow-y: auto;\n background: var(--mj-bg-surface);\n margin: 16px 24px;\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n}\n\n.list-header {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.list-row {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.list-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.list-row.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.list-row.dragging {\n opacity: 0.5;\n}\n\n.list-col {\n display: flex;\n align-items: center;\n}\n\n.checkbox-col {\n width: 40px;\n}\n\n.checkbox-col input {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.name-col {\n flex: 1;\n min-width: 200px;\n gap: 10px;\n display: flex;\n align-items: center;\n}\n\n.name-col .shared-badge {\n margin-left: 4px;\n}\n\n.row-icon {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.dashboard-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.category-col,\n.type-col {\n width: 120px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.date-col {\n width: 120px;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n.actions-col {\n width: 80px;\n justify-content: flex-end;\n gap: 4px;\n opacity: 0;\n transition: opacity 0.15s;\n}\n\n.list-row:hover .actions-col {\n opacity: 1;\n}\n\n/* Empty State */\n/* Empty state fills the browser pane (flex-fill \u2014 mj-empty-state centers\n its content but does not grow on its own). */\n.dashboard-empty {\n flex: 1;\n min-height: 400px;\n}\n\n/* Feature highlights projected into the first-time onboarding empty state */\n.empty-features {\n display: flex;\n gap: 32px;\n margin-top: var(--mj-space-5);\n padding-top: 24px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.feature-item {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-secondary);\n font-size: 13px;\n}\n\n.feature-item i {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n color: var(--mj-brand-primary);\n font-size: 16px;\n}\n\n/* Category Drop Zones */\n.category-drop-zones {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n padding: 16px;\n z-index: 1000;\n}\n\n.drop-zone-header {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-bottom: 12px;\n text-align: center;\n}\n\n.drop-zones {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n justify-content: center;\n}\n\n.drop-zone {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-bg-surface-card);\n border: 2px dashed var(--mj-border-strong);\n border-radius: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.drop-zone:hover,\n.drop-zone.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n}\n\n/* Move Dialog */\n.move-dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.move-dialog {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.dialog-header h3 {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n}\n\n.close-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 4px;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.dialog-content {\n padding: 20px;\n overflow-y: auto;\n}\n\n.dialog-content p {\n margin: 0 0 16px 0;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.category-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.category-option {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 6px;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.category-option:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.category-option i {\n color: var(--mj-brand-primary);\n}\n\n.dialog-footer {\n display: flex;\n justify-content: flex-end;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n/* New Dropdown */\n.new-dropdown {\n position: relative;\n}\n\n.dropdown-caret {\n font-size: 10px;\n margin-left: 4px;\n}\n\n.dropdown-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 4px;\n min-width: 160px;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n overflow: hidden;\n}\n\n.dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 12px 16px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 14px;\n cursor: pointer;\n text-align: left;\n transition: background 0.15s;\n}\n\n.dropdown-item:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.dropdown-item i {\n color: var(--mj-brand-primary);\n width: 16px;\n text-align: center;\n}\n\n.dropdown-backdrop {\n position: fixed;\n inset: 0;\n z-index: 1000;\n}\n\n/* Create Category Dialog */\n.create-category-dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.create-category-dialog {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 400px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.create-category-dialog .dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog .dialog-header h3 {\n margin: 0;\n font-size: 18px;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.create-category-dialog .dialog-header h3 i {\n color: var(--mj-brand-primary);\n}\n\n.create-category-dialog .dialog-content {\n padding: 20px;\n}\n\n.form-field {\n margin-bottom: 16px;\n}\n\n.form-field:last-child {\n margin-bottom: 0;\n}\n\n.form-field label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-field input,\n.form-field textarea {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n transition: border-color 0.15s, box-shadow 0.15s;\n box-sizing: border-box;\n}\n\n.form-field input:focus,\n.form-field textarea:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.form-field textarea {\n resize: vertical;\n min-height: 80px;\n}\n\n.create-category-dialog .dialog-footer {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.create-category-dialog .dialog-footer .btn-primary {\n flex: 0 0 auto;\n}\n\n.create-category-dialog .dialog-footer .btn-secondary {\n flex: 0 0 auto;\n margin-left: auto;\n}\n\n/* Breadcrumb Navigation */\n.breadcrumb-nav {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-wrap: wrap;\n}\n\n.breadcrumb-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 13px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s;\n}\n\n.breadcrumb-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.breadcrumb-item.current {\n color: var(--mj-text-primary);\n font-weight: 500;\n cursor: default;\n}\n\n.breadcrumb-item.current:hover {\n background: transparent;\n}\n\n.breadcrumb-item i {\n font-size: 12px;\n}\n\n.breadcrumb-item.root i {\n font-size: 14px;\n}\n\n.breadcrumb-separator {\n color: var(--mj-text-disabled);\n font-size: 10px;\n}\n\n/* Category Cards */\n.category-card {\n cursor: pointer;\n}\n\n.category-card:hover {\n border-color: var(--mj-brand-primary);\n}\n\n.folder-icon {\n background: var(--mj-status-warning) !important;\n}\n\n.category-row {\n background: var(--mj-bg-surface-card);\n}\n\n.category-row:hover {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface)) !important;\n}\n\n.category-row .folder-icon {\n color: var(--mj-status-warning);\n}\n\n/* Drop target highlighting for category cards/rows */\n.dashboard-card.category-card.drop-target,\n.list-row.category-row.drop-target {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Search text highlighting in folder cards and list rows. The marks come from innerHTML and get no\n _ngcontent attribute, so they are reached through ::ng-deep under the host; the dashboard card\n styles its own marks the same way. */\n:host ::ng-deep mark {\n background: color-mix(in srgb, var(--mj-status-warning) 35%, transparent);\n color: inherit;\n border-radius: 2px;\n padding: 0 1px;\n}\n\n/* Delete Category Dialog */\n.delete-category-dialog-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1002;\n}\n\n.delete-category-dialog {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n width: 480px;\n max-width: 90%;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n}\n\n.delete-category-dialog .dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.delete-category-dialog .dialog-header.danger {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-bottom-color: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.delete-category-dialog .dialog-header.danger h3 {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog .dialog-header.danger h3 i {\n color: var(--mj-status-error);\n}\n\n.delete-category-dialog .dialog-header h3 {\n margin: 0;\n font-size: 18px;\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.delete-category-dialog .dialog-content {\n padding: 20px;\n}\n\n.warning-message {\n margin-bottom: 20px;\n}\n\n.warning-message p {\n margin: 0 0 12px 0;\n color: var(--mj-text-primary);\n font-size: 14px;\n line-height: 1.5;\n}\n\n.warning-message .content-warning {\n color: var(--mj-status-error);\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 16px;\n}\n\n.warning-message .content-list {\n margin: 8px 0 0 0;\n padding-left: 24px;\n color: var(--mj-text-secondary);\n}\n\n.warning-message .content-list li {\n margin: 6px 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.warning-message .content-list li i {\n color: var(--mj-text-disabled);\n width: 16px;\n text-align: center;\n}\n\n.confirmation-checkbox {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 40%, var(--mj-bg-surface));\n border-radius: 8px;\n padding: 16px;\n}\n\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n}\n\n.checkbox-label input {\n width: 18px;\n height: 18px;\n margin-top: 2px;\n cursor: pointer;\n accent-color: var(--mj-status-error);\n}\n\n.checkbox-text {\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.delete-category-dialog .dialog-footer {\n display: flex;\n gap: 10px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.btn-danger {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 16px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.btn-danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 85%, black);\n}\n\n.btn-danger:disabled {\n background: var(--mj-border-default);\n color: var(--mj-text-disabled);\n cursor: not-allowed;\n}\n\n.delete-category-dialog .dialog-footer .btn-secondary {\n margin-left: auto;\n}\n"] }]
1710
+ }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MJConfirmService }], { Dashboards: [{
1730
1711
  type: Input
1731
1712
  }], Categories: [{
1732
1713
  type: Input
1733
1714
  }], SelectedCategoryId: [{
1734
1715
  type: Input
1716
+ }], FlatMode: [{
1717
+ type: Input
1735
1718
  }], ViewMode: [{
1736
1719
  type: Input
1737
1720
  }], IsLoading: [{
@@ -1750,6 +1733,20 @@ export class DashboardBrowserComponent {
1750
1733
  type: Input
1751
1734
  }], EffectiveCategoryMap: [{
1752
1735
  type: Input
1736
+ }], FavoriteIds: [{
1737
+ type: Input
1738
+ }], ShowFavorites: [{
1739
+ type: Input
1740
+ }], OwnerLabels: [{
1741
+ type: Input
1742
+ }], FlatEmptyIcon: [{
1743
+ type: Input
1744
+ }], FlatEmptyTitle: [{
1745
+ type: Input
1746
+ }], FlatEmptyMessage: [{
1747
+ type: Input
1748
+ }], FlatEmptyWelcome: [{
1749
+ type: Input
1753
1750
  }], DashboardOpen: [{
1754
1751
  type: Output
1755
1752
  }], DashboardEdit: [{
@@ -1770,6 +1767,8 @@ export class DashboardBrowserComponent {
1770
1767
  type: Output
1771
1768
  }], ViewPreferenceChange: [{
1772
1769
  type: Output
1770
+ }], DashboardFavoriteToggle: [{
1771
+ type: Output
1773
1772
  }] }); })();
1774
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(DashboardBrowserComponent, { className: "DashboardBrowserComponent", filePath: "src/lib/dashboard-browser/dashboard-browser.component.ts", lineNumber: 114 }); })();
1773
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(DashboardBrowserComponent, { className: "DashboardBrowserComponent", filePath: "src/lib/dashboard-browser/dashboard-browser.component.ts", lineNumber: 135 }); })();
1775
1774
  //# sourceMappingURL=dashboard-browser.component.js.map