@memberjunction/ng-explorer-settings 5.3.0 → 5.4.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 (35) hide show
  1. package/dist/__tests__/explorer-settings.test.js.map +1 -1
  2. package/dist/lib/account-info/account-info.component.js.map +1 -1
  3. package/dist/lib/appearance-settings/appearance-settings.component.js.map +1 -1
  4. package/dist/lib/application-management/application-dialog/application-dialog.component.js +2 -2
  5. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  6. package/dist/lib/application-management/application-management.component.js +2 -2
  7. package/dist/lib/application-management/application-management.component.js.map +1 -1
  8. package/dist/lib/application-settings/application-settings.component.js.map +1 -1
  9. package/dist/lib/entity-permissions/entity-permissions.component.js +2 -2
  10. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  11. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +2 -2
  12. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  13. package/dist/lib/general-settings/general-settings.component.js.map +1 -1
  14. package/dist/lib/module.js.map +1 -1
  15. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
  16. package/dist/lib/role-management/role-dialog/role-dialog.component.js +2 -2
  17. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  18. package/dist/lib/role-management/role-management.component.js +2 -2
  19. package/dist/lib/role-management/role-management.component.js.map +1 -1
  20. package/dist/lib/settings/settings.component.js.map +1 -1
  21. package/dist/lib/shared/settings-card.component.js.map +1 -1
  22. package/dist/lib/shared/shared-settings.module.js.map +1 -1
  23. package/dist/lib/sql-logging/sql-logging.component.js +2 -2
  24. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  25. package/dist/lib/user-app-config/user-app-config.component.d.ts +60 -68
  26. package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
  27. package/dist/lib/user-app-config/user-app-config.component.js +441 -302
  28. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  29. package/dist/lib/user-management/user-dialog/user-dialog.component.js +2 -2
  30. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  31. package/dist/lib/user-management/user-management.component.js +2 -2
  32. package/dist/lib/user-management/user-management.component.js.map +1 -1
  33. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  34. package/dist/public-api.js.map +1 -1
  35. package/package.json +17 -17
@@ -1,9 +1,9 @@
1
- import { Component, Input, Output, EventEmitter } from '@angular/core';
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectorRef, NgZone, ElementRef, inject } from '@angular/core';
2
2
  import { Metadata, RunView, LogError, LogStatus } from '@memberjunction/core';
3
+ import { ApplicationManager } from '@memberjunction/ng-base-application';
4
+ import { SharedService } from '@memberjunction/ng-shared';
3
5
  import * as i0 from "@angular/core";
4
- import * as i1 from "@memberjunction/ng-base-application";
5
- import * as i2 from "@memberjunction/ng-shared";
6
- import * as i3 from "@memberjunction/ng-shared-generic";
6
+ import * as i1 from "@memberjunction/ng-shared-generic";
7
7
  const _forTrack0 = ($index, $item) => $item.app.ID;
8
8
  function UserAppConfigComponent_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
9
9
  i0.ɵɵelementStart(0, "div", 8);
@@ -19,17 +19,17 @@ function UserAppConfigComponent_Conditional_0_Conditional_10_Template(rf, ctx) {
19
19
  } if (rf & 2) {
20
20
  const ctx_r1 = i0.ɵɵnextContext(2);
21
21
  i0.ɵɵadvance(3);
22
- i0.ɵɵtextInterpolate(ctx_r1.errorMessage);
22
+ i0.ɵɵtextInterpolate(ctx_r1.ErrorMessage);
23
23
  } }
24
24
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_13_Template(rf, ctx) { if (rf & 1) {
25
25
  i0.ɵɵelementStart(0, "div", 27);
26
- i0.ɵɵelement(1, "i", 32);
26
+ i0.ɵɵelement(1, "i", 34);
27
27
  i0.ɵɵelementStart(2, "p");
28
28
  i0.ɵɵtext(3, "All applications added!");
29
29
  i0.ɵɵelementEnd()();
30
30
  } }
31
31
  function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_6_Template(rf, ctx) { if (rf & 1) {
32
- i0.ɵɵelementStart(0, "span", 38);
32
+ i0.ɵɵelementStart(0, "span", 40);
33
33
  i0.ɵɵtext(1);
34
34
  i0.ɵɵelementEnd();
35
35
  } if (rf & 2) {
@@ -39,19 +39,19 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_
39
39
  } }
40
40
  function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template(rf, ctx) { if (rf & 1) {
41
41
  const _r4 = i0.ɵɵgetCurrentView();
42
- i0.ɵɵelementStart(0, "div", 33);
43
- 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)); });
44
- i0.ɵɵelementStart(1, "div", 34);
45
- i0.ɵɵelement(2, "i", 35);
42
+ i0.ɵɵelementStart(0, "div", 35);
43
+ 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)); });
44
+ i0.ɵɵelementStart(1, "div", 36);
45
+ i0.ɵɵelement(2, "i", 37);
46
46
  i0.ɵɵelementEnd();
47
- i0.ɵɵelementStart(3, "div", 36)(4, "span", 37);
47
+ i0.ɵɵelementStart(3, "div", 38)(4, "span", 39);
48
48
  i0.ɵɵtext(5);
49
49
  i0.ɵɵelementEnd();
50
- i0.ɵɵconditionalCreate(6, UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_6_Template, 2, 1, "span", 38);
50
+ i0.ɵɵconditionalCreate(6, UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Conditional_6_Template, 2, 1, "span", 40);
51
51
  i0.ɵɵelementEnd();
52
- i0.ɵɵelementStart(7, "button", 39);
53
- 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)); });
54
- i0.ɵɵelement(8, "i", 40);
52
+ i0.ɵɵelementStart(7, "button", 41);
53
+ 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)); });
54
+ i0.ɵɵelement(8, "i", 42);
55
55
  i0.ɵɵtext(9, " Add ");
56
56
  i0.ɵɵelementEnd()();
57
57
  } if (rf & 2) {
@@ -67,16 +67,16 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template(rf,
67
67
  } }
68
68
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_25_Template(rf, ctx) { if (rf & 1) {
69
69
  i0.ɵɵelementStart(0, "div", 27);
70
- i0.ɵɵelement(1, "i", 41);
70
+ i0.ɵɵelement(1, "i", 43);
71
71
  i0.ɵɵelementStart(2, "p");
72
72
  i0.ɵɵtext(3, "No applications selected");
73
73
  i0.ɵɵelementEnd();
74
- i0.ɵɵelementStart(4, "p", 42);
74
+ i0.ɵɵelementStart(4, "p", 44);
75
75
  i0.ɵɵtext(5, "Add apps from the available list");
76
76
  i0.ɵɵelementEnd()();
77
77
  } }
78
78
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
79
- i0.ɵɵelementStart(0, "span", 38);
79
+ i0.ɵɵelementStart(0, "span", 40);
80
80
  i0.ɵɵtext(1);
81
81
  i0.ɵɵelementEnd();
82
82
  } if (rf & 2) {
@@ -86,36 +86,36 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_
86
86
  } }
