@memberjunction/ng-explorer-settings 5.43.0 → 5.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/__tests__/role-management-agent-context.test.d.ts +2 -0
  2. package/dist/__tests__/role-management-agent-context.test.d.ts.map +1 -0
  3. package/dist/__tests__/role-management-agent-context.test.js +107 -0
  4. package/dist/__tests__/role-management-agent-context.test.js.map +1 -0
  5. package/dist/__tests__/user-app-config-reorder.test.d.ts +2 -0
  6. package/dist/__tests__/user-app-config-reorder.test.d.ts.map +1 -0
  7. package/dist/__tests__/user-app-config-reorder.test.js +66 -0
  8. package/dist/__tests__/user-app-config-reorder.test.js.map +1 -0
  9. package/dist/__tests__/user-management-agent-context.test.d.ts +2 -0
  10. package/dist/__tests__/user-management-agent-context.test.d.ts.map +1 -0
  11. package/dist/__tests__/user-management-agent-context.test.js +134 -0
  12. package/dist/__tests__/user-management-agent-context.test.js.map +1 -0
  13. package/dist/lib/application-management/application-dialog/application-dialog.component.js +176 -200
  14. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  15. package/dist/lib/application-management/application-management.component.d.ts +7 -0
  16. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  17. package/dist/lib/application-management/application-management.component.js +49 -39
  18. package/dist/lib/application-management/application-management.component.js.map +1 -1
  19. package/dist/lib/application-settings/application-settings.component.js +58 -70
  20. package/dist/lib/application-settings/application-settings.component.js.map +1 -1
  21. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +10 -0
  22. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  23. package/dist/lib/entity-permissions/entity-permissions.component.js +32 -16
  24. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  25. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +32 -33
  26. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  27. package/dist/lib/module.d.ts +1 -1
  28. package/dist/lib/module.d.ts.map +1 -1
  29. package/dist/lib/module.js +13 -4
  30. package/dist/lib/module.js.map +1 -1
  31. package/dist/lib/notification-preferences/notification-preferences.component.js +30 -35
  32. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
  33. package/dist/lib/role-management/role-dialog/role-dialog.component.js +26 -46
  34. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  35. package/dist/lib/role-management/role-management-agent-context.d.ts +96 -0
  36. package/dist/lib/role-management/role-management-agent-context.d.ts.map +1 -0
  37. package/dist/lib/role-management/role-management-agent-context.js +85 -0
  38. package/dist/lib/role-management/role-management-agent-context.js.map +1 -0
  39. package/dist/lib/role-management/role-management.component.d.ts +32 -0
  40. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  41. package/dist/lib/role-management/role-management.component.js +236 -41
  42. package/dist/lib/role-management/role-management.component.js.map +1 -1
  43. package/dist/lib/sql-logging/sql-logging.component.js +151 -184
  44. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  45. package/dist/lib/user-app-config/user-app-config-reorder.d.ts +29 -0
  46. package/dist/lib/user-app-config/user-app-config-reorder.d.ts.map +1 -0
  47. package/dist/lib/user-app-config/user-app-config-reorder.js +43 -0
  48. package/dist/lib/user-app-config/user-app-config-reorder.js.map +1 -0
  49. package/dist/lib/user-app-config/user-app-config.component.d.ts +6 -3
  50. package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
  51. package/dist/lib/user-app-config/user-app-config.component.js +98 -114
  52. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  53. package/dist/lib/user-management/user-dialog/user-dialog.component.js +20 -21
  54. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  55. package/dist/lib/user-management/user-management-agent-context.d.ts +107 -0
  56. package/dist/lib/user-management/user-management-agent-context.d.ts.map +1 -0
  57. package/dist/lib/user-management/user-management-agent-context.js +132 -0
  58. package/dist/lib/user-management/user-management-agent-context.js.map +1 -0
  59. package/dist/lib/user-management/user-management.component.d.ts +35 -0
  60. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  61. package/dist/lib/user-management/user-management.component.js +311 -71
  62. package/dist/lib/user-management/user-management.component.js.map +1 -1
  63. package/dist/lib/user-profile-settings/user-profile-settings.component.js +52 -70
  64. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  65. package/package.json +19 -19
@@ -5,6 +5,7 @@ import { ApplicationManager } from '@memberjunction/ng-base-application';
5
5
  import { SharedService } from '@memberjunction/ng-shared';
6
6
  import { UUIDsEqual } from '@memberjunction/global';
7
7
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
8
+ import { moveAndResequence, resequenceItems } from './user-app-config-reorder';
8
9
  import * as i0 from "@angular/core";
9
10
  import * as i1 from "@memberjunction/ng-shared-generic";
10
11
  import * as i2 from "@memberjunction/ng-ui-components";
@@ -15,25 +16,19 @@ function UserAppConfigComponent_Conditional_0_Conditional_9_Template(rf, ctx) {
15
16
  i0.ɵɵelementEnd();
16
17
  } }
17
18
  function UserAppConfigComponent_Conditional_0_Conditional_10_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelementStart(0, "div", 9);
19
- i0.ɵɵelement(1, "i", 18);
20
- i0.ɵɵelementStart(2, "span");
21
- i0.ɵɵtext(3);
22
- i0.ɵɵelementEnd()();
19
+ i0.ɵɵelementStart(0, "mj-alert", 9);
20
+ i0.ɵɵtext(1);
21
+ i0.ɵɵelementEnd();
23
22
  } if (rf & 2) {
24
23
  const ctx_r1 = i0.ɵɵnextContext(2);
25
- i0.ɵɵadvance(3);
24
+ i0.ɵɵadvance();
26
25
  i0.ɵɵtextInterpolate(ctx_r1.ErrorMessage);
27
26
  } }
28
27
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_13_Template(rf, ctx) { if (rf & 1) {
29
- i0.ɵɵelementStart(0, "div", 27);
30
- i0.ɵɵelement(1, "i", 34);
31
- i0.ɵɵelementStart(2, "p");
32
- i0.ɵɵtext(3, "All applications added!");
33
- i0.ɵɵelementEnd()();
28
+ i0.ɵɵelement(0, "mj-empty-state", 26);
34
29
  } }
35
30
  function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_6_Template(rf, ctx) { if (rf & 1) {
36
- i0.ɵɵelementStart(0, "span", 40);
31
+ i0.ɵɵelementStart(0, "span", 39);
37
32
  i0.ɵɵtext(1);
38
33
  i0.ɵɵelementEnd();
39
34
  } if (rf & 2) {
@@ -43,19 +38,19 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_
43
38
  } }
44
39
  function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template(rf, ctx) { if (rf & 1) {
45
40
  const _r4 = i0.ɵɵgetCurrentView();
46
- i0.ɵɵelementStart(0, "div", 35);
41
+ i0.ɵɵelementStart(0, "div", 34);
47
42
  i0.ɵɵlistener("dblclick", function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template_div_dblclick_0_listener() { const item_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.AddApp(item_r5)); });
48
- i0.ɵɵelementStart(1, "div", 36);
49
- i0.ɵɵelement(2, "i", 37);
43
+ i0.ɵɵelementStart(1, "div", 35);
44
+ i0.ɵɵelement(2, "i", 36);
50
45
  i0.ɵɵelementEnd();
51
- i0.ɵɵelementStart(3, "div", 38)(4, "span", 39);
46
+ i0.ɵɵelementStart(3, "div", 37)(4, "span", 38);
52
47
  i0.ɵɵtext(5);
53
48
  i0.ɵɵelementEnd();
54
- i0.ɵɵconditionalCreate(6, UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_6_Template, 2, 1, "span", 40);
49
+ i0.ɵɵconditionalCreate(6, UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_6_Template, 2, 1, "span", 39);
55
50
  i0.ɵɵelementEnd();
56
- i0.ɵɵelementStart(7, "button", 41);
51
+ i0.ɵɵelementStart(7, "button", 40);
57
52
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template_button_click_7_listener() { const item_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.AddApp(item_r5)); });
58
- i0.ɵɵelement(8, "i", 42);
53
+ i0.ɵɵelement(8, "i", 41);
59
54
  i0.ɵɵtext(9, " Add ");
60
55
  i0.ɵɵelementEnd()();
61
56
  } if (rf & 2) {
@@ -72,17 +67,10 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template(rf,
72
67
  i0.ɵɵattribute("aria-label", "Add " + item_r5.app.Name);
73
68
  } }
74
69
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_25_Template(rf, ctx) { if (rf & 1) {
75
- i0.ɵɵelementStart(0, "div", 27);
76
- i0.ɵɵelement(1, "i", 43);
77
- i0.ɵɵelementStart(2, "p");
78
- i0.ɵɵtext(3, "No applications selected");
79
- i0.ɵɵelementEnd();
80
- i0.ɵɵelementStart(4, "p", 44);
81
- i0.ɵɵtext(5, "Add apps from the available list");
82
- i0.ɵɵelementEnd()();
70
+ i0.ɵɵelement(0, "mj-empty-state", 30);
83
71
  } }
84
72
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
85
- i0.ɵɵelementStart(0, "span", 40);
73
+ i0.ɵɵelementStart(0, "span", 39);
86
74
  i0.ɵɵtext(1);
87
75
  i0.ɵɵelementEnd();
88
76
  } if (rf & 2) {
@@ -92,34 +80,34 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_
92
80
  } }
93
81
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template(rf, ctx) { if (rf & 1) {
94
82
  const _r7 = i0.ɵɵgetCurrentView();
95
- i0.ɵɵelementStart(0, "div", 47);
96
- i0.ɵɵlistener("dragstart", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dragstart_0_listener($event) { const ctx_r7 = i0.ɵɵrestoreView(_r7); const item_r9 = ctx_r7.$implicit; const ɵ$index_115_r10 = ctx_r7.$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, item_r9, ɵ$index_115_r10)); })("dragend", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("dragenter", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dragenter_0_listener($event) { const ɵ$index_115_r10 = i0.ɵɵrestoreView(_r7).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnDragEnter($event, ɵ$index_115_r10)); })("dblclick", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dblclick_0_listener($event) { const item_r9 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.RemoveApp(item_r9); return i0.ɵɵresetView($event.stopPropagation()); });
97
- i0.ɵɵelementStart(1, "div", 48)(2, "div", 49);
98
- i0.ɵɵelement(3, "i", 50);
83
+ i0.ɵɵelementStart(0, "div", 44);
84
+ i0.ɵɵlistener("dragstart", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dragstart_0_listener($event) { const ctx_r7 = i0.ɵɵrestoreView(_r7); const item_r9 = ctx_r7.$implicit; const ɵ$index_98_r10 = ctx_r7.$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnDragStart($event, item_r9, ɵ$index_98_r10)); })("dragend", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dragend_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnDragEnd()); })("dragenter", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dragenter_0_listener($event) { const ɵ$index_98_r10 = i0.ɵɵrestoreView(_r7).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnDragEnter($event, ɵ$index_98_r10)); })("dblclick", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_div_dblclick_0_listener($event) { const item_r9 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.RemoveApp(item_r9); return i0.ɵɵresetView($event.stopPropagation()); });
85
+ i0.ɵɵelementStart(1, "div", 45)(2, "div", 46);
86
+ i0.ɵɵelement(3, "i", 47);
99
87
  i0.ɵɵelementEnd();
