@memberjunction/ng-explorer-settings 2.50.0 → 2.52.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.
- package/README.md +89 -1
- package/dist/lib/application-management/application-management.component.d.ts +59 -0
- package/dist/lib/application-management/application-management.component.d.ts.map +1 -0
- package/dist/lib/application-management/application-management.component.js +540 -0
- package/dist/lib/application-management/application-management.component.js.map +1 -0
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts +71 -0
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -0
- package/dist/lib/entity-permissions/entity-permissions.component.js +667 -0
- package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -0
- package/dist/lib/module.d.ts +19 -23
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/module.js +13 -38
- package/dist/lib/module.js.map +1 -1
- package/dist/lib/role-management/role-management.component.d.ts +56 -0
- package/dist/lib/role-management/role-management.component.d.ts.map +1 -0
- package/dist/lib/role-management/role-management.component.js +464 -0
- package/dist/lib/role-management/role-management.component.js.map +1 -0
- package/dist/lib/settings/settings.component.d.ts +42 -51
- package/dist/lib/settings/settings.component.d.ts.map +1 -1
- package/dist/lib/settings/settings.component.js +432 -198
- package/dist/lib/settings/settings.component.js.map +1 -1
- package/dist/lib/shared/components/settings-card/settings-card.component.d.ts +27 -0
- package/dist/lib/shared/components/settings-card/settings-card.component.d.ts.map +1 -0
- package/dist/lib/shared/components/settings-card/settings-card.component.js +167 -0
- package/dist/lib/shared/components/settings-card/settings-card.component.js.map +1 -0
- package/dist/lib/shared/settings-card.component.d.ts +11 -0
- package/dist/lib/shared/settings-card.component.d.ts.map +1 -0
- package/dist/lib/shared/settings-card.component.js +73 -0
- package/dist/lib/shared/settings-card.component.js.map +1 -0
- package/dist/lib/shared/shared-settings.module.d.ts +9 -0
- package/dist/lib/shared/shared-settings.module.d.ts.map +1 -0
- package/dist/lib/shared/shared-settings.module.js +25 -0
- package/dist/lib/shared/shared-settings.module.js.map +1 -0
- package/dist/lib/sql-logging/sql-logging.component.d.ts +176 -0
- package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -0
- package/dist/lib/sql-logging/sql-logging.component.js +946 -0
- package/dist/lib/sql-logging/sql-logging.component.js.map +1 -0
- package/dist/lib/user-management/user-management.component.d.ts +65 -0
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -0
- package/dist/lib/user-management/user-management.component.js +643 -0
- package/dist/lib/user-management/user-management.component.js.map +1 -0
- package/dist/public-api.d.ts +1 -5
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -5
- package/dist/public-api.js.map +1 -1
- package/package.json +13 -13
- package/dist/lib/application-entities-grid/application-entities-grid.component.d.ts +0 -50
- package/dist/lib/application-entities-grid/application-entities-grid.component.d.ts.map +0 -1
- package/dist/lib/application-entities-grid/application-entities-grid.component.js +0 -342
- package/dist/lib/application-entities-grid/application-entities-grid.component.js.map +0 -1
- package/dist/lib/single-application/single-application.component.d.ts +0 -22
- package/dist/lib/single-application/single-application.component.d.ts.map +0 -1
- package/dist/lib/single-application/single-application.component.js +0 -130
- package/dist/lib/single-application/single-application.component.js.map +0 -1
- package/dist/lib/single-role/single-role.component.d.ts +0 -36
- package/dist/lib/single-role/single-role.component.d.ts.map +0 -1
- package/dist/lib/single-role/single-role.component.js +0 -188
- package/dist/lib/single-role/single-role.component.js.map +0 -1
- package/dist/lib/single-user/single-user.component.d.ts +0 -24
- package/dist/lib/single-user/single-user.component.d.ts.map +0 -1
- package/dist/lib/single-user/single-user.component.js +0 -176
- package/dist/lib/single-user/single-user.component.js.map +0 -1
- package/dist/lib/user-roles-grid/user-roles-grid.component.d.ts +0 -42
- package/dist/lib/user-roles-grid/user-roles-grid.component.d.ts.map +0 -1
- package/dist/lib/user-roles-grid/user-roles-grid.component.js +0 -326
- package/dist/lib/user-roles-grid/user-roles-grid.component.js.map +0 -1
|
@@ -4,257 +4,491 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Component } from '@angular/core';
|
|
8
|
-
import { NavigationEnd } from '@angular/router';
|
|
9
|
-
import { Metadata } from '@memberjunction/core';
|
|
7
|
+
import { Component, EventEmitter, Output } from '@angular/core';
|
|
10
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
11
|
-
import {
|
|
9
|
+
import { CommonModule } from '@angular/common';
|
|
10
|
+
import { Subject, BehaviorSubject } from 'rxjs';
|
|
11
|
+
import { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
12
|
+
import { SharedSettingsModule } from '../shared/shared-settings.module';
|
|
13
|
+
import { SqlLoggingComponent } from '../sql-logging/sql-logging.component';
|
|
14
|
+
import { UserManagementComponent } from '../user-management/user-management.component';
|
|
15
|
+
import { RoleManagementComponent } from '../role-management/role-management.component';
|
|
16
|
+
import { ApplicationManagementComponent } from '../application-management/application-management.component';
|
|
17
|
+
import { EntityPermissionsComponent } from '../entity-permissions/entity-permissions.component';
|
|
12
18
|
import { BaseNavigationComponent } from '@memberjunction/ng-shared';
|
|
13
|
-
import { filter } from 'rxjs/operators';
|
|
14
19
|
import * as i0 from "@angular/core";
|
|
15
|
-
import * as i1 from "
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
function
|
|
20
|
+
import * as i1 from "../shared/settings-card.component";
|
|
21
|
+
const _forTrack0 = ($index, $item) => $item.id;
|
|
22
|
+
function SettingsComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
23
|
+
i0.ɵɵelementStart(0, "div", 8)(1, "div", 11)(2, "div", 12);
|
|
24
|
+
i0.ɵɵelement(3, "div", 13)(4, "div", 13)(5, "div", 13);
|
|
25
|
+
i0.ɵɵelementEnd();
|
|
26
|
+
i0.ɵɵelementStart(6, "div", 14);
|
|
27
|
+
i0.ɵɵtext(7, "Loading settings...");
|
|
28
|
+
i0.ɵɵelementEnd()()();
|
|
29
|
+
} }
|
|
30
|
+
function SettingsComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
26
31
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
27
|
-
i0.ɵɵelementStart(0, "div",
|
|
28
|
-
i0.ɵɵ
|
|
32
|
+
i0.ɵɵelementStart(0, "div", 9)(1, "div", 15);
|
|
33
|
+
i0.ɵɵelement(2, "i", 16);
|
|
34
|
+
i0.ɵɵelementStart(3, "p", 17);
|
|
35
|
+
i0.ɵɵtext(4);
|
|
36
|
+
i0.ɵɵelementEnd();
|
|
37
|
+
i0.ɵɵelementStart(5, "button", 18);
|
|
38
|
+
i0.ɵɵlistener("click", function SettingsComponent_Conditional_11_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.loadInitialData()); });
|
|
39
|
+
i0.ɵɵelement(6, "i", 19);
|
|
40
|
+
i0.ɵɵtext(7, " Try Again ");
|
|
41
|
+
i0.ɵɵelementEnd()()();
|
|
42
|
+
} if (rf & 2) {
|
|
43
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
44
|
+
i0.ɵɵadvance(4);
|
|
45
|
+
i0.ɵɵtextInterpolate(ctx_r1.error);
|
|
46
|
+
} }
|
|
47
|
+
function SettingsComponent_Conditional_12_Conditional_1_For_4_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
48
|
+
i0.ɵɵelementStart(0, "span", 36);
|
|
29
49
|
i0.ɵɵtext(1);
|
|
30
50
|
i0.ɵɵelementEnd();
|
|
31
51
|
} if (rf & 2) {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
i0.ɵɵclassProp("selected", ctx_r2.leftNavItemSelected(o_r2));
|
|
52
|
+
const tab_r4 = i0.ɵɵnextContext().$implicit;
|
|
53
|
+
i0.ɵɵclassMap("badge-" + (tab_r4.badgeColor || "primary"));
|
|
35
54
|
i0.ɵɵadvance();
|
|
36
|
-
i0.ɵɵ
|
|
55
|
+
i0.ɵɵtextInterpolate1(" ", tab_r4.badgeCount, " ");
|
|
37
56
|
} }
|
|
38
|
-
function
|
|
39
|
-
i0.ɵɵ
|
|
57
|
+
function SettingsComponent_Conditional_12_Conditional_1_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
58
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
59
|
+
i0.ɵɵelementStart(0, "li", 33);
|
|
60
|
+
i0.ɵɵlistener("click", function SettingsComponent_Conditional_12_Conditional_1_For_4_Template_li_click_0_listener() { const tab_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onTabChange(tab_r4.id)); });
|
|
61
|
+
i0.ɵɵelement(1, "i");
|
|
62
|
+
i0.ɵɵelementStart(2, "span", 34);
|
|
63
|
+
i0.ɵɵtext(3);
|
|
64
|
+
i0.ɵɵelementEnd();
|
|
65
|
+
i0.ɵɵtemplate(4, SettingsComponent_Conditional_12_Conditional_1_For_4_Conditional_4_Template, 2, 3, "span", 35);
|
|
66
|
+
i0.ɵɵelementEnd();
|
|
67
|
+
} if (rf & 2) {
|
|
68
|
+
const tab_r4 = ctx.$implicit;
|
|
69
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
70
|
+
i0.ɵɵclassProp("active", ctx_r1.activeTab === tab_r4.id);
|
|
71
|
+
i0.ɵɵadvance();
|
|
72
|
+
i0.ɵɵclassMap(tab_r4.icon);
|
|
73
|
+
i0.ɵɵadvance(2);
|
|
74
|
+
i0.ɵɵtextInterpolate(tab_r4.label);
|
|
75
|
+
i0.ɵɵadvance();
|
|
76
|
+
i0.ɵɵconditional(tab_r4.badgeCount && tab_r4.badgeCount > 0 ? 4 : -1);
|
|
40
77
|
} }
|
|
41
|
-
function
|
|
42
|
-
const
|
|
43
|
-
i0.ɵɵelementStart(0, "
|
|
44
|
-
i0.ɵɵ
|
|
78
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_7_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
80
|
+
i0.ɵɵelementStart(0, "div", 27)(1, "h2", 37);
|
|
81
|
+
i0.ɵɵtext(2, "General Settings");
|
|
45
82
|
i0.ɵɵelementEnd();
|
|
83
|
+
i0.ɵɵelementStart(3, "div", 38)(4, "mj-settings-card", 39);
|
|
84
|
+
i0.ɵɵlistener("toggle", function SettingsComponent_Conditional_12_Conditional_1_Case_7_Template_mj_settings_card_toggle_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleSection("profile")); });
|
|
85
|
+
i0.ɵɵelementStart(5, "div", 40)(6, "p");
|
|
86
|
+
i0.ɵɵtext(7, "Manage your profile information and preferences.");
|
|
87
|
+
i0.ɵɵelementEnd()()();
|
|
88
|
+
i0.ɵɵelementStart(8, "mj-settings-card", 41);
|
|
89
|
+
i0.ɵɵlistener("toggle", function SettingsComponent_Conditional_12_Conditional_1_Case_7_Template_mj_settings_card_toggle_8_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleSection("preferences")); });
|
|
90
|
+
i0.ɵɵelementStart(9, "div", 40)(10, "p");
|
|
91
|
+
i0.ɵɵtext(11, "Customize your experience with display and behavior preferences.");
|
|
92
|
+
i0.ɵɵelementEnd()()();
|
|
93
|
+
i0.ɵɵelementStart(12, "mj-settings-card", 42);
|
|
94
|
+
i0.ɵɵlistener("toggle", function SettingsComponent_Conditional_12_Conditional_1_Case_7_Template_mj_settings_card_toggle_12_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleSection("notifications")); });
|
|
95
|
+
i0.ɵɵelementStart(13, "div", 40)(14, "p");
|
|
96
|
+
i0.ɵɵtext(15, "Configure how and when you receive notifications.");
|
|
97
|
+
i0.ɵɵelementEnd()()()()();
|
|
46
98
|
} if (rf & 2) {
|
|
47
|
-
const
|
|
48
|
-
i0.ɵɵ
|
|
99
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
100
|
+
i0.ɵɵadvance(4);
|
|
101
|
+
i0.ɵɵproperty("expanded", ctx_r1.isSectionExpanded("profile"));
|
|
102
|
+
i0.ɵɵadvance(4);
|
|
103
|
+
i0.ɵɵproperty("expanded", ctx_r1.isSectionExpanded("preferences"));
|
|
104
|
+
i0.ɵɵadvance(4);
|
|
105
|
+
i0.ɵɵproperty("expanded", ctx_r1.isSectionExpanded("notifications"));
|
|
49
106
|
} }
|
|
50
|
-
function
|
|
51
|
-
i0.ɵɵ
|
|
107
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_8_Template(rf, ctx) { if (rf & 1) {
|
|
108
|
+
i0.ɵɵelementStart(0, "div", 28)(1, "h2", 37);
|
|
109
|
+
i0.ɵɵtext(2, "User Management");
|
|
110
|
+
i0.ɵɵelementEnd();
|
|
111
|
+
i0.ɵɵelementStart(3, "p", 43);
|
|
112
|
+
i0.ɵɵtext(4, "Manage user accounts, roles, and permissions");
|
|
113
|
+
i0.ɵɵelementEnd();
|
|
114
|
+
i0.ɵɵelement(5, "mj-user-management");
|
|
115
|
+
i0.ɵɵelementEnd();
|
|
116
|
+
} }
|
|
117
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_9_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
+
i0.ɵɵelementStart(0, "div", 29)(1, "h2", 37);
|
|
119
|
+
i0.ɵɵtext(2, "Role Management");
|
|
120
|
+
i0.ɵɵelementEnd();
|
|
121
|
+
i0.ɵɵelementStart(3, "p", 43);
|
|
122
|
+
i0.ɵɵtext(4, "Define and manage security roles.");
|
|
123
|
+
i0.ɵɵelementEnd();
|
|
124
|
+
i0.ɵɵelement(5, "mj-role-management");
|
|
125
|
+
i0.ɵɵelementEnd();
|
|
126
|
+
} }
|
|
127
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_10_Template(rf, ctx) { if (rf & 1) {
|
|
128
|
+
i0.ɵɵelementStart(0, "div", 30);
|
|
129
|
+
i0.ɵɵelement(1, "mj-application-management");
|
|
130
|
+
i0.ɵɵelementEnd();
|
|
131
|
+
} }
|
|
132
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_11_Template(rf, ctx) { if (rf & 1) {
|
|
133
|
+
i0.ɵɵelementStart(0, "div", 31);
|
|
134
|
+
i0.ɵɵelement(1, "mj-entity-permissions");
|
|
135
|
+
i0.ɵɵelementEnd();
|
|
136
|
+
} }
|
|
137
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_12_Case_18_Template(rf, ctx) { if (rf & 1) {
|
|
138
|
+
i0.ɵɵelement(0, "mj-sql-logging");
|
|
139
|
+
} }
|
|
140
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_12_Case_19_Template(rf, ctx) { if (rf & 1) {
|
|
141
|
+
i0.ɵɵelementStart(0, "div", 52)(1, "h3");
|
|
142
|
+
i0.ɵɵtext(2, "Performance Settings");
|
|
143
|
+
i0.ɵɵelementEnd();
|
|
144
|
+
i0.ɵɵelementStart(3, "p");
|
|
145
|
+
i0.ɵɵtext(4, "Performance monitoring and optimization tools coming soon.");
|
|
146
|
+
i0.ɵɵelementEnd()();
|
|
147
|
+
} }
|
|
148
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_12_Case_20_Template(rf, ctx) { if (rf & 1) {
|
|
149
|
+
i0.ɵɵelementStart(0, "div", 53)(1, "h3");
|
|
150
|
+
i0.ɵɵtext(2, "Developer Tools");
|
|
151
|
+
i0.ɵɵelementEnd();
|
|
152
|
+
i0.ɵɵelementStart(3, "p");
|
|
153
|
+
i0.ɵɵtext(4, "Advanced developer options coming soon.");
|
|
154
|
+
i0.ɵɵelementEnd()();
|
|
155
|
+
} }
|
|
156
|
+
function SettingsComponent_Conditional_12_Conditional_1_Case_12_Template(rf, ctx) { if (rf & 1) {
|
|
157
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
158
|
+
i0.ɵɵelementStart(0, "div", 32)(1, "h2", 37);
|
|
159
|
+
i0.ɵɵtext(2, "Advanced Settings");
|
|
160
|
+
i0.ɵɵelementEnd();
|
|
161
|
+
i0.ɵɵelementStart(3, "div", 44);
|
|
162
|
+
i0.ɵɵelement(4, "i", 45);
|
|
163
|
+
i0.ɵɵelementStart(5, "span");
|
|
164
|
+
i0.ɵɵtext(6, "Beta features - Use with caution");
|
|
165
|
+
i0.ɵɵelementEnd()();
|
|
166
|
+
i0.ɵɵelementStart(7, "div", 46)(8, "button", 47);
|
|
167
|
+
i0.ɵɵlistener("click", function SettingsComponent_Conditional_12_Conditional_1_Case_12_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setAdvancedTab("sql-logging")); });
|
|
168
|
+
i0.ɵɵelement(9, "i", 48);
|
|
169
|
+
i0.ɵɵtext(10, " SQL Logging ");
|
|
170
|
+
i0.ɵɵelementEnd();
|
|
171
|
+
i0.ɵɵelementStart(11, "button", 47);
|
|
172
|
+
i0.ɵɵlistener("click", function SettingsComponent_Conditional_12_Conditional_1_Case_12_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setAdvancedTab("performance")); });
|
|
173
|
+
i0.ɵɵelement(12, "i", 49);
|
|
174
|
+
i0.ɵɵtext(13, " Performance ");
|
|
175
|
+
i0.ɵɵelementEnd();
|
|
176
|
+
i0.ɵɵelementStart(14, "button", 47);
|
|
177
|
+
i0.ɵɵlistener("click", function SettingsComponent_Conditional_12_Conditional_1_Case_12_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setAdvancedTab("developer")); });
|
|
178
|
+
i0.ɵɵelement(15, "i", 50);
|
|
179
|
+
i0.ɵɵtext(16, " Developer Tools ");
|
|
180
|
+
i0.ɵɵelementEnd()();
|
|
181
|
+
i0.ɵɵelementStart(17, "div", 51);
|
|
182
|
+
i0.ɵɵtemplate(18, SettingsComponent_Conditional_12_Conditional_1_Case_12_Case_18_Template, 1, 0, "mj-sql-logging")(19, SettingsComponent_Conditional_12_Conditional_1_Case_12_Case_19_Template, 5, 0, "div", 52)(20, SettingsComponent_Conditional_12_Conditional_1_Case_12_Case_20_Template, 5, 0, "div", 53);
|
|
183
|
+
i0.ɵɵelementEnd()();
|
|
52
184
|
} if (rf & 2) {
|
|
53
|
-
|
|
54
|
-
i0.ɵɵ
|
|
185
|
+
let tmp_6_0;
|
|
186
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
187
|
+
i0.ɵɵadvance(8);
|
|
188
|
+
i0.ɵɵclassProp("active", ctx_r1.advancedActiveTab === "sql-logging");
|
|
189
|
+
i0.ɵɵadvance(3);
|
|
190
|
+
i0.ɵɵclassProp("active", ctx_r1.advancedActiveTab === "performance");
|
|
191
|
+
i0.ɵɵadvance(3);
|
|
192
|
+
i0.ɵɵclassProp("active", ctx_r1.advancedActiveTab === "developer");
|
|
193
|
+
i0.ɵɵadvance(4);
|
|
194
|
+
i0.ɵɵconditional((tmp_6_0 = ctx_r1.advancedActiveTab) === "sql-logging" ? 18 : tmp_6_0 === "performance" ? 19 : tmp_6_0 === "developer" ? 20 : -1);
|
|
55
195
|
} }
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
i0.ɵɵ
|
|
59
|
-
i0.ɵɵ
|
|
196
|
+
function SettingsComponent_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
197
|
+
i0.ɵɵelementStart(0, "div", 20)(1, "nav", 22)(2, "ul", 23);
|
|
198
|
+
i0.ɵɵrepeaterCreate(3, SettingsComponent_Conditional_12_Conditional_1_For_4_Template, 5, 6, "li", 24, _forTrack0);
|
|
199
|
+
i0.ɵɵelementEnd()();
|
|
200
|
+
i0.ɵɵelementStart(5, "div", 25)(6, "div", 26);
|
|
201
|
+
i0.ɵɵtemplate(7, SettingsComponent_Conditional_12_Conditional_1_Case_7_Template, 16, 3, "div", 27)(8, SettingsComponent_Conditional_12_Conditional_1_Case_8_Template, 6, 0, "div", 28)(9, SettingsComponent_Conditional_12_Conditional_1_Case_9_Template, 6, 0, "div", 29)(10, SettingsComponent_Conditional_12_Conditional_1_Case_10_Template, 2, 0, "div", 30)(11, SettingsComponent_Conditional_12_Conditional_1_Case_11_Template, 2, 0, "div", 31)(12, SettingsComponent_Conditional_12_Conditional_1_Case_12_Template, 21, 7, "div", 32);
|
|
202
|
+
i0.ɵɵelementEnd()()();
|
|
203
|
+
} if (rf & 2) {
|
|
204
|
+
let tmp_3_0;
|
|
205
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
206
|
+
i0.ɵɵadvance(3);
|
|
207
|
+
i0.ɵɵrepeater(ctx_r1.tabs);
|
|
208
|
+
i0.ɵɵadvance(4);
|
|
209
|
+
i0.ɵɵconditional((tmp_3_0 = ctx_r1.activeTab) === "general" ? 7 : tmp_3_0 === "users" ? 8 : tmp_3_0 === "roles" ? 9 : tmp_3_0 === "applications" ? 10 : tmp_3_0 === "permissions" ? 11 : tmp_3_0 === "advanced" ? 12 : -1);
|
|
210
|
+
} }
|
|
211
|
+
function SettingsComponent_Conditional_12_Conditional_2_Case_2_Template(rf, ctx) { if (rf & 1) {
|
|
212
|
+
i0.ɵɵelementStart(0, "div", 27)(1, "h2", 37);
|
|
213
|
+
i0.ɵɵtext(2, "General Settings");
|
|
214
|
+
i0.ɵɵelementEnd()();
|
|
215
|
+
} }
|
|
216
|
+
function SettingsComponent_Conditional_12_Conditional_2_Case_3_Template(rf, ctx) { if (rf & 1) {
|
|
217
|
+
i0.ɵɵelementStart(0, "div", 28)(1, "h2", 37);
|
|
218
|
+
i0.ɵɵtext(2, "User Management");
|
|
219
|
+
i0.ɵɵelementEnd();
|
|
220
|
+
i0.ɵɵelementStart(3, "p", 43);
|
|
221
|
+
i0.ɵɵtext(4, "Manage user accounts, roles, and permissions");
|
|
222
|
+
i0.ɵɵelementEnd();
|
|
223
|
+
i0.ɵɵelement(5, "mj-user-management");
|
|
224
|
+
i0.ɵɵelementEnd();
|
|
225
|
+
} }
|
|
226
|
+
function SettingsComponent_Conditional_12_Conditional_2_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
227
|
+
i0.ɵɵelementStart(0, "span", 62);
|
|
228
|
+
i0.ɵɵtext(1);
|
|
60
229
|
i0.ɵɵelementEnd();
|
|
61
230
|
} if (rf & 2) {
|
|
62
|
-
|
|
231
|
+
const tab_r8 = i0.ɵɵnextContext().$implicit;
|
|
232
|
+
i0.ɵɵclassMap("badge-" + (tab_r8.badgeColor || "primary"));
|
|
233
|
+
i0.ɵɵadvance();
|
|
234
|
+
i0.ɵɵtextInterpolate1(" ", tab_r8.badgeCount, " ");
|
|
63
235
|
} }
|
|
64
|
-
function
|
|
65
|
-
i0.ɵɵ
|
|
236
|
+
function SettingsComponent_Conditional_12_Conditional_2_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
237
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
238
|
+
i0.ɵɵelementStart(0, "button", 59);
|
|
239
|
+
i0.ɵɵlistener("click", function SettingsComponent_Conditional_12_Conditional_2_For_7_Template_button_click_0_listener() { const tab_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onTabChange(tab_r8.id)); });
|
|
240
|
+
i0.ɵɵelement(1, "i");
|
|
241
|
+
i0.ɵɵtemplate(2, SettingsComponent_Conditional_12_Conditional_2_For_7_Conditional_2_Template, 2, 3, "span", 60);
|
|
242
|
+
i0.ɵɵelementStart(3, "span", 61);
|
|
243
|
+
i0.ɵɵtext(4);
|
|
244
|
+
i0.ɵɵelementEnd()();
|
|
66
245
|
} if (rf & 2) {
|
|
67
|
-
const
|
|
68
|
-
i0.ɵɵ
|
|
246
|
+
const tab_r8 = ctx.$implicit;
|
|
247
|
+
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
248
|
+
i0.ɵɵclassProp("active", ctx_r1.activeTab === tab_r8.id);
|
|
249
|
+
i0.ɵɵadvance();
|
|
250
|
+
i0.ɵɵclassMap(tab_r8.icon);
|
|
251
|
+
i0.ɵɵadvance();
|
|
252
|
+
i0.ɵɵconditional(tab_r8.badgeCount && tab_r8.badgeCount > 0 ? 2 : -1);
|
|
253
|
+
i0.ɵɵadvance(2);
|
|
254
|
+
i0.ɵɵtextInterpolate(tab_r8.label);
|
|
69
255
|
} }
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
-
i0.ɵɵ
|
|
73
|
-
i0.ɵɵ
|
|
256
|
+
function SettingsComponent_Conditional_12_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
257
|
+
i0.ɵɵelementStart(0, "button", 58);
|
|
258
|
+
i0.ɵɵelement(1, "i", 63);
|
|
259
|
+
i0.ɵɵelementStart(2, "span", 61);
|
|
260
|
+
i0.ɵɵtext(3, "More");
|
|
261
|
+
i0.ɵɵelementEnd()();
|
|
262
|
+
} }
|
|
263
|
+
function SettingsComponent_Conditional_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
264
|
+
i0.ɵɵelementStart(0, "div", 21)(1, "div", 54);
|
|
265
|
+
i0.ɵɵtemplate(2, SettingsComponent_Conditional_12_Conditional_2_Case_2_Template, 3, 0, "div", 27)(3, SettingsComponent_Conditional_12_Conditional_2_Case_3_Template, 6, 0, "div", 28);
|
|
74
266
|
i0.ɵɵelementEnd();
|
|
267
|
+
i0.ɵɵelementStart(4, "nav", 55)(5, "div", 56);
|
|
268
|
+
i0.ɵɵrepeaterCreate(6, SettingsComponent_Conditional_12_Conditional_2_For_7_Template, 5, 6, "button", 57, _forTrack0);
|
|
269
|
+
i0.ɵɵtemplate(8, SettingsComponent_Conditional_12_Conditional_2_Conditional_8_Template, 4, 0, "button", 58);
|
|
270
|
+
i0.ɵɵelementEnd()()();
|
|
75
271
|
} if (rf & 2) {
|
|
76
|
-
|
|
272
|
+
let tmp_2_0;
|
|
273
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
274
|
+
i0.ɵɵadvance(2);
|
|
275
|
+
i0.ɵɵconditional((tmp_2_0 = ctx_r1.activeTab) === "general" ? 2 : tmp_2_0 === "users" ? 3 : -1);
|
|
276
|
+
i0.ɵɵadvance(4);
|
|
277
|
+
i0.ɵɵrepeater(ctx_r1.tabs.slice(0, 5));
|
|
278
|
+
i0.ɵɵadvance(2);
|
|
279
|
+
i0.ɵɵconditional(ctx_r1.tabs.length > 5 ? 8 : -1);
|
|
77
280
|
} }
|
|
78
|
-
function
|
|
79
|
-
i0.ɵɵ
|
|
281
|
+
function SettingsComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
282
|
+
i0.ɵɵelementStart(0, "div", 10);
|
|
283
|
+
i0.ɵɵtemplate(1, SettingsComponent_Conditional_12_Conditional_1_Template, 13, 1, "div", 20)(2, SettingsComponent_Conditional_12_Conditional_2_Template, 9, 2, "div", 21);
|
|
284
|
+
i0.ɵɵelementEnd();
|
|
80
285
|
} if (rf & 2) {
|
|
81
|
-
const
|
|
82
|
-
i0.ɵɵ
|
|
286
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
287
|
+
i0.ɵɵadvance();
|
|
288
|
+
i0.ɵɵconditional(!ctx_r1.isMobile ? 1 : -1);
|
|
289
|
+
i0.ɵɵadvance();
|
|
290
|
+
i0.ɵɵconditional(ctx_r1.isMobile ? 2 : -1);
|
|
83
291
|
} }
|
|
84
|
-
export var SettingsItem;
|
|
85
|
-
(function (SettingsItem) {
|
|
86
|
-
SettingsItem["EntityPermissions"] = "EntityPermissions";
|
|
87
|
-
SettingsItem["Users"] = "Users";
|
|
88
|
-
SettingsItem["User"] = "User";
|
|
89
|
-
SettingsItem["Roles"] = "Roles";
|
|
90
|
-
SettingsItem["Role"] = "Role";
|
|
91
|
-
SettingsItem["Applications"] = "Applications";
|
|
92
|
-
SettingsItem["Application"] = "Application";
|
|
93
|
-
})(SettingsItem || (SettingsItem = {}));
|
|
94
292
|
let SettingsComponent = class SettingsComponent extends BaseNavigationComponent {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
293
|
+
stateChange = new EventEmitter();
|
|
294
|
+
// State management
|
|
295
|
+
activeTab = 'general';
|
|
296
|
+
advancedActiveTab = 'sql-logging';
|
|
297
|
+
searchTerm$ = new BehaviorSubject('');
|
|
298
|
+
isLoading = false;
|
|
299
|
+
error = null;
|
|
300
|
+
// Tab configuration
|
|
301
|
+
tabs = [
|
|
302
|
+
{
|
|
303
|
+
id: 'general',
|
|
304
|
+
label: 'General',
|
|
305
|
+
icon: 'fa-solid fa-cog',
|
|
306
|
+
badgeCount: 0
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: 'users',
|
|
310
|
+
label: 'Users',
|
|
311
|
+
icon: 'fa-solid fa-users',
|
|
312
|
+
badgeCount: 0
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
id: 'roles',
|
|
316
|
+
label: 'Roles',
|
|
317
|
+
icon: 'fa-solid fa-shield-halved',
|
|
318
|
+
badgeCount: 0
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
id: 'applications',
|
|
322
|
+
label: 'Applications',
|
|
323
|
+
icon: 'fa-solid fa-grid-2',
|
|
324
|
+
badgeCount: 0
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
id: 'permissions',
|
|
328
|
+
label: 'Permissions',
|
|
329
|
+
icon: 'fa-solid fa-lock',
|
|
330
|
+
badgeCount: 0
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
id: 'advanced',
|
|
334
|
+
label: 'Advanced',
|
|
335
|
+
icon: 'fa-solid fa-flask',
|
|
336
|
+
badgeCount: 1,
|
|
337
|
+
badgeColor: 'warning'
|
|
338
|
+
}
|
|
108
339
|
];
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
changeRoute(subPath) {
|
|
118
|
-
// Constructs a navigation path relative to the /settings base route
|
|
119
|
-
this.router.navigate([this.baseRoute, subPath]);
|
|
120
|
-
}
|
|
121
|
-
constructor(router, activatedRoute) {
|
|
340
|
+
// Section expansion state
|
|
341
|
+
expandedSections = ['profile', 'preferences'];
|
|
342
|
+
// Mobile state
|
|
343
|
+
isMobile = window.innerWidth < 768;
|
|
344
|
+
destroy$ = new Subject();
|
|
345
|
+
constructor() {
|
|
346
|
+
// Listen for window resize
|
|
122
347
|
super();
|
|
123
|
-
this.
|
|
124
|
-
this.activatedRoute = activatedRoute;
|
|
348
|
+
window.addEventListener('resize', this.handleResize.bind(this));
|
|
125
349
|
}
|
|
126
350
|
ngOnInit() {
|
|
127
|
-
|
|
128
|
-
this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
351
|
+
this.setupSearchFilter();
|
|
352
|
+
this.loadInitialData();
|
|
353
|
+
}
|
|
354
|
+
ngOnDestroy() {
|
|
355
|
+
this.destroy$.next();
|
|
356
|
+
this.destroy$.complete();
|
|
357
|
+
window.removeEventListener('resize', this.handleResize.bind(this));
|
|
358
|
+
}
|
|
359
|
+
setupSearchFilter() {
|
|
360
|
+
this.searchTerm$
|
|
361
|
+
.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.destroy$))
|
|
362
|
+
.subscribe(term => {
|
|
363
|
+
this.filterContent(term);
|
|
364
|
+
this.emitStateChange();
|
|
132
365
|
});
|
|
133
366
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
break;
|
|
145
|
-
case 'applications':
|
|
146
|
-
this.selectItem(SettingsItem.Applications, false);
|
|
147
|
-
break;
|
|
148
|
-
case 'application':
|
|
149
|
-
this.selectedApplicationName = segments.length > 2 ? segments[2] : '';
|
|
150
|
-
const md = new Metadata();
|
|
151
|
-
this.selectedApplicationID = md.Applications.find(a => a.Name === this.selectedApplicationName)?.ID ?? '';
|
|
152
|
-
this.selectItem(SettingsItem.Application, false);
|
|
153
|
-
break;
|
|
154
|
-
case 'users':
|
|
155
|
-
this.selectItem(SettingsItem.Users, false);
|
|
156
|
-
break;
|
|
157
|
-
case 'user':
|
|
158
|
-
this.selectedUserID = segments.length > 2 ? segments[2] : "";
|
|
159
|
-
this.selectItem(SettingsItem.User, false);
|
|
160
|
-
break;
|
|
161
|
-
case 'roles':
|
|
162
|
-
this.selectItem(SettingsItem.Roles, false);
|
|
163
|
-
break;
|
|
164
|
-
case 'role':
|
|
165
|
-
this.selectedRoleID = segments.length > 2 ? segments[2] : '';
|
|
166
|
-
this.selectItem(SettingsItem.Role, false);
|
|
167
|
-
break;
|
|
168
|
-
default:
|
|
169
|
-
break;
|
|
367
|
+
async loadInitialData() {
|
|
368
|
+
try {
|
|
369
|
+
this.isLoading = true;
|
|
370
|
+
// TODO: Load user settings, roles, applications data
|
|
371
|
+
await this.simulateDataLoad();
|
|
372
|
+
this.isLoading = false;
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
this.error = 'Failed to load settings data';
|
|
376
|
+
this.isLoading = false;
|
|
170
377
|
}
|
|
171
378
|
}
|
|
172
|
-
|
|
173
|
-
|
|
379
|
+
async simulateDataLoad() {
|
|
380
|
+
return new Promise(resolve => setTimeout(resolve, 500));
|
|
174
381
|
}
|
|
175
|
-
|
|
176
|
-
this.
|
|
382
|
+
onTabChange(tabId) {
|
|
383
|
+
this.activeTab = tabId;
|
|
384
|
+
this.emitStateChange();
|
|
177
385
|
}
|
|
178
|
-
|
|
179
|
-
|
|
386
|
+
onSearchChange(event) {
|
|
387
|
+
const term = event.target.value;
|
|
388
|
+
this.searchTerm$.next(term);
|
|
180
389
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
390
|
+
toggleSection(sectionId) {
|
|
391
|
+
const index = this.expandedSections.indexOf(sectionId);
|
|
392
|
+
if (index === -1) {
|
|
393
|
+
this.expandedSections.push(sectionId);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
this.expandedSections.splice(index, 1);
|
|
397
|
+
}
|
|
398
|
+
this.emitStateChange();
|
|
188
399
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
* based on the user's IsActive status
|
|
192
|
-
*/
|
|
193
|
-
getUserToggleTooltip(record) {
|
|
194
|
-
const user = record;
|
|
195
|
-
return user.IsActive ? 'Deactivate user' : 'Activate user';
|
|
400
|
+
isSectionExpanded(sectionId) {
|
|
401
|
+
return this.expandedSections.includes(sectionId);
|
|
196
402
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
403
|
+
setAdvancedTab(tabId) {
|
|
404
|
+
this.advancedActiveTab = tabId;
|
|
405
|
+
}
|
|
406
|
+
filterContent(term) {
|
|
407
|
+
// TODO: Implement content filtering based on search term
|
|
408
|
+
console.log('Filtering content with term:', term);
|
|
409
|
+
}
|
|
410
|
+
handleResize() {
|
|
411
|
+
this.isMobile = window.innerWidth < 768;
|
|
412
|
+
}
|
|
413
|
+
emitStateChange() {
|
|
414
|
+
const state = {
|
|
415
|
+
activeTab: this.activeTab,
|
|
416
|
+
searchTerm: this.searchTerm$.value,
|
|
417
|
+
expandedSections: [...this.expandedSections]
|
|
418
|
+
};
|
|
419
|
+
this.stateChange.emit(state);
|
|
420
|
+
}
|
|
421
|
+
loadUserState(state) {
|
|
422
|
+
if (state.activeTab) {
|
|
423
|
+
this.activeTab = state.activeTab;
|
|
216
424
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
425
|
+
if (state.searchTerm !== undefined) {
|
|
426
|
+
this.searchTerm$.next(state.searchTerm);
|
|
427
|
+
}
|
|
428
|
+
if (state.expandedSections) {
|
|
429
|
+
this.expandedSections = [...state.expandedSections];
|
|
220
430
|
}
|
|
221
431
|
}
|
|
222
|
-
|
|
223
|
-
|
|
432
|
+
getTabIcon(tab) {
|
|
433
|
+
return tab.icon;
|
|
224
434
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
435
|
+
getTabClass(tab) {
|
|
436
|
+
const classes = ['settings-tab'];
|
|
437
|
+
if (this.activeTab === tab.id) {
|
|
438
|
+
classes.push('active');
|
|
439
|
+
}
|
|
440
|
+
if (tab.badgeCount && tab.badgeCount > 0) {
|
|
441
|
+
classes.push('has-badge');
|
|
442
|
+
}
|
|
443
|
+
return classes.join(' ');
|
|
229
444
|
}
|
|
230
|
-
static ɵfac = function SettingsComponent_Factory(t) { return new (t || SettingsComponent)(
|
|
231
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SettingsComponent, selectors: [["mj-settings"]], features: [i0.ɵɵInheritDefinitionFeature], decls:
|
|
232
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
|
|
233
|
-
i0.ɵɵ
|
|
234
|
-
i0.ɵɵ
|
|
235
|
-
i0.ɵɵ
|
|
236
|
-
i0.ɵɵtemplate(4, SettingsComponent_Case_4_Template, 1, 0, "mj-entity-permissions-selector-with-grid")(5, SettingsComponent_Case_5_Template, 1, 9, "mj-simple-record-list", 4)(6, SettingsComponent_Case_6_Template, 1, 1, "mj-single-user", 5)(7, SettingsComponent_Case_7_Template, 1, 2, "mj-simple-record-list", 6)(8, SettingsComponent_Case_8_Template, 1, 1, "mj-single-role", 7)(9, SettingsComponent_Case_9_Template, 1, 2, "mj-simple-record-list", 8)(10, SettingsComponent_Case_10_Template, 1, 1, "mj-single-application", 9);
|
|
445
|
+
static ɵfac = function SettingsComponent_Factory(t) { return new (t || SettingsComponent)(); };
|
|
446
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SettingsComponent, selectors: [["mj-settings"]], outputs: { stateChange: "stateChange" }, standalone: true, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵStandaloneFeature], decls: 13, vars: 4, consts: [[1, "settings-container"], [1, "settings-header"], [1, "header-content"], [1, "header-title"], [1, "fa-solid", "fa-cog", "header-icon"], [1, "header-search"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search settings...", 1, "search-input", 3, "input", "value"], [1, "loading-container"], [1, "error-container"], [1, "settings-content"], [1, "loading-content"], [1, "loading-spinner"], [1, "spinner-ring"], [1, "loading-text"], [1, "error-content"], [1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], [1, "retry-button", 3, "click"], [1, "fa-solid", "fa-refresh"], [1, "desktop-layout", 2, "display", "flex"], [1, "mobile-layout"], [1, "side-navigation"], [1, "nav-list"], [1, "nav-item", 3, "active"], [1, "content-area"], [1, "tab-content"], [1, "general-settings"], [1, "users-settings"], [1, "roles-settings"], [1, "applications-settings"], [1, "permissions-settings"], [1, "advanced-settings"], [1, "nav-item", 3, "click"], [1, "nav-label"], [1, "nav-badge", 3, "class"], [1, "nav-badge"], [1, "section-title"], [1, "settings-grid"], ["title", "Profile Information", "icon", "fa-solid fa-user", 3, "toggle", "expanded"], [1, "card-content"], ["title", "Preferences", "icon", "fa-solid fa-sliders", 3, "toggle", "expanded"], ["title", "Notifications", "icon", "fa-solid fa-bell", 3, "toggle", "expanded"], [1, "section-description"], [1, "beta-warning"], [1, "fa-solid", "fa-flask"], [1, "advanced-tabs"], [1, "tab-btn", 3, "click"], [1, "fa-solid", "fa-database"], [1, "fa-solid", "fa-gauge-high"], [1, "fa-solid", "fa-code"], [1, "advanced-tab-content"], [1, "performance-settings"], [1, "developer-settings"], [1, "mobile-content"], [1, "mobile-navigation"], [1, "nav-tabs"], [1, "nav-tab", 3, "active"], [1, "nav-tab", "more-tab"], [1, "nav-tab", 3, "click"], [1, "tab-badge", 3, "class"], [1, "tab-label"], [1, "tab-badge"], [1, "fa-solid", "fa-ellipsis"]], template: function SettingsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
447
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3);
|
|
448
|
+
i0.ɵɵelement(4, "i", 4);
|
|
449
|
+
i0.ɵɵelementStart(5, "h1");
|
|
450
|
+
i0.ɵɵtext(6, "Settings");
|
|
237
451
|
i0.ɵɵelementEnd()();
|
|
452
|
+
i0.ɵɵelementStart(7, "div", 5);
|
|
453
|
+
i0.ɵɵelement(8, "i", 6);
|
|
454
|
+
i0.ɵɵelementStart(9, "input", 7);
|
|
455
|
+
i0.ɵɵlistener("input", function SettingsComponent_Template_input_input_9_listener($event) { return ctx.onSearchChange($event); });
|
|
456
|
+
i0.ɵɵelementEnd()()()();
|
|
457
|
+
i0.ɵɵtemplate(10, SettingsComponent_Conditional_10_Template, 8, 0, "div", 8)(11, SettingsComponent_Conditional_11_Template, 8, 1, "div", 9)(12, SettingsComponent_Conditional_12_Template, 3, 2, "div", 10);
|
|
458
|
+
i0.ɵɵelementEnd();
|
|
238
459
|
} if (rf & 2) {
|
|
239
|
-
|
|
240
|
-
i0.ɵɵproperty("
|
|
241
|
-
i0.ɵɵadvance();
|
|
242
|
-
i0.ɵɵproperty("fillWidth", false);
|
|
460
|
+
i0.ɵɵadvance(9);
|
|
461
|
+
i0.ɵɵproperty("value", ctx.searchTerm$.value);
|
|
243
462
|
i0.ɵɵadvance();
|
|
244
|
-
i0.ɵɵ
|
|
463
|
+
i0.ɵɵconditional(ctx.isLoading ? 10 : -1);
|
|
245
464
|
i0.ɵɵadvance();
|
|
246
|
-
i0.ɵɵ
|
|
465
|
+
i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 11 : -1);
|
|
247
466
|
i0.ɵɵadvance();
|
|
248
|
-
i0.ɵɵconditional(
|
|
249
|
-
} }, dependencies: [
|
|
467
|
+
i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 12 : -1);
|
|
468
|
+
} }, dependencies: [CommonModule,
|
|
469
|
+
SharedSettingsModule, i1.SettingsCardComponent, SqlLoggingComponent,
|
|
470
|
+
UserManagementComponent,
|
|
471
|
+
RoleManagementComponent,
|
|
472
|
+
ApplicationManagementComponent,
|
|
473
|
+
EntityPermissionsComponent], styles: ["@import '../shared/styles/variables';\n@import '../shared/styles/mixins';\n\n.settings-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: #f5f7fa;\n overflow: hidden;\n position: relative;\n}\n\n//[_ngcontent-%COMP%] Header[_ngcontent-%COMP%] Section\n.settings-header[_ngcontent-%COMP%] {\n background-color: #ffffff;\n border-bottom: 1px solid #e5e7eb;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n z-index: 10;\n}\n\n.header-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 2rem;\n\n @media (max-width: 768px) {\n padding: 1rem;\n flex-direction: column;\n gap: 1rem;\n }\n}\n\n.header-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n\n .header-icon {\n font-size: 1.75rem;\n color: #2196f3;\n }\n\n h1 {\n margin: 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: #1f2937;\n }\n}\n\n.header-search[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n max-width: 400px;\n\n .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n }\n\n .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n background-color: #f9fafb;\n\n &:focus {\n outline: none;\n border-color: #2196f3;\n background-color: #ffffff;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n }\n\n &::placeholder {\n color: #9ca3af;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Loading[_ngcontent-%COMP%] State\n.loading-container[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 2rem;\n}\n\n.loading-content[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n position: relative;\n width: 60px;\n height: 60px;\n margin: 0 auto 1rem;\n\n .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n\n &:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n }\n\n &:nth-child(2) {\n border-color: transparent #4caf50 transparent transparent;\n animation-delay: -0.3s;\n }\n\n &:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n }\n }\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.loading-text[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n//[_ngcontent-%COMP%] Error[_ngcontent-%COMP%] State\n.error-container[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 2rem;\n}\n\n.error-content[_ngcontent-%COMP%] {\n text-align: center;\n max-width: 400px;\n\n .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n }\n\n .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n font-size: 1rem;\n }\n\n .retry-button {\n @include button-base;\n background-color: #2196f3;\n color: white;\n padding: 0.75rem 1.5rem;\n font-size: 0.95rem;\n border-radius: 8px;\n transition: all 0.2s;\n\n &:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n }\n\n i {\n margin-right: 0.5rem;\n }\n }\n}\n\n//[_ngcontent-%COMP%] Main[_ngcontent-%COMP%] Content\n.settings-content[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n flex-direction: column;\n width: 100%;\n}\n\n//[_ngcontent-%COMP%] Desktop[_ngcontent-%COMP%] Layout\n.desktop-layout[_ngcontent-%COMP%] {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n//[_ngcontent-%COMP%] More[_ngcontent-%COMP%] specific[_ngcontent-%COMP%] selector[_ngcontent-%COMP%] to[_ngcontent-%COMP%] ensure[_ngcontent-%COMP%] it[_ngcontent-%COMP%] applies\n.settings-content[_ngcontent-%COMP%] .desktop-layout[_ngcontent-%COMP%] {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n// Deep selector for Angular ViewEncapsulation\n[_nghost-%COMP%] .desktop-layout {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n.side-navigation[_ngcontent-%COMP%] {\n width: 260px;\n background-color: #ffffff;\n border-right: 1px solid #e5e7eb;\n overflow-y: auto;\n flex-shrink: 0;\n}\n\n.nav-list[_ngcontent-%COMP%] {\n list-style: none;\n margin: 0;\n padding: 1rem 0;\n}\n\n.nav-item[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n padding: 0.875rem 1.5rem;\n cursor: pointer;\n transition: all 0.2s;\n color: #4b5563;\n font-size: 0.95rem;\n\n &:hover {\n background-color: #f3f4f6;\n color: #1f2937;\n }\n\n &.active {\n background-color: #eff6ff;\n color: #2196f3;\n font-weight: 500;\n\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background-color: #2196f3;\n }\n }\n\n i {\n width: 20px;\n margin-right: 0.75rem;\n font-size: 1.1rem;\n }\n\n .nav-label {\n flex: 1;\n }\n\n .nav-badge {\n padding: 0.125rem 0.5rem;\n border-radius: 12px;\n font-size: 0.75rem;\n font-weight: 600;\n \n &.badge-primary {\n background-color: #dbeafe;\n color: #1e40af;\n }\n\n &.badge-danger {\n background-color: #fee2e2;\n color: #991b1b;\n }\n\n &.badge-warning {\n background-color: #fef3c7;\n color: #92400e;\n }\n\n &.badge-success {\n background-color: #d1fae5;\n color: #065f46;\n }\n }\n}\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 2rem;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 0; // Important for proper flex sizing\n\n @media (max-width: 768px) {\n padding: 1rem;\n }\n}\n\n.tab-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n min-height: 0; // Important for proper flex sizing\n}\n\n//[_ngcontent-%COMP%] Section[_ngcontent-%COMP%] Styles\n.section-title[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n}\n\n.section-description[_ngcontent-%COMP%] {\n color: #6b7280;\n margin: 0 0 2rem 0;\n font-size: 0.95rem;\n}\n\n.settings-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n gap: 1.5rem;\n margin-top: 1.5rem;\n\n @media (max-width: 768px) {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n}\n\n.card-content[_ngcontent-%COMP%] {\n padding: 1rem;\n color: #4b5563;\n font-size: 0.95rem;\n\n p {\n margin: 0 0 1rem 0;\n line-height: 1.6;\n }\n}\n\n//[_ngcontent-%COMP%] Beta[_ngcontent-%COMP%] Warning\n.beta-warning[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n background-color: #fef3c7;\n color: #92400e;\n border-radius: 6px;\n font-size: 0.875rem;\n margin-bottom: 1.5rem;\n\n i {\n font-size: 1rem;\n }\n}\n\n//[_ngcontent-%COMP%] Mobile[_ngcontent-%COMP%] Layout\n.mobile-layout[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.mobile-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n padding-bottom: 80px; // Space for bottom nav\n}\n\n.mobile-navigation[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background-color: #ffffff;\n border-top: 1px solid #e5e7eb;\n box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);\n z-index: 100;\n}\n\n.nav-tabs[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-around;\n align-items: center;\n padding: 0.5rem 0;\n}\n\n.nav-tab[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.25rem;\n padding: 0.5rem;\n background: none;\n border: none;\n color: #9ca3af;\n cursor: pointer;\n transition: all 0.2s;\n font-size: 0.75rem;\n min-width: 60px;\n\n &.active {\n color: #2196f3;\n\n i {\n transform: scale(1.1);\n }\n }\n\n &:active {\n transform: scale(0.95);\n }\n\n i {\n font-size: 1.25rem;\n transition: transform 0.2s;\n }\n\n .tab-badge {\n position: absolute;\n top: 0.25rem;\n right: 0.25rem;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 8px;\n font-size: 0.625rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &.badge-primary {\n background-color: #2196f3;\n color: white;\n }\n\n &.badge-warning {\n background-color: #ff9800;\n color: white;\n }\n }\n\n .tab-label {\n margin-top: 0.125rem;\n }\n}\n\n.more-tab[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n\n//[_ngcontent-%COMP%] Advanced[_ngcontent-%COMP%] Settings[_ngcontent-%COMP%] Tabs\n.advanced-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n border-bottom: 2px solid #e5e7eb;\n margin-bottom: 2rem;\n margin-top: 1.5rem;\n\n .tab-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n color: #6b7280;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n position: relative;\n\n &:hover {\n color: #374151;\n background: #f9fafb;\n }\n\n &.active {\n color: #2196f3;\n border-bottom-color: #2196f3;\n background: #eff6ff;\n\n i {\n color: #2196f3;\n }\n }\n\n i {\n font-size: 1.125rem;\n }\n }\n}\n\n.advanced-tab-content[_ngcontent-%COMP%] {\n @include scrollable-content;\n background: white;\n border-radius: 12px;\n padding: 0;\n min-height: 500px;\n max-height: calc(100vh - 350px);\n}\n\n.performance-settings[_ngcontent-%COMP%], \n.developer-settings[_ngcontent-%COMP%] {\n padding: 2rem;\n \n h3 {\n margin: 0 0 1rem 0;\n color: #1f2937;\n font-size: 1.25rem;\n }\n \n p {\n color: #6b7280;\n font-size: 0.95rem;\n }\n}\n\n//[_ngcontent-%COMP%] Animations\n@keyframes[_ngcontent-%COMP%] fadeIn[_ngcontent-%COMP%] {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.general-settings[_ngcontent-%COMP%], \n.users-settings[_ngcontent-%COMP%], \n.roles-settings[_ngcontent-%COMP%], \n.applications-settings[_ngcontent-%COMP%], \n.permissions-settings[_ngcontent-%COMP%], \n.advanced-settings[_ngcontent-%COMP%] {\n animation: fadeIn 0.3s ease-out;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0; // Important for proper flex sizing\n overflow: hidden;\n \n // Direct child components should handle their own scrolling\n > * {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n }\n}"] });
|
|
250
474
|
};
|
|
251
475
|
SettingsComponent = __decorate([
|
|
252
|
-
RegisterClass(BaseNavigationComponent,
|
|
476
|
+
RegisterClass(BaseNavigationComponent, "Settings")
|
|
253
477
|
], SettingsComponent);
|
|
254
478
|
export { SettingsComponent };
|
|
255
479
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SettingsComponent, [{
|
|
256
480
|
type: Component,
|
|
257
|
-
args: [{ selector: 'mj-settings',
|
|
258
|
-
|
|
259
|
-
|
|
481
|
+
args: [{ selector: 'mj-settings', standalone: true, imports: [
|
|
482
|
+
CommonModule,
|
|
483
|
+
SharedSettingsModule,
|
|
484
|
+
SqlLoggingComponent,
|
|
485
|
+
UserManagementComponent,
|
|
486
|
+
RoleManagementComponent,
|
|
487
|
+
ApplicationManagementComponent,
|
|
488
|
+
EntityPermissionsComponent
|
|
489
|
+
], template: "<div class=\"settings-container\">\n <!-- Header Section -->\n <div class=\"settings-header\">\n <div class=\"header-content\">\n <div class=\"header-title\">\n <i class=\"fa-solid fa-cog header-icon\"></i>\n <h1>Settings</h1>\n </div>\n \n <div class=\"header-search\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input \n type=\"text\" \n class=\"search-input\" \n placeholder=\"Search settings...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"searchTerm$.value\"\n />\n </div>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-content\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading settings...</div>\n </div>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Main Content -->\n @if (!isLoading && !error) {\n <div class=\"settings-content\">\n <!-- Desktop Layout -->\n @if (!isMobile) {\n <div class=\"desktop-layout\" style=\"display: flex;\">\n <!-- Side Navigation -->\n <nav class=\"side-navigation\">\n <ul class=\"nav-list\">\n @for (tab of tabs; track tab.id) {\n <li \n class=\"nav-item\"\n [class.active]=\"activeTab === tab.id\"\n (click)=\"onTabChange(tab.id)\"\n >\n <i [class]=\"tab.icon\"></i>\n <span class=\"nav-label\">{{ tab.label }}</span>\n @if (tab.badgeCount && tab.badgeCount > 0) {\n <span class=\"nav-badge\" [class]=\"'badge-' + (tab.badgeColor || 'primary')\">\n {{ tab.badgeCount }}\n </span>\n }\n </li>\n }\n </ul>\n </nav>\n\n <!-- Content Area -->\n <div class=\"content-area\">\n <div class=\"tab-content\">\n @switch (activeTab) {\n @case ('general') {\n <div class=\"general-settings\">\n <h2 class=\"section-title\">General Settings</h2>\n <div class=\"settings-grid\">\n <mj-settings-card \n title=\"Profile Information\"\n icon=\"fa-solid fa-user\"\n [expanded]=\"isSectionExpanded('profile')\"\n (toggle)=\"toggleSection('profile')\"\n >\n <div class=\"card-content\">\n <p>Manage your profile information and preferences.</p>\n <!-- Profile settings content will go here -->\n </div>\n </mj-settings-card>\n\n <mj-settings-card \n title=\"Preferences\"\n icon=\"fa-solid fa-sliders\"\n [expanded]=\"isSectionExpanded('preferences')\"\n (toggle)=\"toggleSection('preferences')\"\n >\n <div class=\"card-content\">\n <p>Customize your experience with display and behavior preferences.</p>\n <!-- Preferences content will go here -->\n </div>\n </mj-settings-card>\n\n <mj-settings-card \n title=\"Notifications\"\n icon=\"fa-solid fa-bell\"\n [expanded]=\"isSectionExpanded('notifications')\"\n (toggle)=\"toggleSection('notifications')\"\n >\n <div class=\"card-content\">\n <p>Configure how and when you receive notifications.</p>\n <!-- Notification settings will go here -->\n </div>\n </mj-settings-card>\n </div>\n </div>\n }\n \n @case ('users') {\n <div class=\"users-settings\">\n <h2 class=\"section-title\">User Management</h2>\n <p class=\"section-description\">Manage user accounts, roles, and permissions</p>\n <mj-user-management></mj-user-management>\n </div>\n }\n \n @case ('roles') {\n <div class=\"roles-settings\">\n <h2 class=\"section-title\">Role Management</h2>\n <p class=\"section-description\">Define and manage security roles.</p>\n <mj-role-management></mj-role-management>\n </div>\n }\n \n @case ('applications') {\n <div class=\"applications-settings\">\n <mj-application-management></mj-application-management>\n </div>\n }\n \n @case ('permissions') {\n <div class=\"permissions-settings\">\n <mj-entity-permissions></mj-entity-permissions>\n </div>\n }\n \n @case ('advanced') {\n <div class=\"advanced-settings\">\n <h2 class=\"section-title\">Advanced Settings</h2>\n <div class=\"beta-warning\">\n <i class=\"fa-solid fa-flask\"></i>\n <span>Beta features - Use with caution</span>\n </div>\n \n <!-- Tab Navigation -->\n <div class=\"advanced-tabs\">\n <button \n class=\"tab-btn\"\n [class.active]=\"advancedActiveTab === 'sql-logging'\"\n (click)=\"setAdvancedTab('sql-logging')\"\n >\n <i class=\"fa-solid fa-database\"></i>\n SQL Logging\n </button>\n <button \n class=\"tab-btn\"\n [class.active]=\"advancedActiveTab === 'performance'\"\n (click)=\"setAdvancedTab('performance')\"\n >\n <i class=\"fa-solid fa-gauge-high\"></i>\n Performance\n </button>\n <button \n class=\"tab-btn\"\n [class.active]=\"advancedActiveTab === 'developer'\"\n (click)=\"setAdvancedTab('developer')\"\n >\n <i class=\"fa-solid fa-code\"></i>\n Developer Tools\n </button>\n </div>\n \n <!-- Tab Content -->\n <div class=\"advanced-tab-content\">\n @switch (advancedActiveTab) {\n @case ('sql-logging') {\n <mj-sql-logging></mj-sql-logging>\n }\n @case ('performance') {\n <div class=\"performance-settings\">\n <h3>Performance Settings</h3>\n <p>Performance monitoring and optimization tools coming soon.</p>\n </div>\n }\n @case ('developer') {\n <div class=\"developer-settings\">\n <h3>Developer Tools</h3>\n <p>Advanced developer options coming soon.</p>\n </div>\n }\n }\n </div>\n </div>\n }\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Mobile Layout -->\n @if (isMobile) {\n <div class=\"mobile-layout\">\n <!-- Mobile Content -->\n <div class=\"mobile-content\">\n @switch (activeTab) {\n @case ('general') {\n <div class=\"general-settings\">\n <h2 class=\"section-title\">General Settings</h2>\n <!-- Same content as desktop but responsive -->\n </div>\n }\n @case ('users') {\n <div class=\"users-settings\">\n <h2 class=\"section-title\">User Management</h2>\n <p class=\"section-description\">Manage user accounts, roles, and permissions</p>\n <mj-user-management></mj-user-management>\n </div>\n }\n <!-- Other cases similar to desktop -->\n }\n </div>\n\n <!-- Mobile Bottom Navigation -->\n <nav class=\"mobile-navigation\">\n <div class=\"nav-tabs\">\n @for (tab of tabs.slice(0, 5); track tab.id) {\n <button \n class=\"nav-tab\"\n [class.active]=\"activeTab === tab.id\"\n (click)=\"onTabChange(tab.id)\"\n >\n <i [class]=\"tab.icon\"></i>\n @if (tab.badgeCount && tab.badgeCount > 0) {\n <span class=\"tab-badge\" [class]=\"'badge-' + (tab.badgeColor || 'primary')\">\n {{ tab.badgeCount }}\n </span>\n }\n <span class=\"tab-label\">{{ tab.label }}</span>\n </button>\n }\n @if (tabs.length > 5) {\n <button class=\"nav-tab more-tab\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n <span class=\"tab-label\">More</span>\n </button>\n }\n </div>\n </nav>\n </div>\n }\n </div>\n }\n</div>", styles: ["@import '../shared/styles/variables';\n@import '../shared/styles/mixins';\n\n.settings-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background-color: #f5f7fa;\n overflow: hidden;\n position: relative;\n}\n\n// Header Section\n.settings-header {\n background-color: #ffffff;\n border-bottom: 1px solid #e5e7eb;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n z-index: 10;\n}\n\n.header-content {\n padding: 1.5rem 2rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 2rem;\n\n @media (max-width: 768px) {\n padding: 1rem;\n flex-direction: column;\n gap: 1rem;\n }\n}\n\n.header-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n\n .header-icon {\n font-size: 1.75rem;\n color: #2196f3;\n }\n\n h1 {\n margin: 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: #1f2937;\n }\n}\n\n.header-search {\n position: relative;\n width: 100%;\n max-width: 400px;\n\n .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n }\n\n .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n background-color: #f9fafb;\n\n &:focus {\n outline: none;\n border-color: #2196f3;\n background-color: #ffffff;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n }\n\n &::placeholder {\n color: #9ca3af;\n }\n }\n}\n\n// Loading State\n.loading-container {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 2rem;\n}\n\n.loading-content {\n text-align: center;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin: 0 auto 1rem;\n\n .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n\n &:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n }\n\n &:nth-child(2) {\n border-color: transparent #4caf50 transparent transparent;\n animation-delay: -0.3s;\n }\n\n &:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n }\n }\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n// Error State\n.error-container {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 2rem;\n}\n\n.error-content {\n text-align: center;\n max-width: 400px;\n\n .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n }\n\n .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n font-size: 1rem;\n }\n\n .retry-button {\n @include button-base;\n background-color: #2196f3;\n color: white;\n padding: 0.75rem 1.5rem;\n font-size: 0.95rem;\n border-radius: 8px;\n transition: all 0.2s;\n\n &:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n }\n\n i {\n margin-right: 0.5rem;\n }\n }\n}\n\n// Main Content\n.settings-content {\n display: flex;\n flex: 1;\n overflow: hidden;\n flex-direction: column;\n width: 100%;\n}\n\n// Desktop Layout\n.desktop-layout {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n// More specific selector to ensure it applies\n.settings-content .desktop-layout {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n// Deep selector for Angular ViewEncapsulation\n:host ::ng-deep .desktop-layout {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n.side-navigation {\n width: 260px;\n background-color: #ffffff;\n border-right: 1px solid #e5e7eb;\n overflow-y: auto;\n flex-shrink: 0;\n}\n\n.nav-list {\n list-style: none;\n margin: 0;\n padding: 1rem 0;\n}\n\n.nav-item {\n position: relative;\n display: flex;\n align-items: center;\n padding: 0.875rem 1.5rem;\n cursor: pointer;\n transition: all 0.2s;\n color: #4b5563;\n font-size: 0.95rem;\n\n &:hover {\n background-color: #f3f4f6;\n color: #1f2937;\n }\n\n &.active {\n background-color: #eff6ff;\n color: #2196f3;\n font-weight: 500;\n\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background-color: #2196f3;\n }\n }\n\n i {\n width: 20px;\n margin-right: 0.75rem;\n font-size: 1.1rem;\n }\n\n .nav-label {\n flex: 1;\n }\n\n .nav-badge {\n padding: 0.125rem 0.5rem;\n border-radius: 12px;\n font-size: 0.75rem;\n font-weight: 600;\n \n &.badge-primary {\n background-color: #dbeafe;\n color: #1e40af;\n }\n\n &.badge-danger {\n background-color: #fee2e2;\n color: #991b1b;\n }\n\n &.badge-warning {\n background-color: #fef3c7;\n color: #92400e;\n }\n\n &.badge-success {\n background-color: #d1fae5;\n color: #065f46;\n }\n }\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 2rem;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 0; // Important for proper flex sizing\n\n @media (max-width: 768px) {\n padding: 1rem;\n }\n}\n\n.tab-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n min-height: 0; // Important for proper flex sizing\n}\n\n// Section Styles\n.section-title {\n font-size: 1.5rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.5rem 0;\n}\n\n.section-description {\n color: #6b7280;\n margin: 0 0 2rem 0;\n font-size: 0.95rem;\n}\n\n.settings-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));\n gap: 1.5rem;\n margin-top: 1.5rem;\n\n @media (max-width: 768px) {\n grid-template-columns: 1fr;\n gap: 1rem;\n }\n}\n\n.card-content {\n padding: 1rem;\n color: #4b5563;\n font-size: 0.95rem;\n\n p {\n margin: 0 0 1rem 0;\n line-height: 1.6;\n }\n}\n\n// Beta Warning\n.beta-warning {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n background-color: #fef3c7;\n color: #92400e;\n border-radius: 6px;\n font-size: 0.875rem;\n margin-bottom: 1.5rem;\n\n i {\n font-size: 1rem;\n }\n}\n\n// Mobile Layout\n.mobile-layout {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.mobile-content {\n flex: 1;\n overflow-y: auto;\n padding: 1rem;\n padding-bottom: 80px; // Space for bottom nav\n}\n\n.mobile-navigation {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background-color: #ffffff;\n border-top: 1px solid #e5e7eb;\n box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);\n z-index: 100;\n}\n\n.nav-tabs {\n display: flex;\n justify-content: space-around;\n align-items: center;\n padding: 0.5rem 0;\n}\n\n.nav-tab {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.25rem;\n padding: 0.5rem;\n background: none;\n border: none;\n color: #9ca3af;\n cursor: pointer;\n transition: all 0.2s;\n font-size: 0.75rem;\n min-width: 60px;\n\n &.active {\n color: #2196f3;\n\n i {\n transform: scale(1.1);\n }\n }\n\n &:active {\n transform: scale(0.95);\n }\n\n i {\n font-size: 1.25rem;\n transition: transform 0.2s;\n }\n\n .tab-badge {\n position: absolute;\n top: 0.25rem;\n right: 0.25rem;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 8px;\n font-size: 0.625rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n \n &.badge-primary {\n background-color: #2196f3;\n color: white;\n }\n\n &.badge-warning {\n background-color: #ff9800;\n color: white;\n }\n }\n\n .tab-label {\n margin-top: 0.125rem;\n }\n}\n\n.more-tab {\n color: #6b7280;\n}\n\n// Advanced Settings Tabs\n.advanced-tabs {\n display: flex;\n gap: 0.5rem;\n border-bottom: 2px solid #e5e7eb;\n margin-bottom: 2rem;\n margin-top: 1.5rem;\n\n .tab-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n color: #6b7280;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n position: relative;\n\n &:hover {\n color: #374151;\n background: #f9fafb;\n }\n\n &.active {\n color: #2196f3;\n border-bottom-color: #2196f3;\n background: #eff6ff;\n\n i {\n color: #2196f3;\n }\n }\n\n i {\n font-size: 1.125rem;\n }\n }\n}\n\n.advanced-tab-content {\n @include scrollable-content;\n background: white;\n border-radius: 12px;\n padding: 0;\n min-height: 500px;\n max-height: calc(100vh - 350px);\n}\n\n.performance-settings,\n.developer-settings {\n padding: 2rem;\n \n h3 {\n margin: 0 0 1rem 0;\n color: #1f2937;\n font-size: 1.25rem;\n }\n \n p {\n color: #6b7280;\n font-size: 0.95rem;\n }\n}\n\n// Animations\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.general-settings,\n.users-settings,\n.roles-settings,\n.applications-settings,\n.permissions-settings,\n.advanced-settings {\n animation: fadeIn 0.3s ease-out;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0; // Important for proper flex sizing\n overflow: hidden;\n \n // Direct child components should handle their own scrolling\n > * {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n }\n}"] }]
|
|
490
|
+
}], () => [], { stateChange: [{
|
|
491
|
+
type: Output
|
|
492
|
+
}] }); })();
|
|
493
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsComponent, { className: "SettingsComponent", filePath: "src/lib/settings/settings.component.ts", lineNumber: 45 }); })();
|
|
260
494
|
//# sourceMappingURL=settings.component.js.map
|