87
87
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template(rf, ctx) { if (rf & 1) {
88
88
  const _r7 = i0.ɵɵgetCurrentView();
89
- i0.ɵɵelementStart(0, "div", 45);
90
- 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($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.onDragEnd($event)); })("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()); });
91
- i0.ɵɵelementStart(1, "div", 46)(2, "div", 47);
92
- i0.ɵɵelement(3, "i", 48);
89
+ i0.ɵɵelementStart(0, "div", 47);
90
+ 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()); });
91
+ i0.ɵɵelementStart(1, "div", 48)(2, "div", 49);
92
+ i0.ɵɵelement(3, "i", 50);
93
93
  i0.ɵɵelementEnd();
94
- i0.ɵɵelementStart(4, "div", 34);
95
- i0.ɵɵelement(5, "i", 35);
94
+ i0.ɵɵelementStart(4, "div", 36);
95
+ i0.ɵɵelement(5, "i", 37);
96
96
  i0.ɵɵelementEnd();
97
- i0.ɵɵelementStart(6, "div", 36)(7, "span", 37);
97
+ i0.ɵɵelementStart(6, "div", 38)(7, "span", 39);
98
98
  i0.ɵɵtext(8);
99
99
  i0.ɵɵelementEnd();
100
- i0.ɵɵconditionalCreate(9, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Conditional_9_Template, 2, 1, "span", 38);
100
+ i0.ɵɵconditionalCreate(9, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Conditional_9_Template, 2, 1, "span", 40);
101
101
  i0.ɵɵelementEnd();
102
- i0.ɵɵelementStart(10, "div", 49)(11, "button", 50);
103
- 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()); });
104
- i0.ɵɵelement(12, "i", 51);
102
+ i0.ɵɵelementStart(10, "div", 51)(11, "button", 52);
103
+ 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()); });
104
+ i0.ɵɵelement(12, "i", 53);
105
105
  i0.ɵɵelementEnd();
106
- i0.ɵɵelementStart(13, "button", 52);
107
- 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()); });
108
- i0.ɵɵelement(14, "i", 53);
106
+ i0.ɵɵelementStart(13, "button", 54);
107
+ 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()); });
108
+ i0.ɵɵelement(14, "i", 55);
109
109
  i0.ɵɵelementEnd();
110
- i0.ɵɵelementStart(15, "button", 54);
111
- 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()); });
110
+ i0.ɵɵelementStart(15, "button", 56);
111
+ 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()); });
112
112
  i0.ɵɵelement(16, "i", 6);
113
113
  i0.ɵɵelementEnd()()()();
114
114
  } if (rf & 2) {
115
115
  const item_r9 = ctx.$implicit;
116
116
  const ɵ$index_115_r10 = ctx.$index;
117
117
  const ctx_r1 = i0.ɵɵnextContext(4);
118
- i0.ɵɵclassProp("dragging", ctx_r1.draggedItem === item_r9);
118
+ i0.ɵɵclassProp("dragging", ctx_r1.DraggedItem === item_r9);
119
119
  i0.ɵɵadvance();
120
120
  i0.ɵɵstyleProp("border-left-color", item_r9.app.GetColor());
121
121
  i0.ɵɵadvance(3);
@@ -129,18 +129,109 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_
129
129
  i0.ɵɵadvance(2);
130
130
  i0.ɵɵproperty("disabled", ɵ$index_115_r10 === 0);
131
131
  i0.ɵɵadvance(2);
132
- i0.ɵɵproperty("disabled", ɵ$index_115_r10 === ctx_r1.activeApps.length - 1);
132
+ i0.ɵɵproperty("disabled", ɵ$index_115_r10 === ctx_r1.ActiveApps.length - 1);
133
133
  } }
134
134
  function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_Template(rf, ctx) { if (rf & 1) {
135
135
  const _r6 = i0.ɵɵgetCurrentView();
136
- i0.ɵɵelementStart(0, "div", 43);
137
- 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)); });
138
- i0.ɵɵrepeaterCreate(1, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template, 17, 12, "div", 44, _forTrack0);
136
+ i0.ɵɵelementStart(0, "div", 45);
137
+ 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)); });
138
+ i0.ɵɵrepeaterCreate(1, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_For_2_Template, 17, 12, "div", 46, _forTrack0);
139
+ i0.ɵɵelementEnd();
140
+ } if (rf & 2) {
141
+ const ctx_r1 = i0.ɵɵnextContext(3);
142
+ i0.ɵɵadvance();
143
+ i0.ɵɵrepeater(ctx_r1.ActiveApps);
144
+ } }
145
+ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
146
+ i0.ɵɵelement(0, "div", 58);
147
+ } }
148
+ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_10_Template(rf, ctx) { if (rf & 1) {
149
+ i0.ɵɵelement(0, "div", 58);
150
+ } }
151
+ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Template(rf, ctx) { if (rf & 1) {
152
+ const _r11 = i0.ɵɵgetCurrentView();
153
+ i0.ɵɵconditionalCreate(0, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_0_Template, 1, 0, "div", 58);
154
+ i0.ɵɵelementStart(1, "div", 59)(2, "div", 60);
155
+ 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)); });
156
+ i0.ɵɵelement(3, "i", 50);
157
+ i0.ɵɵelementEnd();
158
+ i0.ɵɵelementStart(4, "div", 36);
159
+ i0.ɵɵelement(5, "i", 37);
160
+ i0.ɵɵelementEnd();
161
+ i0.ɵɵelementStart(6, "span", 61);
162
+ i0.ɵɵtext(7);
163
+ i0.ɵɵelementEnd();
164
+ i0.ɵɵelementStart(8, "button", 62);
165
+ 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)); });
166
+ i0.ɵɵelement(9, "i", 63);
167
+ i0.ɵɵelementEnd()();
168
+ i0.ɵɵconditionalCreate(10, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Conditional_10_Template, 1, 0, "div", 58);
169
+ } if (rf & 2) {
170
+ const item_r13 = ctx.$implicit;
171
+ const ɵ$index_159_r12 = ctx.$index;
172
+ const ctx_r1 = i0.ɵɵnextContext(4);
173
+ i0.ɵɵconditional(ctx_r1.TouchDragActive && ctx_r1.TouchDropIndex === ɵ$index_159_r12 && ctx_r1.TouchDragIndex > ɵ$index_159_r12 ? 0 : -1);
174
+ i0.ɵɵadvance();
175
+ i0.ɵɵclassProp("touch-ghost", ctx_r1.TouchDragActive && ctx_r1.TouchDragIndex === ɵ$index_159_r12);
176
+ i0.ɵɵadvance(3);
177
+ i0.ɵɵstyleProp("background-color", item_r13.app.GetColor());
178
+ i0.ɵɵadvance();
179
+ i0.ɵɵclassMap(item_r13.app.Icon || "fa-solid fa-cube");
180
+ i0.ɵɵadvance(2);
181
+ i0.ɵɵtextInterpolate(item_r13.app.Name);
182
+ i0.ɵɵadvance();
183
+ i0.ɵɵariaProperty("aria-label", i0.ɵɵinterpolate1("Remove ", item_r13.app.Name));
184
+ i0.ɵɵadvance(2);
185
+ i0.ɵɵconditional(ctx_r1.TouchDragActive && ctx_r1.TouchDropIndex === ɵ$index_159_r12 && ctx_r1.TouchDragIndex < ɵ$index_159_r12 ? 10 : -1);
186
+ } }
187
+ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Conditional_4_Template(rf, ctx) { if (rf & 1) {
188
+ i0.ɵɵelement(0, "div", 58);
189
+ } }
190
+ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Template(rf, ctx) { if (rf & 1) {
191
+ i0.ɵɵelementStart(0, "div", 57);
192
+ i0.ɵɵtext(1, "Your Apps");
139
193
  i0.ɵɵelementEnd();
194
+ i0.ɵɵrepeaterCreate(2, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_For_3_Template, 11, 11, null, null, _forTrack0);
195
+ i0.ɵɵconditionalCreate(4, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Conditional_4_Template, 1, 0, "div", 58);
140
196
  } if (rf & 2) {
141
197
  const ctx_r1 = i0.ɵɵnextContext(3);
198
+ i0.ɵɵadvance(2);
199
+ i0.ɵɵrepeater(ctx_r1.ActiveApps);
200
+ i0.ɵɵadvance(2);
201
+ i0.ɵɵconditional(ctx_r1.TouchDragActive && ctx_r1.TouchDropIndex === ctx_r1.ActiveApps.length - 1 && ctx_r1.TouchDragIndex < ctx_r1.TouchDropIndex ? 4 : -1);
202
+ } }
203
+ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_For_3_Template(rf, ctx) { if (rf & 1) {
204
+ const _r14 = i0.ɵɵgetCurrentView();
205
+ i0.ɵɵelementStart(0, "div", 64)(1, "div", 36);
206
+ i0.ɵɵelement(2, "i", 37);
207
+ i0.ɵɵelementEnd();
208
+ i0.ɵɵelementStart(3, "span", 61);
209
+ i0.ɵɵtext(4);
210
+ i0.ɵɵelementEnd();
211
+ i0.ɵɵelementStart(5, "button", 65);
212
+ 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)); });
213
+ i0.ɵɵelement(6, "i", 66);
214
+ i0.ɵɵelementEnd()();
215
+ } if (rf & 2) {
216
+ const item_r15 = ctx.$implicit;
217
+ i0.ɵɵadvance();
218
+ i0.ɵɵstyleProp("background-color", item_r15.app.GetColor());
142
219
  i0.ɵɵadvance();
143
- i0.ɵɵrepeater(ctx_r1.activeApps);
220
+ i0.ɵɵclassMap(item_r15.app.Icon || "fa-solid fa-cube");
221
+ i0.ɵɵadvance(2);
222
+ i0.ɵɵtextInterpolate(item_r15.app.Name);
223
+ i0.ɵɵadvance();
224
+ i0.ɵɵariaProperty("aria-label", i0.ɵɵinterpolate1("Add ", item_r15.app.Name));
225
+ } }
226
+ function UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_Template(rf, ctx) { if (rf & 1) {
227
+ i0.ɵɵelementStart(0, "div", 57);
228
+ i0.ɵɵtext(1, "Available");
229
+ i0.ɵɵelementEnd();
230
+ i0.ɵɵrepeaterCreate(2, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_For_3_Template, 7, 7, "div", 64, _forTrack0);
231
+ } if (rf & 2) {
232
+ const ctx_r1 = i0.ɵɵnextContext(3);
233
+ i0.ɵɵadvance(2);
234
+ i0.ɵɵrepeater(ctx_r1.AvailableApps);
144
235
  } }