100
- i0.ɵɵelementStart(4, "div", 36);
101
- i0.ɵɵelement(5, "i", 37);
88
+ i0.ɵɵelementStart(4, "div", 35);
89
+ i0.ɵɵelement(5, "i", 36);
102
90
  i0.ɵɵelementEnd();
103
- i0.ɵɵelementStart(6, "div", 38)(7, "span", 39);
91
+ i0.ɵɵelementStart(6, "div", 37)(7, "span", 38);
104
92
  i0.ɵɵtext(8);
105
93
  i0.ɵɵelementEnd();
106
- i0.ɵɵconditionalCreate(9, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Conditional_9_Template, 2, 1, "span", 40);
94
+ i0.ɵɵconditionalCreate(9, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Conditional_9_Template, 2, 1, "span", 39);
107
95
  i0.ɵɵelementEnd();
108
- i0.ɵɵelementStart(10, "div", 51)(11, "button", 52);
96
+ i0.ɵɵelementStart(10, "div", 48)(11, "button", 49);
109
97
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_button_click_11_listener($event) { const item_r9 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.MoveUp(item_r9); return i0.ɵɵresetView($event.stopPropagation()); });
110
- i0.ɵɵelement(12, "i", 53);
98
+ i0.ɵɵelement(12, "i", 50);
111
99
  i0.ɵɵelementEnd();
112
- i0.ɵɵelementStart(13, "button", 54);
100
+ i0.ɵɵelementStart(13, "button", 51);
113
101
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_button_click_13_listener($event) { const item_r9 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.MoveDown(item_r9); return i0.ɵɵresetView($event.stopPropagation()); });
114
- i0.ɵɵelement(14, "i", 55);
102
+ i0.ɵɵelement(14, "i", 52);
115
103
  i0.ɵɵelementEnd();
116
- i0.ɵɵelementStart(15, "button", 56);
104
+ i0.ɵɵelementStart(15, "button", 53);
117
105
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template_button_click_15_listener($event) { const item_r9 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); ctx_r1.RemoveApp(item_r9); return i0.ɵɵresetView($event.stopPropagation()); });
118
106
  i0.ɵɵelement(16, "i", 6);
119
107
  i0.ɵɵelementEnd()()()();
120
108
  } if (rf & 2) {
121
109
  const item_r9 = ctx.$implicit;
122
- const ɵ$index_115_r10 = ctx.$index;
110
+ const ɵ$index_98_r10 = ctx.$index;
123
111
  const ctx_r1 = i0.ɵɵnextContext(4);
124
112
  i0.ɵɵclassProp("dragging", ctx_r1.DraggedItem === item_r9);
125
113
  i0.ɵɵadvance();
@@ -133,19 +121,19 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_
133
121
  i0.ɵɵadvance();
134
122
  i0.ɵɵconditional(item_r9.app.Description ? 9 : -1);
135
123
  i0.ɵɵadvance(2);
136
- i0.ɵɵproperty("disabled", ɵ$index_115_r10 === 0);
124
+ i0.ɵɵproperty("disabled", ɵ$index_98_r10 === 0);
137
125
  i0.ɵɵattribute("aria-label", "Move " + item_r9.app.Name + " up");
138
126
  i0.ɵɵadvance(2);
139
- i0.ɵɵproperty("disabled", ɵ$index_115_r10 === ctx_r1.ActiveApps.length - 1);
127
+ i0.ɵɵproperty("disabled", ɵ$index_98_r10 === ctx_r1.ActiveApps.length - 1);
140
128
  i0.ɵɵattribute("aria-label", "Move " + item_r9.app.Name + " down");
141
129
  i0.ɵɵadvance(2);
142
130
  i0.ɵɵattribute("aria-label", "Remove " + item_r9.app.Name);
143
131
  } }
144
132
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_Template(rf, ctx) { if (rf & 1) {
145
133
  const _r6 = i0.ɵɵgetCurrentView();
146
- i0.ɵɵelementStart(0, "div", 45);
134
+ i0.ɵɵelementStart(0, "div", 42);
147
135
  i0.ɵɵlistener("dragover", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_Template_div_dragover_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnDragOver($event)); })("drop", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_Template_div_drop_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnDrop($event)); });
148
- i0.ɵɵrepeaterCreate(1, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template, 17, 15, "div", 46, _forTrack0);
136
+ i0.ɵɵrepeaterCreate(1, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template, 17, 15, "div", 43, _forTrack0);
149
137
  i0.ɵɵelementEnd();
150
138
  } if (rf & 2) {
151
139
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -153,36 +141,36 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_Temp
153
141
  i0.ɵɵrepeater(ctx_r1.ActiveApps);
154
142
  } }
155
143
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
156
- i0.ɵɵelement(0, "div", 58);
144
+ i0.ɵɵelement(0, "div", 55);
157
145
  } }
158
146
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_10_Template(rf, ctx) { if (rf & 1) {
159
- i0.ɵɵelement(0, "div", 58);
147
+ i0.ɵɵelement(0, "div", 55);
160
148
  } }
161
149
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Template(rf, ctx) { if (rf & 1) {
162
150
  const _r11 = i0.ɵɵgetCurrentView();
163
- i0.ɵɵconditionalCreate(0, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_0_Template, 1, 0, "div", 58);
164
- i0.ɵɵelementStart(1, "div", 59)(2, "div", 60);
165
- i0.ɵɵlistener("touchstart", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Template_div_touchstart_2_listener($event) { const ɵ$index_159_r12 = i0.ɵɵrestoreView(_r11).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnTouchDragStart($event, ɵ$index_159_r12)); });
166
- i0.ɵɵelement(3, "i", 50);
151
+ i0.ɵɵconditionalCreate(0, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_0_Template, 1, 0, "div", 55);
152
+ i0.ɵɵelementStart(1, "div", 56)(2, "div", 57);
153
+ i0.ɵɵlistener("touchstart", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Template_div_touchstart_2_listener($event) { const ɵ$index_142_r12 = i0.ɵɵrestoreView(_r11).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnTouchDragStart($event, ɵ$index_142_r12)); });
154
+ i0.ɵɵelement(3, "i", 47);
167
155
  i0.ɵɵelementEnd();
168
- i0.ɵɵelementStart(4, "div", 36);
169
- i0.ɵɵelement(5, "i", 37);
156
+ i0.ɵɵelementStart(4, "div", 35);
157
+ i0.ɵɵelement(5, "i", 36);
170
158
  i0.ɵɵelementEnd();
171
- i0.ɵɵelementStart(6, "span", 61);
159
+ i0.ɵɵelementStart(6, "span", 58);
172
160
  i0.ɵɵtext(7);
173
161
  i0.ɵɵelementEnd();
174
- i0.ɵɵelementStart(8, "button", 62);
162
+ i0.ɵɵelementStart(8, "button", 59);
175
163
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Template_button_click_8_listener() { const item_r13 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ToggleApp(item_r13)); });
176
- i0.ɵɵelement(9, "i", 63);
164
+ i0.ɵɵelement(9, "i", 60);
177
165
  i0.ɵɵelementEnd()();
178
- i0.ɵɵconditionalCreate(10, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_10_Template, 1, 0, "div", 58);
166
+ i0.ɵɵconditionalCreate(10, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_10_Template, 1, 0, "div", 55);
179
167
  } if (rf & 2) {
180
168
  const item_r13 = ctx.$implicit;
181
- const ɵ$index_159_r12 = ctx.$index;
169
+ const ɵ$index_142_r12 = ctx.$index;
182
170
  const ctx_r1 = i0.ɵɵnextContext(4);
183
- i0.ɵɵconditional(ctx_r1.TouchDragActive && ctx_r1.TouchDropIndex === ɵ$index_159_r12 && ctx_r1.TouchDragIndex > ɵ$index_159_r12 ? 0 : -1);
171
+ i0.ɵɵconditional(ctx_r1.TouchDragActive && ctx_r1.TouchDropIndex === ɵ$index_142_r12 && ctx_r1.TouchDragIndex > ɵ$index_142_r12 ? 0 : -1);
184
172
  i0.ɵɵadvance();
185
- i0.ɵɵclassProp("touch-ghost", ctx_r1.TouchDragActive && ctx_r1.TouchDragIndex === ɵ$index_159_r12);
173
+ i0.ɵɵclassProp("touch-ghost", ctx_r1.TouchDragActive && ctx_r1.TouchDragIndex === ɵ$index_142_r12);
186
174
  i0.ɵɵadvance(3);
187
175
  i0.ɵɵstyleProp("background-color", item_r13.app.GetColor());
188
176
  i0.ɵɵadvance();
@@ -192,17 +180,17 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_
192
180
  i0.ɵɵadvance();
193
181
  i0.ɵɵariaProperty("aria-label", i0.ɵɵinterpolate1("Remove ", item_r13.app.Name));
194
182
  i0.ɵɵadvance(2);
195
- i0.ɵɵconditional(ctx_r1.TouchDragActive && ctx_r1.TouchDropIndex === ɵ$index_159_r12 && ctx_r1.TouchDragIndex < ɵ$index_159_r12 ? 10 : -1);
183
+ i0.ɵɵconditional(ctx_r1.TouchDragActive && ctx_r1.TouchDropIndex === ɵ$index_142_r12 && ctx_r1.TouchDragIndex < ɵ$index_142_r12 ? 10 : -1);
196
184
  } }
197
185
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Conditional_4_Template(rf, ctx) { if (rf & 1) {
198
- i0.ɵɵelement(0, "div", 58);
186
+ i0.ɵɵelement(0, "div", 55);
199
187
  } }
200
188
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Template(rf, ctx) { if (rf & 1) {
201
- i0.ɵɵelementStart(0, "div", 57);
189
+ i0.ɵɵelementStart(0, "div", 54);
202
190
  i0.ɵɵtext(1, "Your Apps");
203
191
  i0.ɵɵelementEnd();
204
192
  i0.ɵɵrepeaterCreate(2, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Template, 11, 11, null, null, _forTrack0);
205
- i0.ɵɵconditionalCreate(4, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Conditional_4_Template, 1, 0, "div", 58);
193
+ i0.ɵɵconditionalCreate(4, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Conditional_4_Template, 1, 0, "div", 55);
206
194
  } if (rf & 2) {
207
195
  const ctx_r1 = i0.ɵɵnextContext(3);
208
196
  i0.ɵɵadvance(2);
@@ -212,15 +200,15 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Temp
212
200
  } }
213
201
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_For_3_Template(rf, ctx) { if (rf & 1) {
214
202
  const _r14 = i0.ɵɵgetCurrentView();
215
- i0.ɵɵelementStart(0, "div", 64)(1, "div", 36);
216
- i0.ɵɵelement(2, "i", 37);
203
+ i0.ɵɵelementStart(0, "div", 61)(1, "div", 35);
204
+ i0.ɵɵelement(2, "i", 36);
217
205
  i0.ɵɵelementEnd();
218
- i0.ɵɵelementStart(3, "span", 61);
206
+ i0.ɵɵelementStart(3, "span", 58);
219
207
  i0.ɵɵtext(4);
220
208
  i0.ɵɵelementEnd();
221
- i0.ɵɵelementStart(5, "button", 65);
209
+ i0.ɵɵelementStart(5, "button", 62);
222
210
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_For_3_Template_button_click_5_listener() { const item_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ToggleApp(item_r15)); });
223
- i0.ɵɵelement(6, "i", 66);
211
+ i0.ɵɵelement(6, "i", 63);
224
212
  i0.ɵɵelementEnd()();
