@memberjunction/ng-explorer-settings 2.120.0 → 2.122.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/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.js +5 -7
- package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
- package/dist/lib/application-management/application-management.component.d.ts +6 -4
- package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-management.component.js +28 -21
- package/dist/lib/application-management/application-management.component.js.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts +6 -4
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.js +27 -20
- package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +5 -7
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
- package/dist/lib/module.d.ts +33 -19
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/module.js +97 -17
- package/dist/lib/module.js.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.js +5 -7
- package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
- package/dist/lib/role-management/role-management.component.d.ts +6 -4
- package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-management.component.js +28 -24
- package/dist/lib/role-management/role-management.component.js.map +1 -1
- package/dist/lib/settings/settings.component.d.ts +2 -2
- package/dist/lib/settings/settings.component.d.ts.map +1 -1
- package/dist/lib/settings/settings.component.js +11 -28
- package/dist/lib/settings/settings.component.js.map +1 -1
- package/dist/lib/shared/components/settings-card/settings-card.component.js +2 -2
- package/dist/lib/sql-logging/sql-logging.component.d.ts +36 -16
- package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.js +26 -29
- package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
- package/dist/lib/user-app-config/user-app-config.component.d.ts +102 -0
- package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -0
- package/dist/lib/user-app-config/user-app-config.component.js +552 -0
- package/dist/lib/user-app-config/user-app-config.component.js.map +1 -0
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.js +5 -7
- package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
- package/dist/lib/user-management/user-management.component.d.ts +6 -4
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-management.component.js +29 -24
- package/dist/lib/user-management/user-management.component.js.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.js +4 -6
- package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
- package/dist/public-api.d.ts +23 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +52 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +14 -14
|
@@ -6,7 +6,7 @@ export interface SettingsTab {
|
|
|
6
6
|
id: string;
|
|
7
7
|
label: string;
|
|
8
8
|
icon: string;
|
|
9
|
-
component?:
|
|
9
|
+
component?: unknown;
|
|
10
10
|
badgeCount?: number;
|
|
11
11
|
badgeColor?: 'primary' | 'danger' | 'warning' | 'success';
|
|
12
12
|
}
|
|
@@ -44,6 +44,6 @@ export declare class SettingsComponent extends BaseNavigationComponent implement
|
|
|
44
44
|
getTabIcon(tab: SettingsTab): string;
|
|
45
45
|
getTabClass(tab: SettingsTab): string;
|
|
46
46
|
static ɵfac: i0.ɵɵFactoryDeclaration<SettingsComponent, never>;
|
|
47
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SettingsComponent, "mj-settings", never, {}, { "stateChange": "stateChange"; }, never, never,
|
|
47
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SettingsComponent, "mj-settings", never, {}, { "stateChange": "stateChange"; }, never, never, false, never>;
|
|
48
48
|
}
|
|
49
49
|
//# sourceMappingURL=settings.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.component.d.ts","sourceRoot":"","sources":["../../../src/lib/settings/settings.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,YAAY,EAAU,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.component.d.ts","sourceRoot":"","sources":["../../../src/lib/settings/settings.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,YAAY,EAAU,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAW,eAAe,EAAE,MAAM,MAAM,CAAC;AAEhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;;AAEpE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;CAC3D;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,qBAMa,iBAAkB,SAAQ,uBAAwB,YAAW,MAAM,EAAE,SAAS;IAC/E,WAAW,uCAA8C;IAG5D,SAAS,SAAa;IACtB,iBAAiB,SAAiB;IAClC,WAAW,0BAAmC;IAC9C,SAAS,UAAS;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG5B,IAAI,EAAE,WAAW,EAAE,CAsCxB;IAGK,gBAAgB,EAAE,MAAM,EAAE,CAA8B;IAGxD,QAAQ,UAA2B;IAE1C,OAAO,CAAC,QAAQ,CAAuB;;IAQvC,QAAQ,IAAI,IAAI;IAKhB,WAAW,IAAI,IAAI;IAMnB,OAAO,CAAC,iBAAiB;IAaZ,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;YAY/B,gBAAgB;IAIvB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhC,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKlC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAUtC,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI7C,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1C,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,eAAe;IAShB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI;IAY3D,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM;IAIpC,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM;yCAvKjC,iBAAiB;2CAAjB,iBAAiB;CAiL7B"}
|
|
@@ -6,19 +6,17 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { Component, EventEmitter, Output } from '@angular/core';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
-
import { CommonModule } from '@angular/common';
|
|
10
9
|
import { Subject, BehaviorSubject } from 'rxjs';
|
|
11
10
|
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';
|
|
18
|
-
import { UserProfileSettingsComponent } from '../user-profile-settings/user-profile-settings.component';
|
|
19
11
|
import { BaseNavigationComponent } from '@memberjunction/ng-shared';
|
|
20
12
|
import * as i0 from "@angular/core";
|
|
21
13
|
import * as i1 from "../shared/settings-card.component";
|
|
14
|
+
import * as i2 from "../sql-logging/sql-logging.component";
|
|
15
|
+
import * as i3 from "../user-management/user-management.component";
|
|
16
|
+
import * as i4 from "../role-management/role-management.component";
|
|
17
|
+
import * as i5 from "../application-management/application-management.component";
|
|
18
|
+
import * as i6 from "../entity-permissions/entity-permissions.component";
|
|
19
|
+
import * as i7 from "../user-profile-settings/user-profile-settings.component";
|
|
22
20
|
const _forTrack0 = ($index, $item) => $item.id;
|
|
23
21
|
function SettingsComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
24
22
|
i0.ɵɵelementStart(0, "div", 8)(1, "div", 11)(2, "div", 12);
|
|
@@ -444,7 +442,7 @@ let SettingsComponent = class SettingsComponent extends BaseNavigationComponent
|
|
|
444
442
|
return classes.join(' ');
|
|
445
443
|
}
|
|
446
444
|
static ɵfac = function SettingsComponent_Factory(t) { return new (t || SettingsComponent)(); };
|
|
447
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SettingsComponent, selectors: [["mj-settings"]], outputs: { stateChange: "stateChange" },
|
|
445
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SettingsComponent, selectors: [["mj-settings"]], outputs: { stateChange: "stateChange" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 13, vars: 4, consts: [[1, "mj-page-container"], [1, "mj-header"], [1, "mj-header-title"], [1, "fa-solid", "fa-cog"], [1, "mj-header-actions"], [1, "mj-search"], [1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search settings...", 1, "mj-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, "mj-grid", "mj-grid-responsive"], ["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) {
|
|
448
446
|
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
|
|
449
447
|
i0.ɵɵelement(3, "i", 3);
|
|
450
448
|
i0.ɵɵelementStart(4, "h1");
|
|
@@ -466,32 +464,17 @@ let SettingsComponent = class SettingsComponent extends BaseNavigationComponent
|
|
|
466
464
|
i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 11 : -1);
|
|
467
465
|
i0.ɵɵadvance();
|
|
468
466
|
i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 12 : -1);
|
|
469
|
-
} }, dependencies: [CommonModule,
|
|
470
|
-
SharedSettingsModule, i1.SettingsCardComponent, SqlLoggingComponent,
|
|
471
|
-
UserManagementComponent,
|
|
472
|
-
RoleManagementComponent,
|
|
473
|
-
ApplicationManagementComponent,
|
|
474
|
-
EntityPermissionsComponent,
|
|
475
|
-
UserProfileSettingsComponent], 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}"] });
|
|
467
|
+
} }, dependencies: [i1.SettingsCardComponent, i2.SqlLoggingComponent, i3.UserManagementComponent, i4.RoleManagementComponent, i5.ApplicationManagementComponent, i6.EntityPermissionsComponent, i7.UserProfileSettingsComponent], styles: ["@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\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.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 .header-content[_ngcontent-%COMP%] {\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-title[_ngcontent-%COMP%] .header-icon[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n color: #2196f3;\n}\n.header-title[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-search[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n max-width: 400px;\n}\n.header-search[_ngcontent-%COMP%] .search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.header-search[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%] {\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.header-search[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%]: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.header-search[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%]::placeholder {\n color: #9ca3af;\n}\n\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.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%] {\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.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(2) {\n border-color: transparent #4caf50 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\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-content[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-content[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n color: #374151;\n margin-bottom: 1.5rem;\n font-size: 1rem;\n}\n.error-content[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\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.error-content[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-content[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.error-content[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%]:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.error-content[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 0.5rem;\n}\n\n.settings-content[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n flex-direction: column;\n width: 100%;\n}\n\n.desktop-layout[_ngcontent-%COMP%] {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n.settings-content[_ngcontent-%COMP%] .desktop-layout[_ngcontent-%COMP%] {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\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.nav-item[_ngcontent-%COMP%]:hover {\n background-color: #f3f4f6;\n color: #1f2937;\n}\n.nav-item.active[_ngcontent-%COMP%] {\n background-color: #eff6ff;\n color: #2196f3;\n font-weight: 500;\n}\n.nav-item.active[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background-color: #2196f3;\n}\n.nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 20px;\n margin-right: 0.75rem;\n font-size: 1.1rem;\n}\n.nav-item[_ngcontent-%COMP%] .nav-label[_ngcontent-%COMP%] {\n flex: 1;\n}\n.nav-item[_ngcontent-%COMP%] .nav-badge[_ngcontent-%COMP%] {\n padding: 0.125rem 0.5rem;\n border-radius: 12px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n.nav-item[_ngcontent-%COMP%] .nav-badge.badge-primary[_ngcontent-%COMP%] {\n background-color: #dbeafe;\n color: #1e40af;\n}\n.nav-item[_ngcontent-%COMP%] .nav-badge.badge-danger[_ngcontent-%COMP%] {\n background-color: #fee2e2;\n color: #991b1b;\n}\n.nav-item[_ngcontent-%COMP%] .nav-badge.badge-warning[_ngcontent-%COMP%] {\n background-color: #fef3c7;\n color: #92400e;\n}\n.nav-item[_ngcontent-%COMP%] .nav-badge.badge-success[_ngcontent-%COMP%] {\n background-color: #d1fae5;\n color: #065f46;\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;\n}\n@media (max-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\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;\n}\n\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 .settings-grid[_ngcontent-%COMP%] {\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.card-content[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n line-height: 1.6;\n}\n\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.beta-warning[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\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;\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.nav-tab.active[_ngcontent-%COMP%] {\n color: #2196f3;\n}\n.nav-tab.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n.nav-tab[_ngcontent-%COMP%]:active {\n transform: scale(0.95);\n}\n.nav-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n transition: transform 0.2s;\n}\n.nav-tab[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\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.nav-tab[_ngcontent-%COMP%] .tab-badge.badge-primary[_ngcontent-%COMP%] {\n background-color: #2196f3;\n color: white;\n}\n.nav-tab[_ngcontent-%COMP%] .tab-badge.badge-warning[_ngcontent-%COMP%] {\n background-color: #ff9800;\n color: white;\n}\n.nav-tab[_ngcontent-%COMP%] .tab-label[_ngcontent-%COMP%] {\n margin-top: 0.125rem;\n}\n\n.more-tab[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n\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.advanced-tabs[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\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.advanced-tabs[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%]:hover {\n color: #374151;\n background: #f9fafb;\n}\n.advanced-tabs[_ngcontent-%COMP%] .tab-btn.active[_ngcontent-%COMP%] {\n color: #2196f3;\n border-bottom-color: #2196f3;\n background: #eff6ff;\n}\n.advanced-tabs[_ngcontent-%COMP%] .tab-btn.active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #2196f3;\n}\n.advanced-tabs[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n}\n\n.advanced-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\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.performance-settings[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], \n.developer-settings[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n color: #1f2937;\n font-size: 1.25rem;\n}\n.performance-settings[_ngcontent-%COMP%] p[_ngcontent-%COMP%], \n.developer-settings[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\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: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n.general-settings[_ngcontent-%COMP%] > *[_ngcontent-%COMP%], \n.users-settings[_ngcontent-%COMP%] > *[_ngcontent-%COMP%], \n.roles-settings[_ngcontent-%COMP%] > *[_ngcontent-%COMP%], \n.applications-settings[_ngcontent-%COMP%] > *[_ngcontent-%COMP%], \n.permissions-settings[_ngcontent-%COMP%] > *[_ngcontent-%COMP%], \n.advanced-settings[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}"] });
|
|
476
468
|
};
|
|
477
469
|
SettingsComponent = __decorate([
|
|
478
|
-
RegisterClass(BaseNavigationComponent,
|
|
470
|
+
RegisterClass(BaseNavigationComponent, 'Settings')
|
|
479
471
|
], SettingsComponent);
|
|
480
472
|
export { SettingsComponent };
|
|
481
473
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SettingsComponent, [{
|
|
482
474
|
type: Component,
|
|
483
|
-
args: [{ selector: 'mj-settings', standalone: true, imports: [
|
|
484
|
-
CommonModule,
|
|
485
|
-
SharedSettingsModule,
|
|
486
|
-
SqlLoggingComponent,
|
|
487
|
-
UserManagementComponent,
|
|
488
|
-
RoleManagementComponent,
|
|
489
|
-
ApplicationManagementComponent,
|
|
490
|
-
EntityPermissionsComponent,
|
|
491
|
-
UserProfileSettingsComponent
|
|
492
|
-
], template: "<div class=\"mj-page-container\">\n <!-- Header Section -->\n <div class=\"mj-header\">\n <div class=\"mj-header-title\">\n <i class=\"fa-solid fa-cog\"></i>\n <h1>Settings</h1>\n </div>\n \n <div class=\"mj-header-actions\">\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\"></i>\n <input \n type=\"text\" \n class=\"mj-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=\"mj-grid mj-grid-responsive\">\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 <mj-user-profile-settings></mj-user-profile-settings>\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}"] }]
|
|
475
|
+
args: [{ selector: 'mj-settings', template: "<div class=\"mj-page-container\">\n <!-- Header Section -->\n <div class=\"mj-header\">\n <div class=\"mj-header-title\">\n <i class=\"fa-solid fa-cog\"></i>\n <h1>Settings</h1>\n </div>\n \n <div class=\"mj-header-actions\">\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\"></i>\n <input \n type=\"text\" \n class=\"mj-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=\"mj-grid mj-grid-responsive\">\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 <mj-user-profile-settings></mj-user-profile-settings>\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: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\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.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 .header-content {\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-title .header-icon {\n font-size: 1.75rem;\n color: #2196f3;\n}\n.header-title h1 {\n margin: 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: #1f2937;\n}\n\n.header-search {\n position: relative;\n width: 100%;\n max-width: 400px;\n}\n.header-search .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.header-search .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.header-search .search-input: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.header-search .search-input::placeholder {\n color: #9ca3af;\n}\n\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.loading-spinner .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.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #4caf50 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\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-content .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-content .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n font-size: 1rem;\n}\n.error-content .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\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.error-content .retry-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-content .retry-button i {\n font-size: 0.875rem;\n}\n.error-content .retry-button:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.error-content .retry-button i {\n margin-right: 0.5rem;\n}\n\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 display: flex !important;\n height: 100%;\n width: 100%;\n}\n\n.settings-content .desktop-layout {\n display: flex !important;\n height: 100%;\n width: 100%;\n}\n\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.nav-item:hover {\n background-color: #f3f4f6;\n color: #1f2937;\n}\n.nav-item.active {\n background-color: #eff6ff;\n color: #2196f3;\n font-weight: 500;\n}\n.nav-item.active::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background-color: #2196f3;\n}\n.nav-item i {\n width: 20px;\n margin-right: 0.75rem;\n font-size: 1.1rem;\n}\n.nav-item .nav-label {\n flex: 1;\n}\n.nav-item .nav-badge {\n padding: 0.125rem 0.5rem;\n border-radius: 12px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n.nav-item .nav-badge.badge-primary {\n background-color: #dbeafe;\n color: #1e40af;\n}\n.nav-item .nav-badge.badge-danger {\n background-color: #fee2e2;\n color: #991b1b;\n}\n.nav-item .nav-badge.badge-warning {\n background-color: #fef3c7;\n color: #92400e;\n}\n.nav-item .nav-badge.badge-success {\n background-color: #d1fae5;\n color: #065f46;\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;\n}\n@media (max-width: 768px) {\n .content-area {\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;\n}\n\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 .settings-grid {\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.card-content p {\n margin: 0 0 1rem 0;\n line-height: 1.6;\n}\n\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.beta-warning i {\n font-size: 1rem;\n}\n\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;\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.nav-tab.active {\n color: #2196f3;\n}\n.nav-tab.active i {\n transform: scale(1.1);\n}\n.nav-tab:active {\n transform: scale(0.95);\n}\n.nav-tab i {\n font-size: 1.25rem;\n transition: transform 0.2s;\n}\n.nav-tab .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.nav-tab .tab-badge.badge-primary {\n background-color: #2196f3;\n color: white;\n}\n.nav-tab .tab-badge.badge-warning {\n background-color: #ff9800;\n color: white;\n}\n.nav-tab .tab-label {\n margin-top: 0.125rem;\n}\n\n.more-tab {\n color: #6b7280;\n}\n\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.advanced-tabs .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.advanced-tabs .tab-btn:hover {\n color: #374151;\n background: #f9fafb;\n}\n.advanced-tabs .tab-btn.active {\n color: #2196f3;\n border-bottom-color: #2196f3;\n background: #eff6ff;\n}\n.advanced-tabs .tab-btn.active i {\n color: #2196f3;\n}\n.advanced-tabs .tab-btn i {\n font-size: 1.125rem;\n}\n\n.advanced-tab-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\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.performance-settings h3,\n.developer-settings h3 {\n margin: 0 0 1rem 0;\n color: #1f2937;\n font-size: 1.25rem;\n}\n.performance-settings p,\n.developer-settings p {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\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.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;\n overflow: hidden;\n}\n.general-settings > *,\n.users-settings > *,\n.roles-settings > *,\n.applications-settings > *,\n.permissions-settings > *,\n.advanced-settings > * {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n"] }]
|
|
493
476
|
}], () => [], { stateChange: [{
|
|
494
477
|
type: Output
|
|
495
478
|
}] }); })();
|
|
496
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsComponent, { className: "SettingsComponent", filePath: "src/lib/settings/settings.component.ts", lineNumber:
|
|
479
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsComponent, { className: "SettingsComponent", filePath: "src/lib/settings/settings.component.ts", lineNumber: 28 }); })();
|
|
497
480
|
//# sourceMappingURL=settings.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.component.js","sourceRoot":"","sources":["../../../src/lib/settings/settings.component.ts","../../../src/lib/settings/settings.component.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAqB,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"settings.component.js","sourceRoot":"","sources":["../../../src/lib/settings/settings.component.ts","../../../src/lib/settings/settings.component.html"],"names":[],"mappings":"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"}
|
|
@@ -109,7 +109,7 @@ export class SettingsCardComponent {
|
|
|
109
109
|
i0.ɵɵclassProp("no-padding", ctx.noPadding);
|
|
110
110
|
i0.ɵɵadvance(2);
|
|
111
111
|
i0.ɵɵconditional(ctx.footerTemplate ? 4 : -1);
|
|
112
|
-
} }, dependencies: [CommonModule, i1.NgTemplateOutlet], styles: ["//[_ngcontent-%COMP%] =====================================================\n//[_ngcontent-%COMP%] Settings[_ngcontent-%COMP%] Card[_ngcontent-%COMP%] Component[_ngcontent-%COMP%] -[_ngcontent-%COMP%] Reusable[_ngcontent-%COMP%] card[_ngcontent-%COMP%] layout\n//[_ngcontent-%COMP%] =====================================================\n\n@import[_ngcontent-%COMP%] '../../styles/shared-settings'[_ngcontent-%COMP%];\n\n[_nghost-%COMP%] {\n display: block;\n width: 100%;\n}\n\n.settings-card[_ngcontent-%COMP%] {\n @include card-elevated;\n display: flex;\n flex-direction: column;\n height: 100%;\n \n &.settings-card-floating {\n @include card-floating;\n }\n \n &.settings-card-sm {\n @include card-content-sm;\n }\n \n &.settings-card-lg {\n @include card-content-lg;\n }\n}\n\n.card-header[_ngcontent-%COMP%] {\n @include section-header;\n flex-shrink: 0;\n padding: $space-lg $space-lg $space-md $space-lg;\n margin: 0;\n \n .header-content {\n flex: 1;\n \n .card-title {\n margin: 0;\n font-size: $font-size-lg;\n font-weight: $font-weight-semibold;\n color: $text-primary;\n line-height: $line-height-tight;\n }\n \n .card-subtitle {\n margin: $space-xs 0 0 0;\n font-size: $font-size-sm;\n color: $text-secondary;\n line-height: $line-height-normal;\n }\n }\n \n .header-actions {\n flex-shrink: 0;\n display: flex;\n gap: $space-sm;\n align-items: flex-start;\n }\n}\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n padding: 0 $space-lg $space-lg $space-lg;\n \n &.no-padding {\n padding: 0;\n }\n}\n\n.card-footer[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: $space-md $space-lg $space-lg $space-lg;\n border-top: 1px solid $border-light;\n background: $background-light;\n border-radius: 0 0 $radius-lg $radius-lg;\n}\n\n//[_ngcontent-%COMP%] Size[_ngcontent-%COMP%] variants\n.settings-card-sm[_ngcontent-%COMP%] {\n .card-header {\n padding: $space-md $space-md $space-sm $space-md;\n \n .card-title {\n font-size: $font-size-md;\n }\n \n .card-subtitle {\n font-size: $font-size-xs;\n }\n }\n \n .card-content {\n padding: 0 $space-md $space-md $space-md;\n \n &.no-padding {\n padding: 0;\n }\n }\n \n .card-footer {\n padding: $space-sm $space-md $space-md $space-md;\n }\n}\n\n.settings-card-lg[_ngcontent-%COMP%] {\n .card-header {\n padding: $space-xl $space-xl $space-lg $space-xl;\n \n .card-title {\n font-size: $font-size-xl;\n }\n }\n \n .card-content {\n padding: 0 $space-xl $space-xl $space-xl;\n \n &.no-padding {\n padding: 0;\n }\n }\n \n .card-footer {\n padding: $space-lg $space-xl $space-xl $space-xl;\n }\n}"] });
|
|
112
|
+
} }, dependencies: [CommonModule, i1.NgTemplateOutlet], styles: ["@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n[_nghost-%COMP%] {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n color: #212121;\n}\n[_nghost-%COMP%] *[_ngcontent-%COMP%] {\n box-sizing: border-box;\n}\n\n.settings-card[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 20px;\n}\n.settings-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-floating[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n padding: 20px;\n}\n.settings-card-floating[_ngcontent-%COMP%]:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n\n.settings-card-sm[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 16px;\n}\n.settings-card-sm[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-lg[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 24px;\n}\n.settings-card-lg[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.dashboard-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 24px 0 16px 0;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 16px;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], .dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-weight: 600;\n color: #212121;\n font-size: 24px;\n line-height: 1.2;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n.dashboard-header[_ngcontent-%COMP%] .header-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n}\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .section-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.section-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.control-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #ffffff;\n color: #212121;\n border-color: #bdbdbd;\n}\n.control-btn[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8f9fa;\n border-color: #2196f3;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-primary[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn.control-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.control-btn.control-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.control-btn.control-btn-sm[_ngcontent-%COMP%] {\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n}\n.control-btn.control-btn-sm[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.control-btn.control-btn-lg[_ngcontent-%COMP%] {\n height: 44px;\n padding: 0 24px;\n font-size: 14px;\n}\n.control-btn.control-btn-lg[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.action-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n.action-btn.action-btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%]:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.info-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(158, 158, 158, 0.1);\n color: #666666;\n border: 1px solid rgba(158, 158, 158, 0.2);\n}\n.status-badge.status-active[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(76, 175, 80, 0.1);\n color: #3d8b40;\n border: 1px solid rgba(76, 175, 80, 0.2);\n}\n.status-badge.status-migration[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n.status-badge.status-warning[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(255, 193, 7, 0.1);\n color: #6d5200;\n border: 1px solid rgba(255, 193, 7, 0.2);\n}\n.status-badge.status-error[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(244, 67, 54, 0.1);\n color: #ea1c0d;\n border: 1px solid rgba(244, 67, 54, 0.2);\n}\n\n.settings-nav[_ngcontent-%COMP%] {\n width: 220px;\n min-width: 220px;\n max-width: 220px;\n background: #ffffff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n margin: 0 8px 4px 8px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 400;\n color: #666666;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n position: relative;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n width: 3px;\n height: 0;\n background: #2196f3;\n border-radius: 0 2px 2px 0;\n transition: height all 0.15s ease;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%]:hover {\n background: #f8f9fa;\n color: #2196f3;\n transform: translateX(2px);\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item.active[_ngcontent-%COMP%] {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n font-weight: 500;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item.active[_ngcontent-%COMP%]::before {\n height: 24px;\n}\n.settings-nav[_ngcontent-%COMP%] .nav-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 18px;\n text-align: center;\n}\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n.form-field[_ngcontent-%COMP%] .field-label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 4px;\n font-size: 12px;\n font-weight: 500;\n color: #212121;\n}\n.form-field[_ngcontent-%COMP%] .field-hint[_ngcontent-%COMP%] {\n margin-top: 4px;\n font-size: 11px;\n color: #9e9e9e;\n}\n.form-field[_ngcontent-%COMP%] .field-error[_ngcontent-%COMP%] {\n margin-top: 4px;\n font-size: 11px;\n color: #f44336;\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%], .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n width: 100%;\n height: 36px;\n padding: 0 8px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n background: #ffffff;\n color: #212121;\n transition: all 0.15s ease;\n outline: none;\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder, .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]::placeholder, .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%]::placeholder {\n color: #9e9e9e;\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:focus, .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:focus, .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:focus {\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);\n}\n.form-field[_ngcontent-%COMP%] input[_ngcontent-%COMP%]:disabled, .form-field[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]:disabled, .form-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%]:disabled {\n background: #f8f9fa;\n color: #bdbdbd;\n cursor: not-allowed;\n}\n\n.form-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n}\n.form-row[_ngcontent-%COMP%] .form-field[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.checkbox-field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 16px;\n}\n.checkbox-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #212121;\n cursor: pointer;\n margin: 0;\n}\n\n.status-bar[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n padding: 16px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-label[_ngcontent-%COMP%] {\n color: #666666;\n font-weight: 500;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value[_ngcontent-%COMP%] {\n color: #212121;\n font-weight: 600;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value.text-success[_ngcontent-%COMP%] {\n color: #4caf50;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value.text-warning[_ngcontent-%COMP%] {\n color: #ffc107;\n}\n.status-bar[_ngcontent-%COMP%] .status-item[_ngcontent-%COMP%] .status-value.text-danger[_ngcontent-%COMP%] {\n color: #f44336;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n text-align: center;\n color: #666666;\n}\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n color: #9e9e9e;\n margin-bottom: 8px;\n}\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #212121;\n}\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n line-height: 1.6;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n}\n.loading-container[_ngcontent-%COMP%] .loading-spinner[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border: 3px solid #e0e0e0;\n border-top-color: #2196f3;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n.loading-container[_ngcontent-%COMP%] .loading-text[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #666666;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n to {\n transform: rotate(360deg);\n }\n}\n.text-success[_ngcontent-%COMP%] {\n color: #4caf50 !important;\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: #ffc107 !important;\n}\n\n.text-danger[_ngcontent-%COMP%] {\n color: #f44336 !important;\n}\n\n.text-info[_ngcontent-%COMP%] {\n color: #00bcd4 !important;\n}\n\n.text-muted[_ngcontent-%COMP%] {\n color: #9e9e9e !important;\n}\n\n.text-primary[_ngcontent-%COMP%] {\n color: #212121 !important;\n}\n\n.text-secondary[_ngcontent-%COMP%] {\n color: #666666 !important;\n}\n\n.mb-0[_ngcontent-%COMP%] {\n margin-bottom: 0 !important;\n}\n\n.mb-1[_ngcontent-%COMP%] {\n margin-bottom: 4px !important;\n}\n\n.mb-2[_ngcontent-%COMP%] {\n margin-bottom: 8px !important;\n}\n\n.mb-3[_ngcontent-%COMP%] {\n margin-bottom: 16px !important;\n}\n\n.mb-4[_ngcontent-%COMP%] {\n margin-bottom: 24px !important;\n}\n\n.mb-5[_ngcontent-%COMP%] {\n margin-bottom: 32px !important;\n}\n\n.mt-0[_ngcontent-%COMP%] {\n margin-top: 0 !important;\n}\n\n.mt-1[_ngcontent-%COMP%] {\n margin-top: 4px !important;\n}\n\n.mt-2[_ngcontent-%COMP%] {\n margin-top: 8px !important;\n}\n\n.mt-3[_ngcontent-%COMP%] {\n margin-top: 16px !important;\n}\n\n.mt-4[_ngcontent-%COMP%] {\n margin-top: 24px !important;\n}\n\n.mt-5[_ngcontent-%COMP%] {\n margin-top: 32px !important;\n}\n\n.d-flex[_ngcontent-%COMP%] {\n display: flex !important;\n}\n\n.d-block[_ngcontent-%COMP%] {\n display: block !important;\n}\n\n.d-inline-block[_ngcontent-%COMP%] {\n display: inline-block !important;\n}\n\n.d-none[_ngcontent-%COMP%] {\n display: none !important;\n}\n\n.flex-1[_ngcontent-%COMP%] {\n flex: 1 !important;\n}\n\n.flex-column[_ngcontent-%COMP%] {\n flex-direction: column !important;\n}\n\n.flex-row[_ngcontent-%COMP%] {\n flex-direction: row !important;\n}\n\n.align-center[_ngcontent-%COMP%] {\n align-items: center !important;\n}\n\n.justify-center[_ngcontent-%COMP%] {\n justify-content: center !important;\n}\n\n.justify-between[_ngcontent-%COMP%] {\n justify-content: space-between !important;\n}\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card[_ngcontent-%COMP%] {\n margin-right: 10px;\n}\n\n.role-card[_ngcontent-%COMP%] {\n margin-bottom: 5px;\n}\n\n@media (max-width: 768px) {\n .settings-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n .dashboard-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n .dashboard-header[_ngcontent-%COMP%] .header-controls[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: flex-start;\n }\n .form-row[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n}\n[_nghost-%COMP%] {\n display: block;\n width: 100%;\n}\n\n.settings-card[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n.settings-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n.settings-card.settings-card-floating[_ngcontent-%COMP%] {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n.settings-card.settings-card-floating[_ngcontent-%COMP%]:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n.settings-card.settings-card-sm[_ngcontent-%COMP%] {\n padding: 16px;\n}\n.settings-card.settings-card-lg[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n padding: 24px 24px 16px 24px;\n margin: 0;\n}\n.card-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .card-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.card-header[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.card-header[_ngcontent-%COMP%] .header-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n.card-header[_ngcontent-%COMP%] .header-content[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212121;\n line-height: 1.2;\n}\n.card-header[_ngcontent-%COMP%] .header-content[_ngcontent-%COMP%] .card-subtitle[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: #666666;\n line-height: 1.4;\n}\n.card-header[_ngcontent-%COMP%] .header-actions[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 8px;\n align-items: flex-start;\n}\n\n.card-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n padding: 0 24px 24px 24px;\n}\n.card-content.no-padding[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.card-footer[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 16px 24px 24px 24px;\n border-top: 1px solid #e0e0e0;\n background: #f8f9fa;\n border-radius: 0 0 8px 8px;\n}\n\n.settings-card-sm[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] {\n padding: 16px 16px 8px 16px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] .card-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-content[_ngcontent-%COMP%] {\n padding: 0 16px 16px 16px;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-content.no-padding[_ngcontent-%COMP%] {\n padding: 0;\n}\n.settings-card-sm[_ngcontent-%COMP%] .card-footer[_ngcontent-%COMP%] {\n padding: 8px 16px 16px 16px;\n}\n\n.settings-card-lg[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] {\n padding: 32px 32px 24px 32px;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-header[_ngcontent-%COMP%] .card-title[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-content[_ngcontent-%COMP%] {\n padding: 0 32px 32px 32px;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-content.no-padding[_ngcontent-%COMP%] {\n padding: 0;\n}\n.settings-card-lg[_ngcontent-%COMP%] .card-footer[_ngcontent-%COMP%] {\n padding: 24px 32px 32px 32px;\n}"] });
|
|
113
113
|
}
|
|
114
114
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SettingsCardComponent, [{
|
|
115
115
|
type: Component,
|
|
@@ -148,7 +148,7 @@ export class SettingsCardComponent {
|
|
|
148
148
|
</div>
|
|
149
149
|
}
|
|
150
150
|
</div>
|
|
151
|
-
`, styles: ["// =====================================================\n// Settings Card Component - Reusable card layout\n// =====================================================\n\n@import '../../styles/shared-settings';\n\n:host {\n display: block;\n width: 100%;\n}\n\n.settings-card {\n @include card-elevated;\n display: flex;\n flex-direction: column;\n height: 100%;\n \n &.settings-card-floating {\n @include card-floating;\n }\n \n &.settings-card-sm {\n @include card-content-sm;\n }\n \n &.settings-card-lg {\n @include card-content-lg;\n }\n}\n\n.card-header {\n @include section-header;\n flex-shrink: 0;\n padding: $space-lg $space-lg $space-md $space-lg;\n margin: 0;\n \n .header-content {\n flex: 1;\n \n .card-title {\n margin: 0;\n font-size: $font-size-lg;\n font-weight: $font-weight-semibold;\n color: $text-primary;\n line-height: $line-height-tight;\n }\n \n .card-subtitle {\n margin: $space-xs 0 0 0;\n font-size: $font-size-sm;\n color: $text-secondary;\n line-height: $line-height-normal;\n }\n }\n \n .header-actions {\n flex-shrink: 0;\n display: flex;\n gap: $space-sm;\n align-items: flex-start;\n }\n}\n\n.card-content {\n flex: 1;\n min-height: 0;\n padding: 0 $space-lg $space-lg $space-lg;\n \n &.no-padding {\n padding: 0;\n }\n}\n\n.card-footer {\n flex-shrink: 0;\n padding: $space-md $space-lg $space-lg $space-lg;\n border-top: 1px solid $border-light;\n background: $background-light;\n border-radius: 0 0 $radius-lg $radius-lg;\n}\n\n// Size variants\n.settings-card-sm {\n .card-header {\n padding: $space-md $space-md $space-sm $space-md;\n \n .card-title {\n font-size: $font-size-md;\n }\n \n .card-subtitle {\n font-size: $font-size-xs;\n }\n }\n \n .card-content {\n padding: 0 $space-md $space-md $space-md;\n \n &.no-padding {\n padding: 0;\n }\n }\n \n .card-footer {\n padding: $space-sm $space-md $space-md $space-md;\n }\n}\n\n.settings-card-lg {\n .card-header {\n padding: $space-xl $space-xl $space-lg $space-xl;\n \n .card-title {\n font-size: $font-size-xl;\n }\n }\n \n .card-content {\n padding: 0 $space-xl $space-xl $space-xl;\n \n &.no-padding {\n padding: 0;\n }\n }\n \n .card-footer {\n padding: $space-lg $space-xl $space-xl $space-xl;\n }\n}"] }]
|
|
151
|
+
`, styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n:host {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n color: #212121;\n}\n:host * {\n box-sizing: border-box;\n}\n\n.settings-card {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 20px;\n}\n.settings-card:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-floating {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n padding: 20px;\n}\n.settings-card-floating:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n\n.settings-card-sm {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 16px;\n}\n.settings-card-sm:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.settings-card-lg {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n padding: 24px;\n}\n.settings-card-lg:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n\n.dashboard-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 24px 0 16px 0;\n}\n.dashboard-header .header-info {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 16px;\n}\n.dashboard-header .header-info h1, .dashboard-header .header-info h2, .dashboard-header .header-info h3 {\n margin: 0;\n font-weight: 600;\n color: #212121;\n font-size: 24px;\n line-height: 1.2;\n}\n.dashboard-header .header-info h2 {\n font-size: 18px;\n}\n.dashboard-header .header-info h3 {\n font-size: 16px;\n}\n.dashboard-header .header-controls {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n}\n.section-header h3, .section-header h4 {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.section-header h4 {\n font-size: 14px;\n}\n\n.control-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #ffffff;\n color: #212121;\n border-color: #bdbdbd;\n}\n.control-btn:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn i {\n font-size: 14px;\n}\n.control-btn:hover:not(:disabled) {\n background: #f8f9fa;\n border-color: #2196f3;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.control-btn.control-btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n}\n.control-btn.control-btn-primary:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-primary i {\n font-size: 14px;\n}\n.control-btn.control-btn-primary:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-primary:active {\n transform: translateY(0);\n}\n.control-btn.control-btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n}\n.control-btn.control-btn-danger:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-danger i {\n font-size: 14px;\n}\n.control-btn.control-btn-danger:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.control-btn.control-btn-ghost {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n}\n.control-btn.control-btn-ghost:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.control-btn.control-btn-ghost:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.control-btn.control-btn-ghost i {\n font-size: 14px;\n}\n.control-btn.control-btn-ghost:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.control-btn.control-btn-sm {\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n}\n.control-btn.control-btn-sm i {\n font-size: 12px;\n}\n.control-btn.control-btn-lg {\n height: 44px;\n padding: 0 24px;\n font-size: 14px;\n}\n.control-btn.control-btn-lg i {\n font-size: 16px;\n}\n\n.action-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: transparent;\n color: #666666;\n border-color: transparent;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn i {\n font-size: 14px;\n}\n.action-btn:hover:not(:disabled) {\n background: #f8f9fa;\n color: #2196f3;\n}\n.action-btn i {\n font-size: 12px;\n}\n.action-btn.action-btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #2196f3;\n color: #ffffff;\n border-color: #2196f3;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-primary:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-primary i {\n font-size: 14px;\n}\n.action-btn.action-btn-primary:hover:not(:disabled) {\n background: #1976d2;\n border-color: #1976d2;\n box-shadow: 0 2px 8px rgba(33, 150, 243, 0.2);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-primary:active {\n transform: translateY(0);\n}\n.action-btn.action-btn-primary i {\n font-size: 12px;\n}\n.action-btn.action-btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 0 16px;\n height: 36px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 1;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n border: 1px solid transparent;\n outline: none;\n white-space: nowrap;\n background: #f44336;\n color: #ffffff;\n border-color: #f44336;\n height: 28px;\n padding: 0 8px;\n font-size: 11px;\n width: 28px;\n padding: 0;\n}\n.action-btn.action-btn-danger:focus {\n outline: 2px solid rgba(33, 150, 243, 0.2);\n outline-offset: 2px;\n}\n.action-btn.action-btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n.action-btn.action-btn-danger i {\n font-size: 14px;\n}\n.action-btn.action-btn-danger:hover:not(:disabled) {\n background: #ea1c0d;\n border-color: #ea1c0d;\n box-shadow: 0 2px 8px rgba(244, 67, 54, 0.3);\n transform: translateY(-1px);\n}\n.action-btn.action-btn-danger i {\n font-size: 12px;\n}\n\n.info-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(158, 158, 158, 0.1);\n color: #666666;\n border: 1px solid rgba(158, 158, 158, 0.2);\n}\n.status-badge.status-active {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(76, 175, 80, 0.1);\n color: #3d8b40;\n border: 1px solid rgba(76, 175, 80, 0.2);\n}\n.status-badge.status-migration {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(33, 150, 243, 0.1);\n color: #1976d2;\n border: 1px solid rgba(33, 150, 243, 0.2);\n}\n.status-badge.status-warning {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(255, 193, 7, 0.1);\n color: #6d5200;\n border: 1px solid rgba(255, 193, 7, 0.2);\n}\n.status-badge.status-error {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 8px;\n height: 20px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n line-height: 1;\n white-space: nowrap;\n background: rgba(244, 67, 54, 0.1);\n color: #ea1c0d;\n border: 1px solid rgba(244, 67, 54, 0.2);\n}\n\n.settings-nav {\n width: 220px;\n min-width: 220px;\n max-width: 220px;\n background: #ffffff;\n border-right: 1px solid #e0e0e0;\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow-y: auto;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n}\n.settings-nav .nav-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n margin: 0 8px 4px 8px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 400;\n color: #666666;\n text-decoration: none;\n cursor: pointer;\n transition: all 0.15s ease;\n position: relative;\n}\n.settings-nav .nav-item::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n width: 3px;\n height: 0;\n background: #2196f3;\n border-radius: 0 2px 2px 0;\n transition: height all 0.15s ease;\n}\n.settings-nav .nav-item:hover {\n background: #f8f9fa;\n color: #2196f3;\n transform: translateX(2px);\n}\n.settings-nav .nav-item.active {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n font-weight: 500;\n}\n.settings-nav .nav-item.active::before {\n height: 24px;\n}\n.settings-nav .nav-item i {\n font-size: 14px;\n width: 18px;\n text-align: center;\n}\n\n.form-field {\n margin-bottom: 16px;\n}\n.form-field .field-label {\n display: block;\n margin-bottom: 4px;\n font-size: 12px;\n font-weight: 500;\n color: #212121;\n}\n.form-field .field-hint {\n margin-top: 4px;\n font-size: 11px;\n color: #9e9e9e;\n}\n.form-field .field-error {\n margin-top: 4px;\n font-size: 11px;\n color: #f44336;\n}\n.form-field input, .form-field textarea, .form-field select {\n width: 100%;\n height: 36px;\n padding: 0 8px;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n font-size: 12px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n background: #ffffff;\n color: #212121;\n transition: all 0.15s ease;\n outline: none;\n}\n.form-field input::placeholder, .form-field textarea::placeholder, .form-field select::placeholder {\n color: #9e9e9e;\n}\n.form-field input:focus, .form-field textarea:focus, .form-field select:focus {\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);\n}\n.form-field input:disabled, .form-field textarea:disabled, .form-field select:disabled {\n background: #f8f9fa;\n color: #bdbdbd;\n cursor: not-allowed;\n}\n\n.form-row {\n display: flex;\n gap: 16px;\n}\n.form-row .form-field {\n flex: 1;\n}\n\n.checkbox-field {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 16px;\n}\n.checkbox-field label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: #212121;\n cursor: pointer;\n margin: 0;\n}\n\n.status-bar {\n display: flex;\n gap: 24px;\n padding: 16px;\n background: #fafafa;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n margin-bottom: 16px;\n}\n.status-bar .status-item {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n}\n.status-bar .status-item .status-label {\n color: #666666;\n font-weight: 500;\n}\n.status-bar .status-item .status-value {\n color: #212121;\n font-weight: 600;\n}\n.status-bar .status-item .status-value.text-success {\n color: #4caf50;\n}\n.status-bar .status-item .status-value.text-warning {\n color: #ffc107;\n}\n.status-bar .status-item .status-value.text-danger {\n color: #f44336;\n}\n\n.empty-state {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n text-align: center;\n color: #666666;\n}\n.empty-state i {\n font-size: 48px;\n color: #9e9e9e;\n margin-bottom: 8px;\n}\n.empty-state h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 500;\n color: #212121;\n}\n.empty-state p {\n margin: 0;\n font-size: 14px;\n max-width: 400px;\n line-height: 1.6;\n}\n\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 16px;\n padding: 48px;\n}\n.loading-container .loading-spinner {\n width: 40px;\n height: 40px;\n border: 3px solid #e0e0e0;\n border-top-color: #2196f3;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n}\n.loading-container .loading-text {\n font-size: 12px;\n color: #666666;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n.text-success {\n color: #4caf50 !important;\n}\n\n.text-warning {\n color: #ffc107 !important;\n}\n\n.text-danger {\n color: #f44336 !important;\n}\n\n.text-info {\n color: #00bcd4 !important;\n}\n\n.text-muted {\n color: #9e9e9e !important;\n}\n\n.text-primary {\n color: #212121 !important;\n}\n\n.text-secondary {\n color: #666666 !important;\n}\n\n.mb-0 {\n margin-bottom: 0 !important;\n}\n\n.mb-1 {\n margin-bottom: 4px !important;\n}\n\n.mb-2 {\n margin-bottom: 8px !important;\n}\n\n.mb-3 {\n margin-bottom: 16px !important;\n}\n\n.mb-4 {\n margin-bottom: 24px !important;\n}\n\n.mb-5 {\n margin-bottom: 32px !important;\n}\n\n.mt-0 {\n margin-top: 0 !important;\n}\n\n.mt-1 {\n margin-top: 4px !important;\n}\n\n.mt-2 {\n margin-top: 8px !important;\n}\n\n.mt-3 {\n margin-top: 16px !important;\n}\n\n.mt-4 {\n margin-top: 24px !important;\n}\n\n.mt-5 {\n margin-top: 32px !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-none {\n display: none !important;\n}\n\n.flex-1 {\n flex: 1 !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.align-center {\n align-items: center !important;\n}\n\n.justify-center {\n justify-content: center !important;\n}\n\n.justify-between {\n justify-content: space-between !important;\n}\n\n.stats-grid {\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n.stat-card {\n margin-right: 10px;\n}\n\n.role-card {\n margin-bottom: 5px;\n}\n\n@media (max-width: 768px) {\n .settings-card {\n padding: 16px;\n }\n .dashboard-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n .dashboard-header .header-controls {\n width: 100%;\n justify-content: flex-start;\n }\n .form-row {\n flex-direction: column;\n }\n}\n:host {\n display: block;\n width: 100%;\n}\n\n.settings-card {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n.settings-card:hover {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-1px);\n}\n.settings-card.settings-card-floating {\n background: #ffffff;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n overflow: hidden;\n transition: all 0.2s ease;\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n.settings-card.settings-card-floating:hover {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n transform: translateY(-2px);\n}\n.settings-card.settings-card-sm {\n padding: 16px;\n}\n.settings-card.settings-card-lg {\n padding: 24px;\n}\n\n.card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding-bottom: 8px;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n padding: 24px 24px 16px 24px;\n margin: 0;\n}\n.card-header h3, .card-header h4 {\n margin: 0;\n font-weight: 500;\n color: #212121;\n font-size: 16px;\n}\n.card-header h4 {\n font-size: 14px;\n}\n.card-header .header-content {\n flex: 1;\n}\n.card-header .header-content .card-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: #212121;\n line-height: 1.2;\n}\n.card-header .header-content .card-subtitle {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: #666666;\n line-height: 1.4;\n}\n.card-header .header-actions {\n flex-shrink: 0;\n display: flex;\n gap: 8px;\n align-items: flex-start;\n}\n\n.card-content {\n flex: 1;\n min-height: 0;\n padding: 0 24px 24px 24px;\n}\n.card-content.no-padding {\n padding: 0;\n}\n\n.card-footer {\n flex-shrink: 0;\n padding: 16px 24px 24px 24px;\n border-top: 1px solid #e0e0e0;\n background: #f8f9fa;\n border-radius: 0 0 8px 8px;\n}\n\n.settings-card-sm .card-header {\n padding: 16px 16px 8px 16px;\n}\n.settings-card-sm .card-header .card-title {\n font-size: 14px;\n}\n.settings-card-sm .card-header .card-subtitle {\n font-size: 11px;\n}\n.settings-card-sm .card-content {\n padding: 0 16px 16px 16px;\n}\n.settings-card-sm .card-content.no-padding {\n padding: 0;\n}\n.settings-card-sm .card-footer {\n padding: 8px 16px 16px 16px;\n}\n\n.settings-card-lg .card-header {\n padding: 32px 32px 24px 32px;\n}\n.settings-card-lg .card-header .card-title {\n font-size: 18px;\n}\n.settings-card-lg .card-content {\n padding: 0 32px 32px 32px;\n}\n.settings-card-lg .card-content.no-padding {\n padding: 0;\n}\n.settings-card-lg .card-footer {\n padding: 24px 32px 32px 32px;\n}\n"] }]
|
|
152
152
|
}], null, { title: [{
|
|
153
153
|
type: Input
|
|
154
154
|
}], subtitle: [{
|
|
@@ -1,6 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SharedService } from '@memberjunction/ng-shared';
|
|
1
|
+
import { OnDestroy } from '@angular/core';
|
|
2
|
+
import { SharedService, BaseDashboard } from '@memberjunction/ng-shared';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
|
+
/** Session options for SQL logging */
|
|
5
|
+
interface SqlLoggingSessionOptions {
|
|
6
|
+
formatAsMigration: boolean;
|
|
7
|
+
statementTypes: string;
|
|
8
|
+
prettyPrint: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Represents an active SQL logging session */
|
|
11
|
+
interface SqlLoggingSession {
|
|
12
|
+
id: string;
|
|
13
|
+
filePath: string;
|
|
14
|
+
startTime: string;
|
|
15
|
+
statementCount: number;
|
|
16
|
+
sessionName: string;
|
|
17
|
+
filterByUserId?: string;
|
|
18
|
+
options?: SqlLoggingSessionOptions;
|
|
19
|
+
}
|
|
20
|
+
/** SQL logging configuration from the server */
|
|
21
|
+
interface SqlLoggingConfig {
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
allowedLogDirectory?: string;
|
|
24
|
+
maxActiveSessions?: number;
|
|
25
|
+
autoCleanupEmptyFiles?: boolean;
|
|
26
|
+
sessionTimeout?: number;
|
|
27
|
+
activeSessionCount?: number;
|
|
28
|
+
defaultOptions?: SqlLoggingSessionOptions;
|
|
29
|
+
}
|
|
4
30
|
/**
|
|
5
31
|
* Angular component for managing SQL logging sessions in MemberJunction.
|
|
6
32
|
*
|
|
@@ -20,7 +46,7 @@ import * as i0 from "@angular/core";
|
|
|
20
46
|
* @requires Owner-level user privileges
|
|
21
47
|
* @requires SQL logging enabled in server configuration
|
|
22
48
|
*/
|
|
23
|
-
export declare class SqlLoggingComponent implements
|
|
49
|
+
export declare class SqlLoggingComponent extends BaseDashboard implements OnDestroy {
|
|
24
50
|
private sharedService;
|
|
25
51
|
private destroy$;
|
|
26
52
|
/** Whether the component is currently performing an async operation */
|
|
@@ -32,11 +58,11 @@ export declare class SqlLoggingComponent implements OnInit, OnDestroy {
|
|
|
32
58
|
/** Whether SQL logging is enabled in the server configuration */
|
|
33
59
|
configEnabled: boolean;
|
|
34
60
|
/** Current SQL logging configuration from the server */
|
|
35
|
-
sqlLoggingConfig:
|
|
61
|
+
sqlLoggingConfig: SqlLoggingConfig | null;
|
|
36
62
|
/** List of currently active SQL logging sessions */
|
|
37
|
-
activeSessions:
|
|
63
|
+
activeSessions: SqlLoggingSession[];
|
|
38
64
|
/** Currently selected session for viewing logs */
|
|
39
|
-
selectedSession:
|
|
65
|
+
selectedSession: SqlLoggingSession | null;
|
|
40
66
|
/** Content of the currently viewed log file */
|
|
41
67
|
logContent: string;
|
|
42
68
|
/** Whether to automatically refresh session data */
|
|
@@ -66,15 +92,8 @@ export declare class SqlLoggingComponent implements OnInit, OnDestroy {
|
|
|
66
92
|
value: string;
|
|
67
93
|
}[];
|
|
68
94
|
constructor(sharedService: SharedService);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
* Checks user permissions and loads initial data if authorized.
|
|
72
|
-
*/
|
|
73
|
-
ngOnInit(): Promise<void>;
|
|
74
|
-
/**
|
|
75
|
-
* Component cleanup.
|
|
76
|
-
* Stops auto-refresh and cleans up subscriptions.
|
|
77
|
-
*/
|
|
95
|
+
protected initDashboard(): void;
|
|
96
|
+
protected loadData(): Promise<void>;
|
|
78
97
|
ngOnDestroy(): void;
|
|
79
98
|
/**
|
|
80
99
|
* Starts the auto-refresh timer for session data.
|
|
@@ -171,6 +190,7 @@ export declare class SqlLoggingComponent implements OnInit, OnDestroy {
|
|
|
171
190
|
*/
|
|
172
191
|
debugUserEmail(): Promise<void>;
|
|
173
192
|
static ɵfac: i0.ɵɵFactoryDeclaration<SqlLoggingComponent, never>;
|
|
174
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SqlLoggingComponent, "mj-sql-logging", never, {}, {}, never, never,
|
|
193
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SqlLoggingComponent, "mj-sql-logging", never, {}, {}, never, never, false, never>;
|
|
175
194
|
}
|
|
195
|
+
export {};
|
|
176
196
|
//# sourceMappingURL=sql-logging.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-logging.component.d.ts","sourceRoot":"","sources":["../../../src/lib/sql-logging/sql-logging.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"sql-logging.component.d.ts","sourceRoot":"","sources":["../../../src/lib/sql-logging/sql-logging.component.ts"],"names":[],"mappings":"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"}
|