145
236
  function UserAppConfigComponent_Conditional_0_Conditional_11_Template(rf, ctx) { if (rf & 1) {
146
237
  const _r3 = i0.ɵɵgetCurrentView();
@@ -148,7 +239,7 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Template(rf, ctx) {
148
239
  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. ");
149
240
  i0.ɵɵelementEnd();
150
241
  i0.ɵɵelementStart(3, "div", 20)(4, "div", 21)(5, "div", 22);
151
- 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); });
242
+ 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); });
152
243
  i0.ɵɵelement(6, "i", 23);
153
244
  i0.ɵɵelementStart(7, "h3");
154
245
  i0.ɵɵtext(8, "Available Applications");
@@ -163,7 +254,7 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Template(rf, ctx) {
163
254
  i0.ɵɵrepeaterCreate(14, UserAppConfigComponent_Conditional_0_Conditional_11_For_15_Template, 10, 6, "div", 28, _forTrack0);
164
255
  i0.ɵɵelementEnd()();
165
256
  i0.ɵɵelementStart(16, "div", 29)(17, "div", 22);
166
- 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); });
257
+ 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); });
167
258
  i0.ɵɵelement(18, "i", 30);
168
259
  i0.ɵɵelementStart(19, "h3");
169
260
  i0.ɵɵtext(20, "Your Applications");
@@ -176,43 +267,53 @@ function UserAppConfigComponent_Conditional_0_Conditional_11_Template(rf, ctx) {
176
267
  i0.ɵɵelementStart(24, "div", 26);
177
268
  i0.ɵɵconditionalCreate(25, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_25_Template, 6, 0, "div", 27);
178
269
  i0.ɵɵconditionalCreate(26, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_26_Template, 3, 0, "div", 31);
179
- i0.ɵɵelementEnd()()()();
270
+ i0.ɵɵelementEnd()()();
271
+ i0.ɵɵelementStart(27, "div", 32);
272
+ i0.ɵɵlistener("touchmove", function UserAppConfigComponent_Conditional_0_Conditional_11_Template_div_touchmove_27_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnTouchDragMove($event)); })("touchend", function UserAppConfigComponent_Conditional_0_Conditional_11_Template_div_touchend_27_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnTouchDragEnd()); })("touchcancel", function UserAppConfigComponent_Conditional_0_Conditional_11_Template_div_touchcancel_27_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnTouchDragEnd()); });
273
+ i0.ɵɵelementStart(28, "div", 33);
274
+ i0.ɵɵconditionalCreate(29, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_29_Template, 5, 1);
275
+ i0.ɵɵconditionalCreate(30, UserAppConfigComponent_Conditional_0_Conditional_11_Conditional_30_Template, 4, 0);
276
+ i0.ɵɵelementEnd()()();
180
277
  } if (rf & 2) {
181
278
  const ctx_r1 = i0.ɵɵnextContext(2);
182
279
  i0.ɵɵadvance(4);
183
- i0.ɵɵclassProp("collapsed", ctx_r1.availablePanelCollapsed);
280
+ i0.ɵɵclassProp("collapsed", ctx_r1.AvailablePanelCollapsed);
184
281
  i0.ɵɵadvance(6);
185
- i0.ɵɵtextInterpolate(ctx_r1.availableApps.length);
282
+ i0.ɵɵtextInterpolate(ctx_r1.AvailableApps.length);
186
283
  i0.ɵɵadvance();
187
- i0.ɵɵclassProp("fa-chevron-down", ctx_r1.availablePanelCollapsed)("fa-chevron-up", !ctx_r1.availablePanelCollapsed);
284
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r1.AvailablePanelCollapsed)("fa-chevron-up", !ctx_r1.AvailablePanelCollapsed);
188
285
  i0.ɵɵadvance(2);
189
- i0.ɵɵconditional(ctx_r1.availableApps.length === 0 ? 13 : -1);
286
+ i0.ɵɵconditional(ctx_r1.AvailableApps.length === 0 ? 13 : -1);
190
287
  i0.ɵɵadvance();
191
- i0.ɵɵrepeater(ctx_r1.availableApps);
288
+ i0.ɵɵrepeater(ctx_r1.AvailableApps);
192
289
  i0.ɵɵadvance(2);