225
213
  } if (rf & 2) {
226
214
  const item_r15 = ctx.$implicit;
@@ -234,10 +222,10 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_For_
234
222
  i0.ɵɵariaProperty("aria-label", i0.ɵɵinterpolate1("Add ", item_r15.app.Name));
235
223
  } }
236
224
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_Template(rf, ctx) { if (rf & 1) {
237
- i0.ɵɵelementStart(0, "div", 57);
225
+ i0.ɵɵelementStart(0, "div", 54);
238
226
  i0.ɵɵtext(1, "Available");
239
227
  i0.ɵɵelementEnd();
240
- i0.ɵɵrepeaterCreate(2, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_For_3_Template, 7, 7, "div", 64, _forTrack0);
228
+ i0.ɵɵrepeaterCreate(2, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_For_3_Template, 7, 7, "div", 61, _forTrack0);
241
229
  } if (rf & 2) {
242
230
  const ctx_r1 = i0.ɵɵnextContext(3);
243
231
  i0.ɵɵadvance(2);
@@ -245,37 +233,37 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_Temp
245
233
  } }
246
234
  function UserAppConfigComponent_Conditional_0_Conditional_11_Template(rf, ctx) { if (rf & 1) {
247
235
  const _r3 = i0.ɵɵgetCurrentView();
248
- i0.ɵɵelementStart(0, "div", 10)(1, "p", 19);
236
+ i0.ɵɵelementStart(0, "div", 10)(1, "p", 18);
249
237
  i0.ɵɵtext(2, " Select which applications appear in your app switcher and arrange them in your preferred order. Double-click to quickly add or remove. Drag and drop to reorder, or use the arrow buttons. ");
250
238
  i0.ɵɵelementEnd();
251
- i0.ɵɵelementStart(3, "div", 20)(4, "div", 21)(5, "div", 22);
239
+ i0.ɵɵelementStart(3, "div", 19)(4, "div", 20)(5, "div", 21);
252
240
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_Template_div_click_5_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.AvailablePanelCollapsed = !ctx_r1.AvailablePanelCollapsed); });
253
- i0.ɵɵelement(6, "i", 23);
241
+ i0.ɵɵelement(6, "i", 22);
254
242
  i0.ɵɵelementStart(7, "h3");
255
243
  i0.ɵɵtext(8, "Available Applications");
256
244
  i0.ɵɵelementEnd();
257
- i0.ɵɵelementStart(9, "span", 24);
245
+ i0.ɵɵelementStart(9, "span", 23);
258
246
  i0.ɵɵtext(10);
259
247
  i0.ɵɵelementEnd();
260
- i0.ɵɵelement(11, "i", 25);
248
+ i0.ɵɵelement(11, "i", 24);
261
249
  i0.ɵɵelementEnd();
262
- i0.ɵɵelementStart(12, "div", 26);
263
- i0.ɵɵconditionalCreate(13, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_13_Template, 4, 0, "div", 27);
264
- i0.ɵɵrepeaterCreate(14, UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template, 10, 7, "div", 28, _forTrack0);
250
+ i0.ɵɵelementStart(12, "div", 25);
251
+ i0.ɵɵconditionalCreate(13, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_13_Template, 1, 0, "mj-empty-state", 26);
252
+ i0.ɵɵrepeaterCreate(14, UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template, 10, 7, "div", 27, _forTrack0);
265
253
  i0.ɵɵelementEnd()();
266
- i0.ɵɵelementStart(16, "div", 29)(17, "div", 22);
254
+ i0.ɵɵelementStart(16, "div", 28)(17, "div", 21);
267
255
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_11_Template_div_click_17_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectedPanelCollapsed = !ctx_r1.SelectedPanelCollapsed); });
268
- i0.ɵɵelement(18, "i", 30);
256
+ i0.ɵɵelement(18, "i", 29);
269
257
  i0.ɵɵelementStart(19, "h3");
270
258
  i0.ɵɵtext(20, "Your Applications");
271
259
  i0.ɵɵelementEnd();
272
- i0.ɵɵelementStart(21, "span", 24);
260
+ i0.ɵɵelementStart(21, "span", 23);
273
261
  i0.ɵɵtext(22);
274
262
  i0.ɵɵelementEnd();
275
- i0.ɵɵelement(23, "i", 25);
263
+ i0.ɵɵelement(23, "i", 24);
276
264
  i0.ɵɵelementEnd();
277
- i0.ɵɵelementStart(24, "div", 26);
278
- i0.ɵɵconditionalCreate(25, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_25_Template, 6, 0, "div", 27);
265
+ i0.ɵɵelementStart(24, "div", 25);
266
+ i0.ɵɵconditionalCreate(25, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_25_Template, 1, 0, "mj-empty-state", 30);
279
267
  i0.ɵɵconditionalCreate(26, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_Template, 3, 0, "div", 31);
280
268
  i0.ɵɵelementEnd()()();
281
269
  i0.ɵɵelementStart(27, "div", 32);
@@ -315,7 +303,7 @@ function UserAppConfigComponent_Conditional_0_Conditional_14_Template(rf, ctx) {
315
303
  const _r16 = i0.ɵɵgetCurrentView();
316
304
  i0.ɵɵelementStart(0, "button", 16);
317
305
  i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.Reset()); });
318
- i0.ɵɵelement(1, "i", 67);
306
+ i0.ɵɵelement(1, "i", 64);
319
307
  i0.ɵɵtext(2, " Reset Changes ");
320
308
  i0.ɵɵelementEnd();
321
309
  } if (rf & 2) {
@@ -323,7 +311,7 @@ function UserAppConfigComponent_Conditional_0_Conditional_14_Template(rf, ctx) {
323
311
  i0.ɵɵproperty("disabled", ctx_r1.IsLoading || ctx_r1.IsSaving);
324
312
  } }
325
313
  function UserAppConfigComponent_Conditional_0_Conditional_17_Template(rf, ctx) { if (rf & 1) {
326
- i0.ɵɵelement(0, "mj-loading", 68);
314
+ i0.ɵɵelement(0, "mj-loading", 65);
327
315
  i0.ɵɵelementStart(1, "span");
328
316
  i0.ɵɵtext(2, "Saving...");
329
317
  i0.ɵɵelementEnd();
@@ -331,7 +319,7 @@ function UserAppConfigComponent_Conditional_0_Conditional_17_Template(rf, ctx) {
331
319
  i0.ɵɵproperty("showText", false);
332
320
  } }
333
321
  function UserAppConfigComponent_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
334
- i0.ɵɵelement(0, "i", 69);
322
+ i0.ɵɵelement(0, "i", 66);
335
323
  i0.ɵɵelementStart(1, "span");
336
324
  i0.ɵɵtext(2, "Save Changes");
337
325
  i0.ɵɵelementEnd();
@@ -351,7 +339,7 @@ function UserAppConfigComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
351
339
  i0.ɵɵelementEnd()();
352
340
  i0.ɵɵelementStart(8, "div", 7);
353
341
  i0.ɵɵconditionalCreate(9, UserAppConfigComponent_Conditional_0_Conditional_9_Template, 2, 0, "div", 8);
354
- i0.ɵɵconditionalCreate(10, UserAppConfigComponent_Conditional_0_Conditional_10_Template, 4, 1, "div", 9);
342
+ i0.ɵɵconditionalCreate(10, UserAppConfigComponent_Conditional_0_Conditional_10_Template, 2, 1, "mj-alert", 9);
355
343
  i0.ɵɵconditionalCreate(11, UserAppConfigComponent_Conditional_0_Conditional_11_Template, 31, 19, "div", 10);
356
344
  i0.ɵɵelementStart(12, "div", 11)(13, "div", 12);
357
345
  i0.ɵɵconditionalCreate(14, UserAppConfigComponent_Conditional_0_Conditional_14_Template, 3, 1, "button", 13);
@@ -463,25 +451,29 @@ export class UserAppConfigComponent extends BaseAngularComponent {
463
451
  }
464
452
  }
465
453
  /**
466
- * Moves an app up in the order
454
+ * Moves an app up in the order. Positional (splice + renumber), NOT a sequence-value
455
+ * swap: rows can carry duplicate Sequence values (issue #3027 — e.g. a re-enabled app
456
+ * kept a stale value), and swapping two equal values is a silent no-op. Reordering by
457
+ * position then renumbering 0..n-1 always works and heals duplicates as a side effect.
467
458
  */
468
459
  MoveUp(item) {
469
460
  const index = this.ActiveApps.indexOf(item);
470
461
  if (index > 0) {
471
- this.swapSequences(item, this.ActiveApps[index - 1]);
472
- this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.sequence - b.sequence);
462
+ this.moveActiveApp(index, index - 1);
473
463
  }
474
464
  }
475
465
  /**
476
- * Moves an app down in the order
466
+ * Moves an app down in the order. Positional — see {@link MoveUp} for why.
477
467
  */
478
468
  MoveDown(item) {
479
469
  const index = this.ActiveApps.indexOf(item);
480
- if (index < this.ActiveApps.length - 1) {
481
- this.swapSequences(item, this.ActiveApps[index + 1]);
482
- this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.sequence - b.sequence);
470
+ if (index >= 0 && index < this.ActiveApps.length - 1) {
471
+ this.moveActiveApp(index, index + 1);
483
472
  }
484
473
  }
474
+ moveActiveApp(fromIndex, toIndex) {
475
+ this.ActiveApps = moveAndResequence(this.ActiveApps, fromIndex, toIndex);
476
+ }
485
477
  /**
486
478
  * Checks if there are any unsaved changes
487
479
  */