193
- i0.ɵɵclassProp("collapsed", ctx_r1.selectedPanelCollapsed);
290
+ i0.ɵɵclassProp("collapsed", ctx_r1.SelectedPanelCollapsed);
194
291
  i0.ɵɵadvance(6);
195
- i0.ɵɵtextInterpolate(ctx_r1.activeApps.length);
292
+ i0.ɵɵtextInterpolate(ctx_r1.ActiveApps.length);
196
293
  i0.ɵɵadvance();
197
- i0.ɵɵclassProp("fa-chevron-down", ctx_r1.selectedPanelCollapsed)("fa-chevron-up", !ctx_r1.selectedPanelCollapsed);
294
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r1.SelectedPanelCollapsed)("fa-chevron-up", !ctx_r1.SelectedPanelCollapsed);
198
295
  i0.ɵɵadvance(2);
199
- i0.ɵɵconditional(ctx_r1.activeApps.length === 0 ? 25 : -1);
296
+ i0.ɵɵconditional(ctx_r1.ActiveApps.length === 0 ? 25 : -1);
297
+ i0.ɵɵadvance();
298
+ i0.ɵɵconditional(ctx_r1.ActiveApps.length > 0 ? 26 : -1);
299
+ i0.ɵɵadvance(3);
300
+ i0.ɵɵconditional(ctx_r1.ActiveApps.length > 0 ? 29 : -1);
200
301
  i0.ɵɵadvance();
201
- i0.ɵɵconditional(ctx_r1.activeApps.length > 0 ? 26 : -1);
302
+ i0.ɵɵconditional(ctx_r1.AvailableApps.length > 0 ? 30 : -1);
202
303
  } }
203
304
  function UserAppConfigComponent_Conditional_0_Conditional_14_Template(rf, ctx) { if (rf & 1) {
204
- const _r11 = i0.ɵɵgetCurrentView();
305
+ const _r16 = i0.ɵɵgetCurrentView();
205
306
  i0.ɵɵelementStart(0, "button", 16);
206
- i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.reset()); });
207
- i0.ɵɵelement(1, "i", 55);
307
+ 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()); });
308
+ i0.ɵɵelement(1, "i", 67);
208
309
  i0.ɵɵtext(2, " Reset Changes ");
209
310
  i0.ɵɵelementEnd();
210
311
  } if (rf & 2) {
211
312
  const ctx_r1 = i0.ɵɵnextContext(2);
212
- i0.ɵɵproperty("disabled", ctx_r1.isLoading || ctx_r1.isSaving);
313
+ i0.ɵɵproperty("disabled", ctx_r1.IsLoading || ctx_r1.IsSaving);
213
314
  } }
214
315
  function UserAppConfigComponent_Conditional_0_Conditional_17_Template(rf, ctx) { if (rf & 1) {
215
- i0.ɵɵelement(0, "mj-loading", 56);
316
+ i0.ɵɵelement(0, "mj-loading", 68);
216
317
  i0.ɵɵelementStart(1, "span");
217
318
  i0.ɵɵtext(2, "Saving...");
218
319
  i0.ɵɵelementEnd();
@@ -220,7 +321,7 @@ function UserAppConfigComponent_Conditional_0_Conditional_17_Template(rf, ctx) {
220
321
  i0.ɵɵproperty("showText", false);
221
322
  } }
222
323
  function UserAppConfigComponent_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
223
- i0.ɵɵelement(0, "i", 57);
324
+ i0.ɵɵelement(0, "i", 69);
224
325
  i0.ɵɵelementStart(1, "span");
225
326
  i0.ɵɵtext(2, "Save Changes");
226
327
  i0.ɵɵelementEnd();
@@ -228,337 +329,384 @@ function UserAppConfigComponent_Conditional_0_Conditional_18_Template(rf, ctx) {
228
329
  function UserAppConfigComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
229
330
  const _r1 = i0.ɵɵgetCurrentView();
230
331
  i0.ɵɵelementStart(0, "div", 0);
231
- i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
332
+ i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Close()); });
232
333
  i0.ɵɵelementEnd();
233
334
  i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "h2", 3);
234
335
  i0.ɵɵelement(4, "i", 4);
235
336
  i0.ɵɵtext(5, " Configure Apps ");
236
337
  i0.ɵɵelementEnd();
237
338
  i0.ɵɵelementStart(6, "button", 5);
238
- i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
339
+ i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Close()); });
239
340
  i0.ɵɵelement(7, "i", 6);
240
341
  i0.ɵɵelementEnd()();
241
342
  i0.ɵɵelementStart(8, "div", 7);
242
343
  i0.ɵɵconditionalCreate(9, UserAppConfigComponent_Conditional_0_Conditional_9_Template, 2, 0, "div", 8);
243
344
  i0.ɵɵconditionalCreate(10, UserAppConfigComponent_Conditional_0_Conditional_10_Template, 4, 1, "div", 9);
244
- i0.ɵɵconditionalCreate(11, UserAppConfigComponent_Conditional_0_Conditional_11_Template, 27, 17, "div", 10);
345
+ i0.ɵɵconditionalCreate(11, UserAppConfigComponent_Conditional_0_Conditional_11_Template, 31, 19, "div", 10);
245
346
  i0.ɵɵelementStart(12, "div", 11)(13, "div", 12);
246
347
  i0.ɵɵconditionalCreate(14, UserAppConfigComponent_Conditional_0_Conditional_14_Template, 3, 1, "button", 13);
247
348
  i0.ɵɵelementEnd();
248
349
  i0.ɵɵelementStart(15, "div", 14)(16, "button", 15);
249
- i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.save()); });
350
+ i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Save()); });
250
351
  i0.ɵɵconditionalCreate(17, UserAppConfigComponent_Conditional_0_Conditional_17_Template, 3, 1)(18, UserAppConfigComponent_Conditional_0_Conditional_18_Template, 3, 0);
251
352
  i0.ɵɵelementEnd();
252
353
  i0.ɵɵelementStart(19, "button", 16);
253
- i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.close()); });
354
+ i0.ɵɵlistener("click", function UserAppConfigComponent_Conditional_0_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Close()); });
254
355
  i0.ɵɵtext(20, " Cancel ");
255
356
  i0.ɵɵelementEnd()()()()();
256
357
  } if (rf & 2) {
257
358
  const ctx_r1 = i0.ɵɵnextContext();
258
359
  i0.ɵɵadvance(9);
259
- i0.ɵɵconditional(ctx_r1.isLoading ? 9 : -1);
360
+ i0.ɵɵconditional(ctx_r1.IsLoading ? 9 : -1);
260
361
  i0.ɵɵadvance();
261
- i0.ɵɵconditional(ctx_r1.errorMessage ? 10 : -1);
362
+ i0.ɵɵconditional(ctx_r1.ErrorMessage ? 10 : -1);
262
363
  i0.ɵɵadvance();
263
- i0.ɵɵconditional(!ctx_r1.isLoading ? 11 : -1);
364
+ i0.ɵɵconditional(!ctx_r1.IsLoading ? 11 : -1);
264
365
  i0.ɵɵadvance(3);
265
- i0.ɵɵconditional(ctx_r1.hasChanges() ? 14 : -1);
366
+ i0.ɵɵconditional(ctx_r1.HasChanges() ? 14 : -1);
266
367
  i0.ɵɵadvance(2);
267
- i0.ɵɵproperty("disabled", ctx_r1.isLoading || ctx_r1.isSaving || !ctx_r1.hasChanges());
368
+ i0.ɵɵproperty("disabled", ctx_r1.IsLoading || ctx_r1.IsSaving || !ctx_r1.HasChanges());
268
369
  i0.ɵɵadvance();
269
- i0.ɵɵconditional(ctx_r1.isSaving ? 17 : 18);
370
+ i0.ɵɵconditional(ctx_r1.IsSaving ? 17 : 18);
270
371
  i0.ɵɵadvance(2);
271
- i0.ɵɵproperty("disabled", ctx_r1.isSaving);
372
+ i0.ɵɵproperty("disabled", ctx_r1.IsSaving);
272
373
  } }