@@ -499,6 +491,10 @@ export class UserAppConfigComponent extends BaseAngularComponent {
499
491
  this.IsSaving = true;
500
492
  this.ErrorMessage = '';
501
493
  try {
494
+ // Self-heal: renumber active apps 0..n-1 before persisting. Existing rows can
495
+ // carry duplicate Sequence values from older data (issue #3027); renumbering in
496
+ // display order marks any corrected rows dirty so this save fixes them for good.
497
+ this.resequenceActiveApps();
502
498
  const md = this.ProviderToUse;
503
499
  for (const item of this.AllApps) {
504
500
  if (!item.isDirty)
@@ -705,19 +701,7 @@ export class UserAppConfigComponent extends BaseAngularComponent {
705
701
  .sort((a, b) => a.app.Name.localeCompare(b.app.Name));
706
702
  }
707
703
  resequenceActiveApps() {
708
- this.ActiveApps.forEach((item, index) => {
709
- if (item.sequence !== index) {
710
- item.sequence = index;
711
- item.isDirty = true;
712
- }
713
- });
714
- }
715
- swapSequences(a, b) {
716
- const tempSeq = a.sequence;
717
- a.sequence = b.sequence;
718
- b.sequence = tempSeq;
719
- a.isDirty = true;
720
- b.isDirty = true;
704
+ resequenceItems(this.ActiveApps);
721
705
  }
722
706
  async updateUserApplication(md, item) {
723
707
  const userApp = await md.GetEntityObject('MJ: User Applications');
@@ -747,15 +731,15 @@ export class UserAppConfigComponent extends BaseAngularComponent {
747
731
  LogStatus(`Created UserApplication for ${item.app.Name}: sequence=${item.sequence}`);
748
732
  }
749
733
  static ɵfac = /*@__PURE__*/ (() => { let ɵUserAppConfigComponent_BaseFactory; return function UserAppConfigComponent_Factory(__ngFactoryType__) { return (ɵUserAppConfigComponent_BaseFactory || (ɵUserAppConfigComponent_BaseFactory = i0.ɵɵgetInheritedFactory(UserAppConfigComponent)))(__ngFactoryType__ || UserAppConfigComponent); }; })();
750
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserAppConfigComponent, selectors: [["mj-user-app-config"]], inputs: { ShowDialog: "ShowDialog" }, outputs: { ShowDialogChange: "ShowDialogChange", ConfigSaved: "ConfigSaved" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [["role", "presentation", 1, "modal-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "app-config-title", 1, "modal-dialog", "full-screen-dialog"], [1, "modal-header"], ["id", "app-config-title", 1, "modal-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-grid-2"], ["aria-label", "Close dialog", 1, "modal-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], [1, "app-config-container"], ["role", "status", "aria-live", "polite", 1, "loading-container"], ["role", "alert", 1, "error-message"], [1, "config-content"], [1, "dialog-footer"], [1, "footer-left"], ["mjButton", "", 3, "disabled"], [1, "footer-right"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"], ["text", "Loading your app configuration...", "size", "medium"], ["aria-hidden", "true", 1, "fa-solid", "fa-circle-exclamation"], [1, "config-description"], [1, "panels-container", "desktop-only"], [1, "panel", "available-apps-panel"], [1, "panel-header", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-layer-group"], [1, "badge"], ["aria-hidden", "true", 1, "collapse-toggle", "fa-solid"], [1, "panel-content"], [1, "empty-state"], [1, "available-app-item"], [1, "panel", "selected-apps-panel"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-circle"], [1, "sortable-list"], [1, "mobile-view", 3, "touchmove", "touchend", "touchcancel"], [1, "mobile-list"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-double"], [1, "available-app-item", 3, "dblclick"], [1, "app-icon"], ["aria-hidden", "true"], [1, "app-info"], [1, "app-name"], [1, "app-description"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Add to your apps", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["aria-hidden", "true", 1, "fa-solid", "fa-inbox"], [1, "hint"], [1, "sortable-list", 3, "dragover", "drop"], ["draggable", "true", 1, "app-item", 3, "dragging"], ["draggable", "true", 1, "app-item", 3, "dragstart", "dragend", "dragenter", "dblclick"], [1, "app-item-content"], [1, "drag-handle"], ["aria-hidden", "true", 1, "fa-solid", "fa-grip-vertical"], [1, "app-actions"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Move up", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-up"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Move down", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["mjButton", "", "variant", "danger", "size", "sm", "title", "Remove from your apps", 3, "click"], [1, "mobile-section-label"], [1, "mobile-drop-indicator"], [1, "mobile-app-row"], ["aria-label", "Drag to reorder", 1, "mobile-drag-handle", 3, "touchstart"], [1, "mobile-app-name"], [1, "mobile-toggle", "on", 3, "click", "aria-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-on"], [1, "mobile-app-row", "inactive"], [1, "mobile-toggle", "off", 3, "click", "aria-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-off"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], ["size", "small", 3, "showText"], ["aria-hidden", "true", 1, "fa-solid", "fa-check"]], template: function UserAppConfigComponent_Template(rf, ctx) { if (rf & 1) {
734
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserAppConfigComponent, selectors: [["mj-user-app-config"]], inputs: { ShowDialog: "ShowDialog" }, outputs: { ShowDialogChange: "ShowDialogChange", ConfigSaved: "ConfigSaved" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [["role", "presentation", 1, "modal-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "app-config-title", 1, "modal-dialog", "full-screen-dialog"], [1, "modal-header"], ["id", "app-config-title", 1, "modal-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-grid-2"], ["aria-label", "Close dialog", 1, "modal-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], [1, "app-config-container"], ["role", "status", "aria-live", "polite", 1, "loading-container"], ["Variant", "error"], [1, "config-content"], [1, "dialog-footer"], [1, "footer-left"], ["mjButton", "", 3, "disabled"], [1, "footer-right"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"], ["text", "Loading your app configuration...", "size", "medium"], [1, "config-description"], [1, "panels-container", "desktop-only"], [1, "panel", "available-apps-panel"], [1, "panel-header", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-layer-group"], [1, "badge"], ["aria-hidden", "true", 1, "collapse-toggle", "fa-solid"], [1, "panel-content"], ["Size", "compact", "Icon", "fa-solid fa-check-double", "Title", "All applications added!"], [1, "available-app-item"], [1, "panel", "selected-apps-panel"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-circle"], ["Size", "compact", "Icon", "fa-solid fa-inbox", "Title", "No applications selected", "Message", "Add apps from the available list"], [1, "sortable-list"], [1, "mobile-view", 3, "touchmove", "touchend", "touchcancel"], [1, "mobile-list"], [1, "available-app-item", 3, "dblclick"], [1, "app-icon"], ["aria-hidden", "true"], [1, "app-info"], [1, "app-name"], [1, "app-description"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Add to your apps", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], [1, "sortable-list", 3, "dragover", "drop"], ["draggable", "true", 1, "app-item", 3, "dragging"], ["draggable", "true", 1, "app-item", 3, "dragstart", "dragend", "dragenter", "dblclick"], [1, "app-item-content"], [1, "drag-handle"], ["aria-hidden", "true", 1, "fa-solid", "fa-grip-vertical"], [1, "app-actions"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Move up", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-up"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Move down", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["mjButton", "", "variant", "danger", "size", "sm", "title", "Remove from your apps", 3, "click"], [1, "mobile-section-label"], [1, "mobile-drop-indicator"], [1, "mobile-app-row"], ["aria-label", "Drag to reorder", 1, "mobile-drag-handle", 3, "touchstart"], [1, "mobile-app-name"], [1, "mobile-toggle", "on", 3, "click", "aria-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-on"], [1, "mobile-app-row", "inactive"], [1, "mobile-toggle", "off", 3, "click", "aria-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-off"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], ["size", "small", 3, "showText"], ["aria-hidden", "true", 1, "fa-solid", "fa-check"]], template: function UserAppConfigComponent_Template(rf, ctx) { if (rf & 1) {
751
735
  i0.ɵɵconditionalCreate(0, UserAppConfigComponent_Conditional_0_Template, 21, 7);
752
736
  } if (rf & 2) {
753
737
  i0.ɵɵconditional(ctx.ShowDialog ? 0 : -1);
754
- } }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective], styles: ["\n\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000;\n}\n\n\n\n.full-screen-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: var(--mat-sys-surface);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin: 0;\n font: var(--mat-sys-title-large);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mat-sys-primary);\n}\n\n.modal-close[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border: none;\n border-radius: var(--mat-sys-corner-full);\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-close[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mat-sys-primary);\n outline-offset: 2px;\n}\n\n\n\n.app-config-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: var(--mat-sys-surface-container-lowest);\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 1rem;\n color: var(--mat-sys-on-surface-variant);\n}\n\n\n\n.error-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--mat-sys-error-container);\n color: var(--mat-sys-on-error-container);\n border-bottom: 1px solid var(--mat-sys-error);\n}\n\n.error-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.1rem;\n}\n\n\n\n.config-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 1.5rem;\n overflow: hidden;\n}\n\n.config-description[_ngcontent-%COMP%] {\n margin: 0 0 1.5rem 0;\n color: var(--mat-sys-on-surface-variant);\n font: var(--mat-sys-body-large);\n line-height: 1.5;\n}\n\n\n\n.panels-container[_ngcontent-%COMP%] {\n flex: 1;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1.5rem;\n overflow: hidden;\n}\n\n@media (max-width: 900px) {\n .panels-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow-y: auto;\n }\n\n \n\n .panel-header[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%] {\n display: inline-block !important;\n color: var(--mat-sys-on-surface-variant) !important;\n }\n\n \n\n .panel-header[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n }\n\n .panel-header[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container);\n }\n\n \n\n .panel.collapsed[_ngcontent-%COMP%] {\n flex: 0 0 auto !important;\n }\n\n .panel.collapsed[_ngcontent-%COMP%] .panel-content[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .panel.collapsed[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n border-bottom: none;\n }\n\n \n\n .panel[_ngcontent-%COMP%]:not(.collapsed) {\n flex: 1 1 auto;\n min-height: 150px;\n }\n}\n\n\n\n.panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-medium);\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 1rem 1.25rem;\n background: var(--mat-sys-surface-container);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.panel-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 1.1rem;\n color: var(--mat-sys-primary);\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font: var(--mat-sys-title-medium);\n color: var(--mat-sys-on-surface);\n flex: 1;\n}\n\n.panel-header[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary);\n padding: 0.125rem 0.625rem;\n border-radius: var(--mat-sys-corner-full);\n font: var(--mat-sys-label-medium);\n font-weight: 500;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%] {\n display: none;\n color: var(--mat-sys-on-surface-variant);\n font-size: 0.9rem;\n margin-left: 0.5rem;\n}\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 1.5rem;\n color: var(--mat-sys-on-surface-variant);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font: var(--mat-sys-body-large);\n}\n\n.empty-state[_ngcontent-%COMP%] .hint[_ngcontent-%COMP%] {\n margin-top: 0.25rem;\n font: var(--mat-sys-body-medium);\n opacity: 0.7;\n}\n\n\n\n.sortable-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n\n\n.app-item[_ngcontent-%COMP%] {\n cursor: grab;\n transition: transform 0.2s, opacity 0.2s;\n}\n\n.app-item[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.app-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n transform: scale(0.98);\n}\n\n.app-item-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-left-width: 4px;\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.app-item-content[_ngcontent-%COMP%]:hover {\n border-color: var(--mat-sys-primary);\n box-shadow: var(--mat-sys-elevation-1);\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n color: var(--mat-sys-on-surface-variant);\n cursor: grab;\n padding: 0.25rem;\n}\n\n.drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: var(--mat-sys-corner-small);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n font: var(--mat-sys-body-large);\n font-weight: 500;\n color: var(--mat-sys-on-surface);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-description[_ngcontent-%COMP%] {\n font: var(--mat-sys-body-small);\n color: var(--mat-sys-on-surface-variant);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n flex-shrink: 0;\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%]:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-sm[_ngcontent-%COMP%] {\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n font-size: 0.8rem;\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n\n\n.available-app-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-bottom: 0.5rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.available-app-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mat-sys-primary);\n background: var(--mat-sys-surface-container);\n}\n\n.available-app-item[_ngcontent-%COMP%] .app-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-top: 1px solid var(--mat-sys-outline-variant);\n}\n\n.footer-left[_ngcontent-%COMP%], \n.footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n}\n\n.dialog-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n\n\n\n\n\n\n\n.mobile-view[_ngcontent-%COMP%] {\n display: none;\n}\n\n@media (max-width: 600px) {\n \n\n .desktop-only[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .config-description[_ngcontent-%COMP%] {\n display: none;\n }\n\n .mobile-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .mobile-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0.5rem;\n }\n\n \n\n .mobile-section-label[_ngcontent-%COMP%] {\n padding: 0.5rem 0.625rem 0.25rem;\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--mj-text-secondary);\n }\n\n \n\n .mobile-app-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.625rem;\n border-radius: var(--mj-radius-md);\n transition: background-color 0.15s ease;\n }\n\n .mobile-app-row.inactive[_ngcontent-%COMP%] {\n opacity: 0.7;\n }\n\n .mobile-app-row[_ngcontent-%COMP%] .app-icon[_ngcontent-%COMP%] {\n width: 2rem;\n height: 2rem;\n font-size: 0.875rem;\n flex-shrink: 0;\n }\n\n .mobile-app-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n \n\n .mobile-drag-handle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.5rem;\n flex-shrink: 0;\n color: var(--mj-text-muted);\n font-size: 0.875rem;\n touch-action: none;\n cursor: grab;\n padding: 0.5rem 0;\n }\n\n .mobile-drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n color: var(--mj-text-primary);\n }\n\n \n\n .mobile-app-row.touch-dragging[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n box-shadow: var(--mj-shadow-lg);\n border-radius: var(--mj-radius-md);\n position: relative;\n z-index: 100;\n opacity: 0.95;\n }\n\n \n\n .mobile-app-row.touch-ghost[_ngcontent-%COMP%] {\n opacity: 0.3;\n }\n\n \n\n .mobile-drop-indicator[_ngcontent-%COMP%] {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 0.625rem;\n }\n\n \n\n .mobile-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n padding: 0.25rem;\n cursor: pointer;\n font-size: 1.5rem;\n flex-shrink: 0;\n transition: color 0.15s ease;\n min-width: 44px;\n min-height: 44px;\n }\n\n .mobile-toggle.on[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .mobile-toggle.off[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n }\n\n \n\n .modal-header[_ngcontent-%COMP%] {\n padding: 0.75rem 1rem;\n }\n\n .modal-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n \n\n .config-content[_ngcontent-%COMP%] {\n padding: 0;\n }\n\n \n\n .dialog-footer[_ngcontent-%COMP%] {\n padding: 0.75rem;\n gap: 0.5rem;\n }\n\n .footer-left[_ngcontent-%COMP%], \n .footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n }\n\n .dialog-footer[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 38px;\n }\n}\n\n\n\n@media (prefers-reduced-motion: reduce) {\n .app-item[_ngcontent-%COMP%], \n .app-item-content[_ngcontent-%COMP%], \n .available-app-item[_ngcontent-%COMP%], \n .modal-close[_ngcontent-%COMP%] {\n transition: none;\n }\n}"] });
738
+ } }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJEmptyStateComponent, i2.MJAlertComponent], styles: ["\n\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000;\n}\n\n\n\n.full-screen-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: var(--mat-sys-surface);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin: 0;\n font: var(--mat-sys-title-large);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mat-sys-primary);\n}\n\n.modal-close[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border: none;\n border-radius: var(--mat-sys-corner-full);\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-close[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mat-sys-primary);\n outline-offset: 2px;\n}\n\n\n\n.app-config-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: var(--mat-sys-surface-container-lowest);\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 1rem;\n color: var(--mat-sys-on-surface-variant);\n}\n\n\n\n\n.config-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 1.5rem;\n overflow: hidden;\n}\n\n.config-description[_ngcontent-%COMP%] {\n margin: 0 0 1.5rem 0;\n color: var(--mat-sys-on-surface-variant);\n font: var(--mat-sys-body-large);\n line-height: 1.5;\n}\n\n\n\n.panels-container[_ngcontent-%COMP%] {\n flex: 1;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1.5rem;\n overflow: hidden;\n}\n\n@media (max-width: 900px) {\n .panels-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow-y: auto;\n }\n\n \n\n .panel-header[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%] {\n display: inline-block !important;\n color: var(--mat-sys-on-surface-variant) !important;\n }\n\n \n\n .panel-header[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n }\n\n .panel-header[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container);\n }\n\n \n\n .panel.collapsed[_ngcontent-%COMP%] {\n flex: 0 0 auto !important;\n }\n\n .panel.collapsed[_ngcontent-%COMP%] .panel-content[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .panel.collapsed[_ngcontent-%COMP%] .panel-header[_ngcontent-%COMP%] {\n border-bottom: none;\n }\n\n \n\n .panel[_ngcontent-%COMP%]:not(.collapsed) {\n flex: 1 1 auto;\n min-height: 150px;\n }\n}\n\n\n\n.panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-medium);\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 1rem 1.25rem;\n background: var(--mat-sys-surface-container);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.panel-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 1.1rem;\n color: var(--mat-sys-primary);\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font: var(--mat-sys-title-medium);\n color: var(--mat-sys-on-surface);\n flex: 1;\n}\n\n.panel-header[_ngcontent-%COMP%] .badge[_ngcontent-%COMP%] {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary);\n padding: 0.125rem 0.625rem;\n border-radius: var(--mat-sys-corner-full);\n font: var(--mat-sys-label-medium);\n font-weight: 500;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%] {\n display: none;\n color: var(--mat-sys-on-surface-variant);\n font-size: 0.9rem;\n margin-left: 0.5rem;\n}\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n}\n\n\n\n\n.sortable-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n\n\n.app-item[_ngcontent-%COMP%] {\n cursor: grab;\n transition: transform 0.2s, opacity 0.2s;\n}\n\n.app-item[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.app-item.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n transform: scale(0.98);\n}\n\n.app-item-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-left-width: 4px;\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.app-item-content[_ngcontent-%COMP%]:hover {\n border-color: var(--mat-sys-primary);\n box-shadow: var(--mat-sys-elevation-1);\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n color: var(--mat-sys-on-surface-variant);\n cursor: grab;\n padding: 0.25rem;\n}\n\n.drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: var(--mat-sys-corner-small);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n font: var(--mat-sys-body-large);\n font-weight: 500;\n color: var(--mat-sys-on-surface);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-description[_ngcontent-%COMP%] {\n font: var(--mat-sys-body-small);\n color: var(--mat-sys-on-surface-variant);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n flex-shrink: 0;\n}\n\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-ghost[_ngcontent-%COMP%]:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-sm[_ngcontent-%COMP%] {\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n font-size: 0.8rem;\n}\n\n.app-actions[_ngcontent-%COMP%] .mj-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n\n\n.available-app-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-bottom: 0.5rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.available-app-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mat-sys-primary);\n background: var(--mat-sys-surface-container);\n}\n\n.available-app-item[_ngcontent-%COMP%] .app-info[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n\n\n.dialog-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-top: 1px solid var(--mat-sys-outline-variant);\n}\n\n.footer-left[_ngcontent-%COMP%], \n.footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n}\n\n.dialog-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n\n\n\n\n\n\n\n.mobile-view[_ngcontent-%COMP%] {\n display: none;\n}\n\n@media (max-width: 600px) {\n \n\n .desktop-only[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .config-description[_ngcontent-%COMP%] {\n display: none;\n }\n\n .mobile-view[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .mobile-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 0.5rem;\n }\n\n \n\n .mobile-section-label[_ngcontent-%COMP%] {\n padding: 0.5rem 0.625rem 0.25rem;\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--mj-text-secondary);\n }\n\n \n\n .mobile-app-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.625rem;\n border-radius: var(--mj-radius-md);\n transition: background-color 0.15s ease;\n }\n\n .mobile-app-row.inactive[_ngcontent-%COMP%] {\n opacity: 0.7;\n }\n\n .mobile-app-row[_ngcontent-%COMP%] .app-icon[_ngcontent-%COMP%] {\n width: 2rem;\n height: 2rem;\n font-size: 0.875rem;\n flex-shrink: 0;\n }\n\n .mobile-app-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n \n\n .mobile-drag-handle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.5rem;\n flex-shrink: 0;\n color: var(--mj-text-muted);\n font-size: 0.875rem;\n touch-action: none;\n cursor: grab;\n padding: 0.5rem 0;\n }\n\n .mobile-drag-handle[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n color: var(--mj-text-primary);\n }\n\n \n\n .mobile-app-row.touch-dragging[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n box-shadow: var(--mj-shadow-lg);\n border-radius: var(--mj-radius-md);\n position: relative;\n z-index: 100;\n opacity: 0.95;\n }\n\n \n\n .mobile-app-row.touch-ghost[_ngcontent-%COMP%] {\n opacity: 0.3;\n }\n\n \n\n .mobile-drop-indicator[_ngcontent-%COMP%] {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 0.625rem;\n }\n\n \n\n .mobile-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n padding: 0.25rem;\n cursor: pointer;\n font-size: 1.5rem;\n flex-shrink: 0;\n transition: color 0.15s ease;\n min-width: 44px;\n min-height: 44px;\n }\n\n .mobile-toggle.on[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n }\n\n .mobile-toggle.off[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n }\n\n \n\n .modal-header[_ngcontent-%COMP%] {\n padding: 0.75rem 1rem;\n }\n\n .modal-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n \n\n .config-content[_ngcontent-%COMP%] {\n padding: 0;\n }\n\n \n\n .dialog-footer[_ngcontent-%COMP%] {\n padding: 0.75rem;\n gap: 0.5rem;\n }\n\n .footer-left[_ngcontent-%COMP%], \n .footer-right[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n }\n\n}\n\n\n\n@media (prefers-reduced-motion: reduce) {\n .app-item[_ngcontent-%COMP%], \n .app-item-content[_ngcontent-%COMP%], \n .available-app-item[_ngcontent-%COMP%], \n .modal-close[_ngcontent-%COMP%] {\n transition: none;\n }\n}"] });
755
739
  }