273
374
  /**
274
375
  * Full-screen modal dialog for configuring user's application visibility and order.
275
376
  * Allows users to:
276
377
  * - Select which applications to show in the app switcher
277
- * - Reorder applications via drag-and-drop
378
+ * - Reorder applications via drag-and-drop (desktop)
379
+ * - Toggle apps on/off in a single list (mobile)
278
380
  */
279
381
  export class UserAppConfigComponent {
280
- appManager;
281
- sharedService;
282
- cdr;
283
- ngZone;
284
- showDialog = false;
285
- showDialogChange = new EventEmitter();
286
- configSaved = new EventEmitter();
287
- // All available apps from the system
288
- allApps = [];
289
- // User's selected apps (active and ordered)
290
- activeApps = [];
291
- // Available apps not yet selected
292
- availableApps = [];
293
- isLoading = false;
294
- isSaving = false;
295
- errorMessage = '';
296
- // Panel collapse state (for mobile)
297
- availablePanelCollapsed = false;
298
- selectedPanelCollapsed = false;
299
- // Native drag-and-drop state
300
- draggedItem = null;
301
- draggedIndex = -1;
302
- dropTargetIndex = -1;
303
- constructor(appManager, sharedService, cdr, ngZone) {
304
- this.appManager = appManager;
305
- this.sharedService = sharedService;
306
- this.cdr = cdr;
307
- this.ngZone = ngZone;
382
+ appManager = inject(ApplicationManager);
383
+ sharedService = inject(SharedService);
384
+ cdr = inject(ChangeDetectorRef);
385
+ ngZone = inject(NgZone);
386
+ el = inject(ElementRef);
387
+ _showDialog = false;
388
+ set ShowDialog(value) {
389
+ if (value !== this._showDialog) {
390
+ this._showDialog = value;
391
+ }
392
+ }
393
+ get ShowDialog() {
394
+ return this._showDialog;
308
395
  }
396
+ ShowDialogChange = new EventEmitter();
397
+ ConfigSaved = new EventEmitter();
398
+ AllApps = [];
399
+ ActiveApps = [];
400
+ AvailableApps = [];
401
+ IsLoading = false;
402
+ IsSaving = false;
403
+ ErrorMessage = '';
404
+ AvailablePanelCollapsed = false;
405
+ SelectedPanelCollapsed = false;
406
+ DraggedItem = null;
407
+ DraggedIndex = -1;
408
+ DropTargetIndex = -1;
309
409
  /**
310
410
  * Opens the dialog and loads user's app configuration
311
411
  */
312
- async open() {
313
- this.showDialog = true;
314
- this.showDialogChange.emit(true);
315
- this.errorMessage = '';
412
+ async Open() {
413
+ this._showDialog = true;
414
+ this.ShowDialogChange.emit(true);
415
+ this.ErrorMessage = '';
316
416
  await this.loadConfiguration();
317
417
  }
318
418
  /**
319
419
  * Closes the dialog without saving
320
420
  */
321
- close() {
322
- this.showDialog = false;
323
- this.showDialogChange.emit(false);
324
- }
325
- /**
326
- * Loads the user's current app configuration
327
- */
328
- async loadConfiguration() {
329
- this.isLoading = true;
330
- this.errorMessage = '';
331
- try {
332
- const md = new Metadata();
333
- const rv = new RunView();
334
- // Load all system apps from ApplicationManager
335
- const systemApps = this.appManager.GetAllSystemApps();
336
- // Load user's UserApplication records
337
- const userAppsResult = await rv.RunView({
338
- EntityName: 'MJ: User Applications',
339
- ExtraFilter: `UserID = '${md.CurrentUser.ID}'`,
340
- OrderBy: 'Sequence, Application',
341
- ResultType: 'entity_object'
342
- });
343
- const userApps = userAppsResult.Success ? userAppsResult.Results : [];
344
- // Build app config items
345
- this.allApps = this.buildAppConfigItems(systemApps, userApps);
346
- // Separate into active (selected) and available (unselected)
347
- this.refreshAppLists();
348
- }
349
- catch (error) {
350
- this.errorMessage = 'Failed to load app configuration. Please try again.';
351
- LogError('Error loading app configuration:', undefined, error instanceof Error ? error.message : String(error));
352
- }
353
- finally {
354
- this.ngZone.run(() => {
355
- this.isLoading = false;
356
- this.cdr.detectChanges();
357
- });
358
- }
359
- }
360
- /**
361
- * Builds app config items by matching system apps with user's UserApplication records
362
- */
363
- buildAppConfigItems(systemApps, userApps) {
364
- const items = [];
365
- for (const app of systemApps) {
366
- const userApp = userApps.find(ua => ua.ApplicationID === app.ID);
367
- items.push({
368
- app,
369
- userAppId: userApp?.ID || null,
370
- sequence: userApp?.Sequence ?? 999, // Default high sequence for unselected
371
- isActive: userApp?.IsActive ?? false,
372
- isDirty: false
373
- });
374
- }
375
- return items;
376
- }
377
- /**
378
- * Separates apps into active and available lists based on isActive state
379
- */
380
- refreshAppLists() {
381
- this.activeApps = this.allApps
382
- .filter(item => item.isActive)
383
- .sort((a, b) => a.sequence - b.sequence);
384
- this.availableApps = this.allApps
385
- .filter(item => !item.isActive)
386
- .sort((a, b) => a.app.Name.localeCompare(b.app.Name));
387
- }
388
- /**
389
- * Native drag start handler
390
- */
391
- onDragStart(event, item, index) {
392
- this.draggedItem = item;
393
- this.draggedIndex = index;
394
- if (event.dataTransfer) {
395
- event.dataTransfer.effectAllowed = 'move';
396
- event.dataTransfer.setData('text/plain', index.toString());
397
- }
398
- }
399
- /**
400
- * Native drag over handler - allows drop
401
- */
402
- onDragOver(event) {
403
- event.preventDefault();
404
- if (event.dataTransfer) {
405
- event.dataTransfer.dropEffect = 'move';
406
- }
407
- }
408
- /**
409
- * Native drag enter handler - tracks drop target
410
- */
411
- onDragEnter(event, index) {
412
- event.preventDefault();
413
- this.dropTargetIndex = index;
414
- }
415
- /**
416
- * Native drag end handler - cleanup
417
- */
418
- onDragEnd(event) {
419
- this.draggedItem = null;
420
- this.draggedIndex = -1;
421
- this.dropTargetIndex = -1;
422
- }
423
- /**
424
- * Native drop handler - reorder items
425
- */
426
- onDrop(event) {
427
- event.preventDefault();
428
- if (this.draggedIndex >= 0 && this.dropTargetIndex >= 0 && this.draggedIndex !== this.dropTargetIndex) {
429
- // Remove item from old position
430
- const [movedItem] = this.activeApps.splice(this.draggedIndex, 1);
431
- // Insert at new position
432
- this.activeApps.splice(this.dropTargetIndex, 0, movedItem);
433
- // Update sequences based on new order
434
- this.activeApps.forEach((item, idx) => {
435
- if (item.sequence !== idx) {
436
- item.sequence = idx;
437
- item.isDirty = true;
438
- }
439
- });
440
- this.cdr.detectChanges();
441
- }
442
- // Reset drag state
443
- this.draggedItem = null;
444
- this.draggedIndex = -1;
445
- this.dropTargetIndex = -1;
421
+ Close() {
422
+ this._showDialog = false;
423
+ this.ShowDialogChange.emit(false);
446
424
  }
447
425
  /**
448
426
  * Adds an app to the user's active list
449
427
  */
450
- addApp(item) {
428
+ AddApp(item) {
451
429
  item.isActive = true;
452
- item.sequence = this.activeApps.length;
430
+ item.sequence = this.ActiveApps.length;
453
431
  item.isDirty = true;
454
432
  this.refreshAppLists();
455
433
  }
456
434
  /**
457
435
  * Removes an app from the user's active list
458
436
  */
459
- removeApp(item) {
437
+ RemoveApp(item) {
460
438
  item.isActive = false;
461
439
  item.sequence = 999;
462
440
  item.isDirty = true;
463
441
  this.refreshAppLists();
464
- // Resequence remaining active apps
465
- this.activeApps.forEach((activeItem, index) => {
466
- if (activeItem.sequence !== index) {
467
- activeItem.sequence = index;
468
- activeItem.isDirty = true;
469
- }
470
- });
442
+ this.resequenceActiveApps();
443
+ }
444
+ /**
445
+ * Toggles an app between active and inactive
446
+ */
447
+ ToggleApp(item) {
448
+ if (item.isActive) {
449
+ this.RemoveApp(item);
450
+ }
451
+ else {
452
+ this.AddApp(item);
453
+ }
471
454
  }
472
455
  /**
473
456
  * Moves an app up in the order
474
457
  */
475
- moveUp(item) {
476
- const index = this.activeApps.indexOf(item);
458
+ MoveUp(item) {
459
+ const index = this.ActiveApps.indexOf(item);
477
460
  if (index > 0) {
478
- // Swap with previous item
479
- const prevItem = this.activeApps[index - 1];
480
- // Swap sequences
481
- const tempSeq = item.sequence;
482
- item.sequence = prevItem.sequence;
483
- prevItem.sequence = tempSeq;
484
- item.isDirty = true;
485
- prevItem.isDirty = true;
486
- // Re-sort and create new array reference to trigger change detection
487
- this.activeApps = [...this.activeApps].sort((a, b) => a.sequence - b.sequence);
461
+ this.swapSequences(item, this.ActiveApps[index - 1]);
462
+ this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.sequence - b.sequence);
488
463
  }
489
464
  }
490
465
  /**
491
466
  * Moves an app down in the order
492
467
  */
493
- moveDown(item) {
494
- const index = this.activeApps.indexOf(item);
495
- if (index < this.activeApps.length - 1) {
496
- // Swap with next item
497
- const nextItem = this.activeApps[index + 1];
498
- // Swap sequences
499
- const tempSeq = item.sequence;
500
- item.sequence = nextItem.sequence;
501
- nextItem.sequence = tempSeq;
502
- item.isDirty = true;
503
- nextItem.isDirty = true;
504
- // Re-sort and create new array reference to trigger change detection
505
- this.activeApps = [...this.activeApps].sort((a, b) => a.sequence - b.sequence);
468
+ MoveDown(item) {
469
+ const index = this.ActiveApps.indexOf(item);
470
+ if (index < this.ActiveApps.length - 1) {
471
+ this.swapSequences(item, this.ActiveApps[index + 1]);
472
+ this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.sequence - b.sequence);
506
473
  }
507
474
  }
508
475
  /**
509
476
  * Checks if there are any unsaved changes
510
477
  */
511
- hasChanges() {
512
- return this.allApps.some(item => item.isDirty);
478
+ HasChanges() {
479
+ return this.AllApps.some(item => item.isDirty);
513
480
  }
514
481
  /**
515
482
  * Saves the user's app configuration
516
483
  */
517
- async save() {
518
- if (!this.hasChanges()) {
519
- this.close();
484
+ async Save() {
485
+ if (!this.HasChanges()) {
486
+ this.Close();
520
487
  return;
521
488
  }
522
- this.isSaving = true;
523
- this.errorMessage = '';
489
+ this.IsSaving = true;
490
+ this.ErrorMessage = '';
524
491
  try {
525
492
  const md = new Metadata();
526
- const rv = new RunView();
527
- // Process each app config item
528
- for (const item of this.allApps) {
493
+ for (const item of this.AllApps) {
529
494
  if (!item.isDirty)
530
495
  continue;
531
496
  if (item.userAppId) {
532
- // Update existing UserApplication record
533
497
  await this.updateUserApplication(md, item);
534
498
  }
535
499
  else if (item.isActive) {
536
- // Create new UserApplication record (only if active)
537
500
  await this.createUserApplication(md, item);
538
501
  }
539
- // If not active and no existing record, nothing to do
540
502
  }
541
- // Reload the ApplicationManager to reflect changes
542
503
  LogStatus('User app configuration saved, reloading ApplicationManager...');
543
504
  await this.appManager.ReloadUserApplications();
544
505
  this.sharedService.CreateSimpleNotification('App configuration saved successfully!', 'success', 3000);
545
- this.configSaved.emit();
546
- this.close();
506
+ this.ConfigSaved.emit();
507
+ this.Close();
547
508
  }
548
509
  catch (error) {
549
- this.errorMessage = 'Failed to save configuration. Please try again.';
510
+ this.ErrorMessage = 'Failed to save configuration. Please try again.';
550
511
  LogError('Error saving app configuration:', undefined, error instanceof Error ? error.message : String(error));
551
512
  }
552
513
  finally {
553
514
  this.ngZone.run(() => {
554
- this.isSaving = false;
515
+ this.IsSaving = false;
555
516
  this.cdr.detectChanges();
556
517
  });
557
518
  }
558
519
  }
559
520
  /**
560
- * Updates an existing UserApplication record
521
+ * Resets all changes and reloads the configuration
561
522
  */
523
+ async Reset() {
524
+ await this.loadConfiguration();
525
+ }
526
+ // ---------------------------------------------------------------------------
527
+ // Drag-and-drop handlers (desktop only)
528
+ // ---------------------------------------------------------------------------
529
+ OnDragStart(event, item, index) {
530
+ this.DraggedItem = item;
531
+ this.DraggedIndex = index;
532
+ if (event.dataTransfer) {
533
+ event.dataTransfer.effectAllowed = 'move';
534
+ event.dataTransfer.setData('text/plain', index.toString());
535
+ }
536
+ }
537
+ OnDragOver(event) {
538
+ event.preventDefault();
539
+ if (event.dataTransfer) {
540
+ event.dataTransfer.dropEffect = 'move';
541
+ }
542
+ }
543
+ OnDragEnter(event, index) {
544
+ event.preventDefault();
545
+ this.DropTargetIndex = index;
546
+ }
547
+ OnDragEnd() {
548
+ this.DraggedItem = null;
549
+ this.DraggedIndex = -1;
550
+ this.DropTargetIndex = -1;
551
+ }
552
+ OnDrop(event) {
553
+ event.preventDefault();
554
+ if (this.DraggedIndex >= 0 && this.DropTargetIndex >= 0 && this.DraggedIndex !== this.DropTargetIndex) {
555
+ const [movedItem] = this.ActiveApps.splice(this.DraggedIndex, 1);
556
+ this.ActiveApps.splice(this.DropTargetIndex, 0, movedItem);
557
+ this.resequenceActiveApps();
558
+ this.cdr.detectChanges();
559
+ }
560
+ this.OnDragEnd();
561
+ }
562
+ // ---------------------------------------------------------------------------
563
+ // Touch drag-and-drop handlers (mobile)
564
+ // ---------------------------------------------------------------------------
565
+ TouchDragIndex = -1;
566
+ TouchDropIndex = -1;
567
+ TouchDragActive = false;
568
+ touchStartY = 0;
569
+ touchCurrentY = 0;
570
+ touchRowHeight = 0;
571
+ touchDragElement = null;
572
+ touchScrollContainer = null;
573
+ OnTouchDragStart(event, index) {
574
+ const touch = event.touches[0];
575
+ const row = event.target.closest('.mobile-app-row');
576
+ if (!row)
577
+ return;
578
+ event.preventDefault();
579
+ this.TouchDragIndex = index;
580
+ this.TouchDropIndex = index;
581
+ this.TouchDragActive = true;
582
+ this.touchStartY = touch.clientY;
583
+ this.touchCurrentY = touch.clientY;
584
+ this.touchDragElement = row;
585
+ this.touchRowHeight = row.offsetHeight;
586
+ this.touchScrollContainer = this.el.nativeElement.querySelector('.mobile-list');
587
+ row.classList.add('touch-dragging');
588
+ }
589
+ OnTouchDragMove(event) {
590
+ if (!this.TouchDragActive || !this.touchDragElement)
591
+ return;
592
+ event.preventDefault();
593
+ const touch = event.touches[0];
594
+ this.touchCurrentY = touch.clientY;
595
+ const deltaY = this.touchCurrentY - this.touchStartY;
596
+ this.touchDragElement.style.transform = `translateY(${deltaY}px)`;
597
+ this.touchDragElement.style.zIndex = '100';
598
+ this.updateTouchDropTarget(deltaY);
599
+ this.autoScrollIfNeeded();
600
+ }
601
+ OnTouchDragEnd() {
602
+ if (!this.TouchDragActive)
603
+ return;
604
+ if (this.touchDragElement) {
605
+ this.touchDragElement.style.transform = '';
606
+ this.touchDragElement.style.zIndex = '';
607
+ this.touchDragElement.classList.remove('touch-dragging');
608
+ }
609
+ if (this.TouchDragIndex >= 0 && this.TouchDropIndex >= 0 && this.TouchDragIndex !== this.TouchDropIndex) {
610
+ const [movedItem] = this.ActiveApps.splice(this.TouchDragIndex, 1);
611
+ this.ActiveApps.splice(this.TouchDropIndex, 0, movedItem);
612
+ this.resequenceActiveApps();
613
+ }
614
+ this.resetTouchDragState();
615
+ this.cdr.detectChanges();
616
+ }
617
+ updateTouchDropTarget(deltaY) {
618
+ const rowsToMove = Math.round(deltaY / this.touchRowHeight);
619
+ const newIndex = Math.max(0, Math.min(this.ActiveApps.length - 1, this.TouchDragIndex + rowsToMove));
620
+ this.TouchDropIndex = newIndex;
621
+ }
622
+ autoScrollIfNeeded() {
623
+ if (!this.touchScrollContainer)
624
+ return;
625
+ const rect = this.touchScrollContainer.getBoundingClientRect();
626
+ const edgeZone = 40;
627
+ if (this.touchCurrentY < rect.top + edgeZone) {
628
+ this.touchScrollContainer.scrollTop -= 8;
629
+ }
630
+ else if (this.touchCurrentY > rect.bottom - edgeZone) {
631
+ this.touchScrollContainer.scrollTop += 8;
632
+ }
633
+ }
634
+ resetTouchDragState() {
635
+ this.TouchDragIndex = -1;
636
+ this.TouchDropIndex = -1;
637
+ this.TouchDragActive = false;
638
+ this.touchDragElement = null;
639
+ this.touchScrollContainer = null;
640
+ }
641
+ // ---------------------------------------------------------------------------
642
+ // Private helpers
643
+ // ---------------------------------------------------------------------------
644
+ async loadConfiguration() {
645
+ this.IsLoading = true;
646
+ this.ErrorMessage = '';
647
+ try {
648
+ const md = new Metadata();
649
+ const rv = new RunView();
650
+ const systemApps = this.appManager.GetAllSystemApps();
651
+ const userAppsResult = await rv.RunView({
652
+ EntityName: 'MJ: User Applications',
653
+ Fields: ['ID', 'ApplicationID', 'Sequence', 'IsActive'],
654
+ ExtraFilter: `UserID = '${md.CurrentUser.ID}'`,
655
+ OrderBy: 'Sequence, Application',
656
+ ResultType: 'simple'
657
+ });
658
+ if (!userAppsResult.Success) {
659
+ throw new Error(userAppsResult.ErrorMessage);
660
+ }
661
+ this.AllApps = this.buildAppConfigItems(systemApps, userAppsResult.Results);
662
+ this.refreshAppLists();
663
+ }
664
+ catch (error) {
665
+ this.ErrorMessage = 'Failed to load app configuration. Please try again.';
666
+ LogError('Error loading app configuration:', undefined, error instanceof Error ? error.message : String(error));
667
+ }
668
+ finally {
669
+ this.ngZone.run(() => {
670
+ this.IsLoading = false;
671
+ this.cdr.detectChanges();
672
+ });
673
+ }
674
+ }
675
+ buildAppConfigItems(systemApps, userApps) {
676
+ return systemApps.map(app => {
677
+ const userApp = userApps.find(ua => ua.ApplicationID === app.ID);
678
+ return {
679
+ app,
680
+ userAppId: userApp?.ID ?? null,
681
+ sequence: userApp?.Sequence ?? 999,
682
+ isActive: userApp?.IsActive ?? false,
683
+ isDirty: false
684
+ };
685
+ });
686
+ }
687
+ refreshAppLists() {
688
+ this.ActiveApps = this.AllApps
689
+ .filter(item => item.isActive)
690
+ .sort((a, b) => a.sequence - b.sequence);
691
+ this.AvailableApps = this.AllApps
692
+ .filter(item => !item.isActive)
693
+ .sort((a, b) => a.app.Name.localeCompare(b.app.Name));
694
+ }
695
+ resequenceActiveApps() {
696
+ this.ActiveApps.forEach((item, index) => {
697
+ if (item.sequence !== index) {
698
+ item.sequence = index;
699
+ item.isDirty = true;
700
+ }
701
+ });
702
+ }
703
+ swapSequences(a, b) {
704
+ const tempSeq = a.sequence;
705
+ a.sequence = b.sequence;
706
+ b.sequence = tempSeq;
707
+ a.isDirty = true;
708
+ b.isDirty = true;
709
+ }
562
710
  async updateUserApplication(md, item) {
563
711
  const userApp = await md.GetEntityObject('MJ: User Applications');
564
712
  await userApp.Load(item.userAppId);
@@ -571,9 +719,6 @@ export class UserAppConfigComponent {
571
719
  item.isDirty = false;
572
720
  LogStatus(`Updated UserApplication for ${item.app.Name}: sequence=${item.sequence}, isActive=${item.isActive}`);
573
721
  }
574
- /**
575
- * Creates a new UserApplication record
576
- */
577
722
  async createUserApplication(md, item) {
578
723
  const userApp = await md.GetEntityObject('MJ: User Applications');
579
724
  userApp.NewRecord();
@@ -589,28 +734,22 @@ export class UserAppConfigComponent {
589
734
  item.isDirty = false;
590
735
  LogStatus(`Created UserApplication for ${item.app.Name}: sequence=${item.sequence}`);
591
736
  }
592
- /**
593
- * Resets all changes and reloads the configuration
594
- */
595
- async reset() {
596
- await this.loadConfiguration();
597
- }
598
- static ɵfac = function UserAppConfigComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserAppConfigComponent)(i0.ɵɵdirectiveInject(i1.ApplicationManager), i0.ɵɵdirectiveInject(i2.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
599
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserAppConfigComponent, selectors: [["mj-user-app-config"]], inputs: { showDialog: "showDialog" }, outputs: { showDialogChange: "showDialogChange", configSaved: "configSaved" }, standalone: false, 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"], [1, "mj-btn", "mj-btn-secondary", 3, "disabled"], [1, "footer-right"], [1, "mj-btn", "mj-btn-primary", 3, "click", "disabled"], [1, "mj-btn", "mj-btn-secondary", 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"], [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"], ["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"], ["title", "Add to your apps", 1, "mj-btn", "mj-btn-primary", "mj-btn-outline", "mj-btn-sm", 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"], ["title", "Move up", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-up"], ["title", "Move down", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["title", "Remove from your apps", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "mj-btn-danger", 3, "click"], ["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) {
737
+ static ɵfac = function UserAppConfigComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserAppConfigComponent)(); };
738
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserAppConfigComponent, selectors: [["mj-user-app-config"]], inputs: { ShowDialog: "ShowDialog" }, outputs: { ShowDialogChange: "ShowDialogChange", ConfigSaved: "ConfigSaved" }, standalone: false, 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"], [1, "mj-btn", "mj-btn-secondary", 3, "disabled"], [1, "footer-right"], [1, "mj-btn", "mj-btn-primary", 3, "click", "disabled"], [1, "mj-btn", "mj-btn-secondary", 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"], ["title", "Add to your apps", 1, "mj-btn", "mj-btn-primary", "mj-btn-outline", "mj-btn-sm", 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"], ["title", "Move up", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-up"], ["title", "Move down", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["title", "Remove from your apps", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "mj-btn-danger", 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) {
600
739
  i0.ɵɵconditionalCreate(0, UserAppConfigComponent_Conditional_0_Template, 21, 7);
601
740
  } if (rf & 2) {
602
- i0.ɵɵconditional(ctx.showDialog ? 0 : -1);
603
- } }, dependencies: [i3.LoadingComponent], 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\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@media (max-width: 600px) {\n .config-content[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .panels-container[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n\n .app-item-content[_ngcontent-%COMP%], \n .available-app-item[_ngcontent-%COMP%] {\n padding: 0.625rem 0.75rem;\n }\n\n .app-icon[_ngcontent-%COMP%] {\n width: 2.25rem;\n height: 2.25rem;\n font-size: 1rem;\n }\n\n .dialog-footer[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 0.75rem;\n }\n\n .footer-left[_ngcontent-%COMP%], \n .footer-right[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\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}"] });
741
+ i0.ɵɵconditional(ctx.ShowDialog ? 0 : -1);
742
+ } }, dependencies: [i1.LoadingComponent], 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}"] });
604
743
  }
605
744
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserAppConfigComponent, [{
606
745
  type: Component,
607
- 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 <div class=\"panels-container\">\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 class=\"mj-btn mj-btn-primary mj-btn-outline mj-btn-sm\"\n (click)=\"addApp(item)\"\n title=\"Add to your apps\"\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($event)\"\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 class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n [disabled]=\"i === 0\"\n (click)=\"moveUp(item); $event.stopPropagation()\"\n title=\"Move up\"\n >\n <i class=\"fa-solid fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n [disabled]=\"i === activeApps.length - 1\"\n (click)=\"moveDown(item); $event.stopPropagation()\"\n title=\"Move down\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm mj-btn-danger\"\n (click)=\"removeApp(item); $event.stopPropagation()\"\n title=\"Remove from your apps\"\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 </div>\n }\n\n <!-- Footer Actions - Primary on LEFT per MD3 -->\n <div class=\"dialog-footer\">\n <div class=\"footer-left\">\n @if (hasChanges()) {\n <button\n class=\"mj-btn mj-btn-secondary\"\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 class=\"mj-btn mj-btn-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 class=\"mj-btn mj-btn-secondary\"\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/* 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/* Responsive adjustments */\n@media (max-width: 600px) {\n .config-content {\n padding: 1rem;\n }\n\n .panels-container {\n gap: 1rem;\n }\n\n .app-item-content,\n .available-app-item {\n padding: 0.625rem 0.75rem;\n }\n\n .app-icon {\n width: 2.25rem;\n height: 2.25rem;\n font-size: 1rem;\n }\n\n .dialog-footer {\n flex-direction: column;\n gap: 0.75rem;\n }\n\n .footer-left,\n .footer-right {\n width: 100%;\n justify-content: center;\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"] }]
608
- }], () => [{ type: i1.ApplicationManager }, { type: i2.SharedService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], { showDialog: [{
746
+ 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 class=\"mj-btn mj-btn-primary mj-btn-outline mj-btn-sm\"\n (click)=\"AddApp(item)\"\n title=\"Add to your apps\"\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 class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n [disabled]=\"i === 0\"\n (click)=\"MoveUp(item); $event.stopPropagation()\"\n title=\"Move up\"\n >\n <i class=\"fa-solid fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n [disabled]=\"i === ActiveApps.length - 1\"\n (click)=\"MoveDown(item); $event.stopPropagation()\"\n title=\"Move down\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm mj-btn-danger\"\n (click)=\"RemoveApp(item); $event.stopPropagation()\"\n title=\"Remove from your apps\"\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 class=\"mj-btn mj-btn-secondary\"\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 class=\"mj-btn mj-btn-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 class=\"mj-btn mj-btn-secondary\"\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"] }]
747
+ }], null, { ShowDialog: [{
609
748
  type: Input
610
- }], showDialogChange: [{
749
+ }], ShowDialogChange: [{
611
750
  type: Output
612
- }], configSaved: [{
751
+ }], ConfigSaved: [{
613
752
  type: Output
614
753
  }] }); })();
615
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserAppConfigComponent, { className: "UserAppConfigComponent", filePath: "src/lib/user-app-config/user-app-config.component.ts", lineNumber: 30 }); })();
754
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserAppConfigComponent, { className: "UserAppConfigComponent", filePath: "src/lib/user-app-config/user-app-config.component.ts", lineNumber: 41 }); })();
616
755
  //# sourceMappingURL=user-app-config.component.js.map