756
740
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserAppConfigComponent, [{
757
741
  type: Component,
758
- args: [{ standalone: false, selector: 'mj-user-app-config', template: "<!-- Modal Backdrop -->\n@if (ShowDialog) {\n <div class=\"modal-backdrop\" (click)=\"Close()\" role=\"presentation\"></div>\n <div\n class=\"modal-dialog full-screen-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"app-config-title\"\n >\n <!-- Dialog Header -->\n <div class=\"modal-header\">\n <h2 class=\"modal-title\" id=\"app-config-title\">\n <i class=\"fa-solid fa-grid-2\" aria-hidden=\"true\"></i>\n Configure Apps\n </h2>\n <button\n class=\"modal-close\"\n (click)=\"Close()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"app-config-container\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\">\n <mj-loading text=\"Loading your app configuration...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error Message -->\n @if (ErrorMessage) {\n <div class=\"error-message\" role=\"alert\">\n <i class=\"fa-solid fa-circle-exclamation\" aria-hidden=\"true\"></i>\n <span>{{ ErrorMessage }}</span>\n </div>\n }\n\n <!-- Main Content -->\n @if (!IsLoading) {\n <div class=\"config-content\">\n <p class=\"config-description\">\n Select which applications appear in your app switcher and arrange them in your preferred order.\n Double-click to quickly add or remove. Drag and drop to reorder, or use the arrow buttons.\n </p>\n\n <!-- Desktop: two-panel layout with drag-and-drop -->\n <div class=\"panels-container desktop-only\">\n <!-- Available Apps Panel -->\n <div class=\"panel available-apps-panel\" [class.collapsed]=\"AvailablePanelCollapsed\">\n <div class=\"panel-header\" (click)=\"AvailablePanelCollapsed = !AvailablePanelCollapsed\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i>\n <h3>Available Applications</h3>\n <span class=\"badge\">{{ AvailableApps.length }}</span>\n <i\n class=\"collapse-toggle fa-solid\"\n [class.fa-chevron-down]=\"AvailablePanelCollapsed\"\n [class.fa-chevron-up]=\"!AvailablePanelCollapsed\"\n aria-hidden=\"true\"\n ></i>\n </div>\n\n <div class=\"panel-content\">\n @if (AvailableApps.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-check-double\" aria-hidden=\"true\"></i>\n <p>All applications added!</p>\n </div>\n }\n\n @for (item of AvailableApps; track item.app.ID) {\n <div class=\"available-app-item\" (dblclick)=\"AddApp(item)\">\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.app.Name }}</span>\n @if (item.app.Description) {\n <span class=\"app-description\">{{ item.app.Description }}</span>\n }\n </div>\n\n <button\n mjButton variant=\"outline\" size=\"sm\"\n (click)=\"AddApp(item)\"\n title=\"Add to your apps\"\n [attr.aria-label]=\"'Add ' + item.app.Name\"\n >\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n Add\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- Selected Apps Panel -->\n <div class=\"panel selected-apps-panel\" [class.collapsed]=\"SelectedPanelCollapsed\">\n <div class=\"panel-header\" (click)=\"SelectedPanelCollapsed = !SelectedPanelCollapsed\">\n <i class=\"fa-solid fa-check-circle\" aria-hidden=\"true\"></i>\n <h3>Your Applications</h3>\n <span class=\"badge\">{{ ActiveApps.length }}</span>\n <i\n class=\"collapse-toggle fa-solid\"\n [class.fa-chevron-down]=\"SelectedPanelCollapsed\"\n [class.fa-chevron-up]=\"!SelectedPanelCollapsed\"\n aria-hidden=\"true\"\n ></i>\n </div>\n\n <div class=\"panel-content\">\n @if (ActiveApps.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-inbox\" aria-hidden=\"true\"></i>\n <p>No applications selected</p>\n <p class=\"hint\">Add apps from the available list</p>\n </div>\n }\n\n @if (ActiveApps.length > 0) {\n <div\n class=\"sortable-list\"\n (dragover)=\"OnDragOver($event)\"\n (drop)=\"OnDrop($event)\"\n >\n @for (item of ActiveApps; track item.app.ID; let i = $index) {\n <div\n class=\"app-item\"\n [class.dragging]=\"DraggedItem === item\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, item, i)\"\n (dragend)=\"OnDragEnd()\"\n (dragenter)=\"OnDragEnter($event, i)\"\n (dblclick)=\"RemoveApp(item); $event.stopPropagation()\"\n >\n <div class=\"app-item-content\" [style.border-left-color]=\"item.app.GetColor()\">\n <div class=\"drag-handle\">\n <i class=\"fa-solid fa-grip-vertical\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.app.Name }}</span>\n @if (item.app.Description) {\n <span class=\"app-description\">{{ item.app.Description }}</span>\n }\n </div>\n\n <div class=\"app-actions\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n [disabled]=\"i === 0\"\n (click)=\"MoveUp(item); $event.stopPropagation()\"\n title=\"Move up\"\n [attr.aria-label]=\"'Move ' + item.app.Name + ' up'\"\n >\n <i class=\"fa-solid fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n [disabled]=\"i === ActiveApps.length - 1\"\n (click)=\"MoveDown(item); $event.stopPropagation()\"\n title=\"Move down\"\n [attr.aria-label]=\"'Move ' + item.app.Name + ' down'\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"RemoveApp(item); $event.stopPropagation()\"\n title=\"Remove from your apps\"\n [attr.aria-label]=\"'Remove ' + item.app.Name\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Mobile: single list with toggles + touch drag reorder -->\n <div\n class=\"mobile-view\"\n (touchmove)=\"OnTouchDragMove($event)\"\n (touchend)=\"OnTouchDragEnd()\"\n (touchcancel)=\"OnTouchDragEnd()\"\n >\n <div class=\"mobile-list\">\n @if (ActiveApps.length > 0) {\n <div class=\"mobile-section-label\">Your Apps</div>\n @for (item of ActiveApps; track item.app.ID; let i = $index) {\n @if (TouchDragActive && TouchDropIndex === i && TouchDragIndex > i) {\n <div class=\"mobile-drop-indicator\"></div>\n }\n <div\n class=\"mobile-app-row\"\n [class.touch-ghost]=\"TouchDragActive && TouchDragIndex === i\"\n >\n <div\n class=\"mobile-drag-handle\"\n (touchstart)=\"OnTouchDragStart($event, i)\"\n aria-label=\"Drag to reorder\"\n >\n <i class=\"fa-solid fa-grip-vertical\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n <span class=\"mobile-app-name\">{{ item.app.Name }}</span>\n <button\n class=\"mobile-toggle on\"\n (click)=\"ToggleApp(item)\"\n aria-label=\"Remove {{ item.app.Name }}\"\n >\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n </button>\n </div>\n @if (TouchDragActive && TouchDropIndex === i && TouchDragIndex < i) {\n <div class=\"mobile-drop-indicator\"></div>\n }\n }\n @if (TouchDragActive && TouchDropIndex === ActiveApps.length - 1 && TouchDragIndex < TouchDropIndex) {\n <div class=\"mobile-drop-indicator\"></div>\n }\n }\n\n @if (AvailableApps.length > 0) {\n <div class=\"mobile-section-label\">Available</div>\n @for (item of AvailableApps; track item.app.ID) {\n <div class=\"mobile-app-row inactive\">\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n <span class=\"mobile-app-name\">{{ item.app.Name }}</span>\n <button\n class=\"mobile-toggle off\"\n (click)=\"ToggleApp(item)\"\n aria-label=\"Add {{ item.app.Name }}\"\n >\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Footer Actions -->\n <div class=\"dialog-footer\">\n <div class=\"footer-left\">\n @if (HasChanges()) {\n <button\n mjButton\n (click)=\"Reset()\"\n [disabled]=\"IsLoading || IsSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n Reset Changes\n </button>\n }\n </div>\n <div class=\"footer-right\">\n <button\n mjButton variant=\"primary\"\n (click)=\"Save()\"\n [disabled]=\"IsLoading || IsSaving || !HasChanges()\"\n >\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span>Save Changes</span>\n }\n </button>\n <button\n mjButton\n (click)=\"Close()\"\n [disabled]=\"IsSaving\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", styles: ["/* ============================================\n User App Config - MD3 Design System\n ============================================ */\n\n/* Modal Backdrop */\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000;\n}\n\n/* Full-screen dialog */\n.full-screen-dialog {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: var(--mat-sys-surface);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n}\n\n/* Modal Header */\n.modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin: 0;\n font: var(--mat-sys-title-large);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-title i {\n color: var(--mat-sys-primary);\n}\n\n.modal-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border: none;\n border-radius: var(--mat-sys-corner-full);\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.modal-close:hover {\n background: var(--mat-sys-surface-container);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-close:focus-visible {\n outline: 2px solid var(--mat-sys-primary);\n outline-offset: 2px;\n}\n\n/* Main container */\n.app-config-container {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: var(--mat-sys-surface-container-lowest);\n}\n\n/* Loading state */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 1rem;\n color: var(--mat-sys-on-surface-variant);\n}\n\n/* Error message */\n.error-message {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--mat-sys-error-container);\n color: var(--mat-sys-on-error-container);\n border-bottom: 1px solid var(--mat-sys-error);\n}\n\n.error-message i {\n font-size: 1.1rem;\n}\n\n/* Config content */\n.config-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 1.5rem;\n overflow: hidden;\n}\n\n.config-description {\n margin: 0 0 1.5rem 0;\n color: var(--mat-sys-on-surface-variant);\n font: var(--mat-sys-body-large);\n line-height: 1.5;\n}\n\n/* Panels container */\n.panels-container {\n flex: 1;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1.5rem;\n overflow: hidden;\n}\n\n@media (max-width: 900px) {\n .panels-container {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow-y: auto;\n }\n\n /* Show collapse toggle on mobile */\n .panel-header .collapse-toggle {\n display: inline-block !important;\n color: var(--mat-sys-on-surface-variant) !important;\n }\n\n /* Make header clickable on mobile */\n .panel-header {\n cursor: pointer;\n user-select: none;\n }\n\n .panel-header:hover {\n background: var(--mat-sys-surface-container);\n }\n\n /* Collapsed panel - just show header */\n .panel.collapsed {\n flex: 0 0 auto !important;\n }\n\n .panel.collapsed .panel-content {\n display: none !important;\n }\n\n .panel.collapsed .panel-header {\n border-bottom: none;\n }\n\n /* Non-collapsed panel takes available space */\n .panel:not(.collapsed) {\n flex: 1 1 auto;\n min-height: 150px;\n }\n}\n\n/* Panel styles */\n.panel {\n display: flex;\n flex-direction: column;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-medium);\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 1rem 1.25rem;\n background: var(--mat-sys-surface-container);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.panel-header i:first-child {\n font-size: 1.1rem;\n color: var(--mat-sys-primary);\n}\n\n.panel-header h3 {\n margin: 0;\n font: var(--mat-sys-title-medium);\n color: var(--mat-sys-on-surface);\n flex: 1;\n}\n\n.panel-header .badge {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary);\n padding: 0.125rem 0.625rem;\n border-radius: var(--mat-sys-corner-full);\n font: var(--mat-sys-label-medium);\n font-weight: 500;\n}\n\n/* Collapse toggle - hidden by default, shown on mobile */\n.panel-header .collapse-toggle {\n display: none;\n color: var(--mat-sys-on-surface-variant);\n font-size: 0.9rem;\n margin-left: 0.5rem;\n}\n\n.panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n}\n\n/* Empty state */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 3rem 1.5rem;\n color: var(--mat-sys-on-surface-variant);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n opacity: 0.5;\n}\n\n.empty-state p {\n margin: 0;\n font: var(--mat-sys-body-large);\n}\n\n.empty-state .hint {\n margin-top: 0.25rem;\n font: var(--mat-sys-body-medium);\n opacity: 0.7;\n}\n\n/* Sortable list container */\n.sortable-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n/* App items */\n.app-item {\n cursor: grab;\n transition: transform 0.2s, opacity 0.2s;\n}\n\n.app-item:active {\n cursor: grabbing;\n}\n\n.app-item.dragging {\n opacity: 0.5;\n transform: scale(0.98);\n}\n\n.app-item-content {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-left-width: 4px;\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.app-item-content:hover {\n border-color: var(--mat-sys-primary);\n box-shadow: var(--mat-sys-elevation-1);\n}\n\n.drag-handle {\n color: var(--mat-sys-on-surface-variant);\n cursor: grab;\n padding: 0.25rem;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n}\n\n.app-icon {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: var(--mat-sys-corner-small);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.app-info {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n min-width: 0;\n}\n\n.app-name {\n font: var(--mat-sys-body-large);\n font-weight: 500;\n color: var(--mat-sys-on-surface);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-description {\n font: var(--mat-sys-body-small);\n color: var(--mat-sys-on-surface-variant);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-actions {\n display: flex;\n gap: 0.25rem;\n flex-shrink: 0;\n}\n\n.app-actions .mj-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.app-actions .mj-btn-ghost {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.app-actions .mj-btn-ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.app-actions .mj-btn-ghost:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.app-actions .mj-btn-sm {\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n font-size: 0.8rem;\n}\n\n.app-actions .mj-btn-danger:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n/* Available app items */\n.available-app-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-bottom: 0.5rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.available-app-item:hover {\n border-color: var(--mat-sys-primary);\n background: var(--mat-sys-surface-container);\n}\n\n.available-app-item .app-info {\n flex: 1;\n}\n\n/* Dialog footer */\n.dialog-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-top: 1px solid var(--mat-sys-outline-variant);\n}\n\n.footer-left,\n.footer-right {\n display: flex;\n gap: 0.75rem;\n}\n\n.dialog-footer button {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* ==============================================\n Mobile: single list with toggles\n ============================================== */\n\n/* Hidden by default on desktop */\n.mobile-view {\n display: none;\n}\n\n@media (max-width: 600px) {\n /* Swap layouts */\n .desktop-only {\n display: none !important;\n }\n\n .config-description {\n display: none;\n }\n\n .mobile-view {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .mobile-list {\n flex: 1;\n overflow-y: auto;\n padding: 0.5rem;\n }\n\n /* Section labels */\n .mobile-section-label {\n padding: 0.5rem 0.625rem 0.25rem;\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--mj-text-secondary);\n }\n\n /* App rows */\n .mobile-app-row {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.625rem;\n border-radius: var(--mj-radius-md);\n transition: background-color 0.15s ease;\n }\n\n .mobile-app-row.inactive {\n opacity: 0.7;\n }\n\n .mobile-app-row .app-icon {\n width: 2rem;\n height: 2rem;\n font-size: 0.875rem;\n flex-shrink: 0;\n }\n\n .mobile-app-name {\n flex: 1;\n min-width: 0;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n /* Drag handle */\n .mobile-drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.5rem;\n flex-shrink: 0;\n color: var(--mj-text-muted);\n font-size: 0.875rem;\n touch-action: none;\n cursor: grab;\n padding: 0.5rem 0;\n }\n\n .mobile-drag-handle:active {\n cursor: grabbing;\n color: var(--mj-text-primary);\n }\n\n /* Dragging row */\n .mobile-app-row.touch-dragging {\n background: var(--mj-bg-surface-hover);\n box-shadow: var(--mj-shadow-lg);\n border-radius: var(--mj-radius-md);\n position: relative;\n z-index: 100;\n opacity: 0.95;\n }\n\n /* Ghost placeholder for the original position */\n .mobile-app-row.touch-ghost {\n opacity: 0.3;\n }\n\n /* Drop indicator line */\n .mobile-drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 0.625rem;\n }\n\n /* Toggle button */\n .mobile-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n padding: 0.25rem;\n cursor: pointer;\n font-size: 1.5rem;\n flex-shrink: 0;\n transition: color 0.15s ease;\n min-width: 44px;\n min-height: 44px;\n }\n\n .mobile-toggle.on {\n color: var(--mj-brand-primary);\n }\n\n .mobile-toggle.off {\n color: var(--mj-text-muted);\n }\n\n /* Header compact */\n .modal-header {\n padding: 0.75rem 1rem;\n }\n\n .modal-title {\n font-size: 1.125rem;\n }\n\n /* Content compact */\n .config-content {\n padding: 0;\n }\n\n /* Footer compact */\n .dialog-footer {\n padding: 0.75rem;\n gap: 0.5rem;\n }\n\n .footer-left,\n .footer-right {\n display: flex;\n gap: 0.5rem;\n }\n\n .dialog-footer .mj-btn {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 38px;\n }\n}\n\n/* Accessibility - Reduced Motion */\n@media (prefers-reduced-motion: reduce) {\n .app-item,\n .app-item-content,\n .available-app-item,\n .modal-close {\n transition: none;\n }\n}\n"] }]
742
+ args: [{ standalone: false, selector: 'mj-user-app-config', template: "<!-- Modal Backdrop -->\n@if (ShowDialog) {\n <div class=\"modal-backdrop\" (click)=\"Close()\" role=\"presentation\"></div>\n <div\n class=\"modal-dialog full-screen-dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"app-config-title\"\n >\n <!-- Dialog Header -->\n <div class=\"modal-header\">\n <h2 class=\"modal-title\" id=\"app-config-title\">\n <i class=\"fa-solid fa-grid-2\" aria-hidden=\"true\"></i>\n Configure Apps\n </h2>\n <button\n class=\"modal-close\"\n (click)=\"Close()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"app-config-container\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\">\n <mj-loading text=\"Loading your app configuration...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error Message -->\n @if (ErrorMessage) {\n <mj-alert Variant=\"error\">{{ ErrorMessage }}</mj-alert>\n }\n\n <!-- Main Content -->\n @if (!IsLoading) {\n <div class=\"config-content\">\n <p class=\"config-description\">\n Select which applications appear in your app switcher and arrange them in your preferred order.\n Double-click to quickly add or remove. Drag and drop to reorder, or use the arrow buttons.\n </p>\n\n <!-- Desktop: two-panel layout with drag-and-drop -->\n <div class=\"panels-container desktop-only\">\n <!-- Available Apps Panel -->\n <div class=\"panel available-apps-panel\" [class.collapsed]=\"AvailablePanelCollapsed\">\n <div class=\"panel-header\" (click)=\"AvailablePanelCollapsed = !AvailablePanelCollapsed\">\n <i class=\"fa-solid fa-layer-group\" aria-hidden=\"true\"></i>\n <h3>Available Applications</h3>\n <span class=\"badge\">{{ AvailableApps.length }}</span>\n <i\n class=\"collapse-toggle fa-solid\"\n [class.fa-chevron-down]=\"AvailablePanelCollapsed\"\n [class.fa-chevron-up]=\"!AvailablePanelCollapsed\"\n aria-hidden=\"true\"\n ></i>\n </div>\n\n <div class=\"panel-content\">\n @if (AvailableApps.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-check-double\"\n Title=\"All applications added!\" />\n }\n\n @for (item of AvailableApps; track item.app.ID) {\n <div class=\"available-app-item\" (dblclick)=\"AddApp(item)\">\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.app.Name }}</span>\n @if (item.app.Description) {\n <span class=\"app-description\">{{ item.app.Description }}</span>\n }\n </div>\n\n <button\n mjButton variant=\"outline\" size=\"sm\"\n (click)=\"AddApp(item)\"\n title=\"Add to your apps\"\n [attr.aria-label]=\"'Add ' + item.app.Name\"\n >\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n Add\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- Selected Apps Panel -->\n <div class=\"panel selected-apps-panel\" [class.collapsed]=\"SelectedPanelCollapsed\">\n <div class=\"panel-header\" (click)=\"SelectedPanelCollapsed = !SelectedPanelCollapsed\">\n <i class=\"fa-solid fa-check-circle\" aria-hidden=\"true\"></i>\n <h3>Your Applications</h3>\n <span class=\"badge\">{{ ActiveApps.length }}</span>\n <i\n class=\"collapse-toggle fa-solid\"\n [class.fa-chevron-down]=\"SelectedPanelCollapsed\"\n [class.fa-chevron-up]=\"!SelectedPanelCollapsed\"\n aria-hidden=\"true\"\n ></i>\n </div>\n\n <div class=\"panel-content\">\n @if (ActiveApps.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-inbox\"\n Title=\"No applications selected\"\n Message=\"Add apps from the available list\" />\n }\n\n @if (ActiveApps.length > 0) {\n <div\n class=\"sortable-list\"\n (dragover)=\"OnDragOver($event)\"\n (drop)=\"OnDrop($event)\"\n >\n @for (item of ActiveApps; track item.app.ID; let i = $index) {\n <div\n class=\"app-item\"\n [class.dragging]=\"DraggedItem === item\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, item, i)\"\n (dragend)=\"OnDragEnd()\"\n (dragenter)=\"OnDragEnter($event, i)\"\n (dblclick)=\"RemoveApp(item); $event.stopPropagation()\"\n >\n <div class=\"app-item-content\" [style.border-left-color]=\"item.app.GetColor()\">\n <div class=\"drag-handle\">\n <i class=\"fa-solid fa-grip-vertical\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.app.Name }}</span>\n @if (item.app.Description) {\n <span class=\"app-description\">{{ item.app.Description }}</span>\n }\n </div>\n\n <div class=\"app-actions\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n [disabled]=\"i === 0\"\n (click)=\"MoveUp(item); $event.stopPropagation()\"\n title=\"Move up\"\n [attr.aria-label]=\"'Move ' + item.app.Name + ' up'\"\n >\n <i class=\"fa-solid fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n [disabled]=\"i === ActiveApps.length - 1\"\n (click)=\"MoveDown(item); $event.stopPropagation()\"\n title=\"Move down\"\n [attr.aria-label]=\"'Move ' + item.app.Name + ' down'\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"RemoveApp(item); $event.stopPropagation()\"\n title=\"Remove from your apps\"\n [attr.aria-label]=\"'Remove ' + item.app.Name\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Mobile: single list with toggles + touch drag reorder -->\n <div\n class=\"mobile-view\"\n (touchmove)=\"OnTouchDragMove($event)\"\n (touchend)=\"OnTouchDragEnd()\"\n (touchcancel)=\"OnTouchDragEnd()\"\n >\n <div class=\"mobile-list\">\n @if (ActiveApps.length > 0) {\n <div class=\"mobile-section-label\">Your Apps</div>\n @for (item of ActiveApps; track item.app.ID; let i = $index) {\n @if (TouchDragActive && TouchDropIndex === i && TouchDragIndex > i) {\n <div class=\"mobile-drop-indicator\"></div>\n }\n <div\n class=\"mobile-app-row\"\n [class.touch-ghost]=\"TouchDragActive && TouchDragIndex === i\"\n >\n <div\n class=\"mobile-drag-handle\"\n (touchstart)=\"OnTouchDragStart($event, i)\"\n aria-label=\"Drag to reorder\"\n >\n <i class=\"fa-solid fa-grip-vertical\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n <span class=\"mobile-app-name\">{{ item.app.Name }}</span>\n <button\n class=\"mobile-toggle on\"\n (click)=\"ToggleApp(item)\"\n aria-label=\"Remove {{ item.app.Name }}\"\n >\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n </button>\n </div>\n @if (TouchDragActive && TouchDropIndex === i && TouchDragIndex < i) {\n <div class=\"mobile-drop-indicator\"></div>\n }\n }\n @if (TouchDragActive && TouchDropIndex === ActiveApps.length - 1 && TouchDragIndex < TouchDropIndex) {\n <div class=\"mobile-drop-indicator\"></div>\n }\n }\n\n @if (AvailableApps.length > 0) {\n <div class=\"mobile-section-label\">Available</div>\n @for (item of AvailableApps; track item.app.ID) {\n <div class=\"mobile-app-row inactive\">\n <div class=\"app-icon\" [style.background-color]=\"item.app.GetColor()\">\n <i [class]=\"item.app.Icon || 'fa-solid fa-cube'\" aria-hidden=\"true\"></i>\n </div>\n <span class=\"mobile-app-name\">{{ item.app.Name }}</span>\n <button\n class=\"mobile-toggle off\"\n (click)=\"ToggleApp(item)\"\n aria-label=\"Add {{ item.app.Name }}\"\n >\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Footer Actions -->\n <div class=\"dialog-footer\">\n <div class=\"footer-left\">\n @if (HasChanges()) {\n <button\n mjButton\n (click)=\"Reset()\"\n [disabled]=\"IsLoading || IsSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n Reset Changes\n </button>\n }\n </div>\n <div class=\"footer-right\">\n <button\n mjButton variant=\"primary\"\n (click)=\"Save()\"\n [disabled]=\"IsLoading || IsSaving || !HasChanges()\"\n >\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span>Save Changes</span>\n }\n </button>\n <button\n mjButton\n (click)=\"Close()\"\n [disabled]=\"IsSaving\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", styles: ["/* ============================================\n User App Config - MD3 Design System\n ============================================ */\n\n/* Modal Backdrop */\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: rgba(0, 0, 0, 0.5);\n z-index: 1000;\n}\n\n/* Full-screen dialog */\n.full-screen-dialog {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n background: var(--mat-sys-surface);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n}\n\n/* Modal Header */\n.modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin: 0;\n font: var(--mat-sys-title-large);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-title i {\n color: var(--mat-sys-primary);\n}\n\n.modal-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2.5rem;\n height: 2.5rem;\n border: none;\n border-radius: var(--mat-sys-corner-full);\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.modal-close:hover {\n background: var(--mat-sys-surface-container);\n color: var(--mat-sys-on-surface);\n}\n\n.modal-close:focus-visible {\n outline: 2px solid var(--mat-sys-primary);\n outline-offset: 2px;\n}\n\n/* Main container */\n.app-config-container {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n background: var(--mat-sys-surface-container-lowest);\n}\n\n/* Loading state */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n gap: 1rem;\n color: var(--mat-sys-on-surface-variant);\n}\n\n\n/* Config content */\n.config-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 1.5rem;\n overflow: hidden;\n}\n\n.config-description {\n margin: 0 0 1.5rem 0;\n color: var(--mat-sys-on-surface-variant);\n font: var(--mat-sys-body-large);\n line-height: 1.5;\n}\n\n/* Panels container */\n.panels-container {\n flex: 1;\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1.5rem;\n overflow: hidden;\n}\n\n@media (max-width: 900px) {\n .panels-container {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow-y: auto;\n }\n\n /* Show collapse toggle on mobile */\n .panel-header .collapse-toggle {\n display: inline-block !important;\n color: var(--mat-sys-on-surface-variant) !important;\n }\n\n /* Make header clickable on mobile */\n .panel-header {\n cursor: pointer;\n user-select: none;\n }\n\n .panel-header:hover {\n background: var(--mat-sys-surface-container);\n }\n\n /* Collapsed panel - just show header */\n .panel.collapsed {\n flex: 0 0 auto !important;\n }\n\n .panel.collapsed .panel-content {\n display: none !important;\n }\n\n .panel.collapsed .panel-header {\n border-bottom: none;\n }\n\n /* Non-collapsed panel takes available space */\n .panel:not(.collapsed) {\n flex: 1 1 auto;\n min-height: 150px;\n }\n}\n\n/* Panel styles */\n.panel {\n display: flex;\n flex-direction: column;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-medium);\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 1rem 1.25rem;\n background: var(--mat-sys-surface-container);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n}\n\n.panel-header i:first-child {\n font-size: 1.1rem;\n color: var(--mat-sys-primary);\n}\n\n.panel-header h3 {\n margin: 0;\n font: var(--mat-sys-title-medium);\n color: var(--mat-sys-on-surface);\n flex: 1;\n}\n\n.panel-header .badge {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary);\n padding: 0.125rem 0.625rem;\n border-radius: var(--mat-sys-corner-full);\n font: var(--mat-sys-label-medium);\n font-weight: 500;\n}\n\n/* Collapse toggle - hidden by default, shown on mobile */\n.panel-header .collapse-toggle {\n display: none;\n color: var(--mat-sys-on-surface-variant);\n font-size: 0.9rem;\n margin-left: 0.5rem;\n}\n\n.panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n}\n\n\n/* Sortable list container */\n.sortable-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n/* App items */\n.app-item {\n cursor: grab;\n transition: transform 0.2s, opacity 0.2s;\n}\n\n.app-item:active {\n cursor: grabbing;\n}\n\n.app-item.dragging {\n opacity: 0.5;\n transform: scale(0.98);\n}\n\n.app-item-content {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-left-width: 4px;\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.app-item-content:hover {\n border-color: var(--mat-sys-primary);\n box-shadow: var(--mat-sys-elevation-1);\n}\n\n.drag-handle {\n color: var(--mat-sys-on-surface-variant);\n cursor: grab;\n padding: 0.25rem;\n}\n\n.drag-handle:active {\n cursor: grabbing;\n}\n\n.app-icon {\n width: 2.5rem;\n height: 2.5rem;\n border-radius: var(--mat-sys-corner-small);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.app-info {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n min-width: 0;\n}\n\n.app-name {\n font: var(--mat-sys-body-large);\n font-weight: 500;\n color: var(--mat-sys-on-surface);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-description {\n font: var(--mat-sys-body-small);\n color: var(--mat-sys-on-surface-variant);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-actions {\n display: flex;\n gap: 0.25rem;\n flex-shrink: 0;\n}\n\n\n.app-actions .mj-btn-ghost {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.app-actions .mj-btn-ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.app-actions .mj-btn-ghost:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.app-actions .mj-btn-sm {\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n font-size: 0.8rem;\n}\n\n.app-actions .mj-btn-danger:hover:not(:disabled) {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error);\n}\n\n/* Available app items */\n.available-app-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-bottom: 0.5rem;\n background: var(--mat-sys-surface);\n border: 1px solid var(--mat-sys-outline-variant);\n border-radius: var(--mat-sys-corner-small);\n transition: all 0.2s ease;\n}\n\n.available-app-item:hover {\n border-color: var(--mat-sys-primary);\n background: var(--mat-sys-surface-container);\n}\n\n.available-app-item .app-info {\n flex: 1;\n}\n\n/* Dialog footer */\n.dialog-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1rem 1.5rem;\n background: var(--mat-sys-surface);\n border-top: 1px solid var(--mat-sys-outline-variant);\n}\n\n.footer-left,\n.footer-right {\n display: flex;\n gap: 0.75rem;\n}\n\n.dialog-footer button {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* ==============================================\n Mobile: single list with toggles\n ============================================== */\n\n/* Hidden by default on desktop */\n.mobile-view {\n display: none;\n}\n\n@media (max-width: 600px) {\n /* Swap layouts */\n .desktop-only {\n display: none !important;\n }\n\n .config-description {\n display: none;\n }\n\n .mobile-view {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .mobile-list {\n flex: 1;\n overflow-y: auto;\n padding: 0.5rem;\n }\n\n /* Section labels */\n .mobile-section-label {\n padding: 0.5rem 0.625rem 0.25rem;\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--mj-text-secondary);\n }\n\n /* App rows */\n .mobile-app-row {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.625rem;\n border-radius: var(--mj-radius-md);\n transition: background-color 0.15s ease;\n }\n\n .mobile-app-row.inactive {\n opacity: 0.7;\n }\n\n .mobile-app-row .app-icon {\n width: 2rem;\n height: 2rem;\n font-size: 0.875rem;\n flex-shrink: 0;\n }\n\n .mobile-app-name {\n flex: 1;\n min-width: 0;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n /* Drag handle */\n .mobile-drag-handle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.5rem;\n flex-shrink: 0;\n color: var(--mj-text-muted);\n font-size: 0.875rem;\n touch-action: none;\n cursor: grab;\n padding: 0.5rem 0;\n }\n\n .mobile-drag-handle:active {\n cursor: grabbing;\n color: var(--mj-text-primary);\n }\n\n /* Dragging row */\n .mobile-app-row.touch-dragging {\n background: var(--mj-bg-surface-hover);\n box-shadow: var(--mj-shadow-lg);\n border-radius: var(--mj-radius-md);\n position: relative;\n z-index: 100;\n opacity: 0.95;\n }\n\n /* Ghost placeholder for the original position */\n .mobile-app-row.touch-ghost {\n opacity: 0.3;\n }\n\n /* Drop indicator line */\n .mobile-drop-indicator {\n height: 2px;\n background: var(--mj-brand-primary);\n border-radius: 1px;\n margin: 0 0.625rem;\n }\n\n /* Toggle button */\n .mobile-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n padding: 0.25rem;\n cursor: pointer;\n font-size: 1.5rem;\n flex-shrink: 0;\n transition: color 0.15s ease;\n min-width: 44px;\n min-height: 44px;\n }\n\n .mobile-toggle.on {\n color: var(--mj-brand-primary);\n }\n\n .mobile-toggle.off {\n color: var(--mj-text-muted);\n }\n\n /* Header compact */\n .modal-header {\n padding: 0.75rem 1rem;\n }\n\n .modal-title {\n font-size: 1.125rem;\n }\n\n /* Content compact */\n .config-content {\n padding: 0;\n }\n\n /* Footer compact */\n .dialog-footer {\n padding: 0.75rem;\n gap: 0.5rem;\n }\n\n .footer-left,\n .footer-right {\n display: flex;\n gap: 0.5rem;\n }\n\n}\n\n/* Accessibility - Reduced Motion */\n@media (prefers-reduced-motion: reduce) {\n .app-item,\n .app-item-content,\n .available-app-item,\n .modal-close {\n transition: none;\n }\n}\n"] }]
759
743
  }], null, { ShowDialog: [{
760
744
  type: Input
761
745
  }], ShowDialogChange: [{
@@ -763,5 +747,5 @@ export class UserAppConfigComponent extends BaseAngularComponent {
763
747
  }], ConfigSaved: [{
764
748
  type: Output
765
749
  }] }); })();
766
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserAppConfigComponent, { className: "UserAppConfigComponent", filePath: "src/lib/user-app-config/user-app-config.component.ts", lineNumber: 33 }); })();
750
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserAppConfigComponent, { className: "UserAppConfigComponent", filePath: "src/lib/user-app-config/user-app-config.component.ts", lineNumber: 34 }); })();
767
751
  //# sourceMappingURL=user-app-config.component.js.map