@memberjunction/ng-dashboards 5.31.0 → 5.33.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/Admin/admin-data-schema.component.d.ts +16 -0
- package/dist/Admin/admin-data-schema.component.d.ts.map +1 -0
- package/dist/Admin/admin-data-schema.component.js +136 -0
- package/dist/Admin/admin-data-schema.component.js.map +1 -0
- package/dist/Admin/admin-dev-tools-resource.component.d.ts +14 -0
- package/dist/Admin/admin-dev-tools-resource.component.d.ts.map +1 -0
- package/dist/Admin/admin-dev-tools-resource.component.js +162 -0
- package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -0
- package/dist/Admin/admin-identity-access.component.d.ts +15 -0
- package/dist/Admin/admin-identity-access.component.d.ts.map +1 -0
- package/dist/Admin/admin-identity-access.component.js +156 -0
- package/dist/Admin/admin-identity-access.component.js.map +1 -0
- package/dist/Admin/admin-monitoring.component.d.ts +15 -0
- package/dist/Admin/admin-monitoring.component.d.ts.map +1 -0
- package/dist/Admin/admin-monitoring.component.js +130 -0
- package/dist/Admin/admin-monitoring.component.js.map +1 -0
- package/dist/Admin/base-admin-container.component.d.ts +80 -0
- package/dist/Admin/base-admin-container.component.d.ts.map +1 -0
- package/dist/Admin/base-admin-container.component.js +198 -0
- package/dist/Admin/base-admin-container.component.js.map +1 -0
- package/dist/Admin/index.d.ts +6 -0
- package/dist/Admin/index.d.ts.map +1 -0
- package/dist/Admin/index.js +6 -0
- package/dist/Admin/index.js.map +1 -0
- package/dist/DevTools/app-state-inspector.component.d.ts +53 -0
- package/dist/DevTools/app-state-inspector.component.d.ts.map +1 -0
- package/dist/DevTools/app-state-inspector.component.js +301 -0
- package/dist/DevTools/app-state-inspector.component.js.map +1 -0
- package/dist/DevTools/class-registry.component.d.ts +64 -0
- package/dist/DevTools/class-registry.component.d.ts.map +1 -0
- package/dist/DevTools/class-registry.component.js +423 -0
- package/dist/DevTools/class-registry.component.js.map +1 -0
- package/dist/DevTools/dev-tools-prefs.d.ts +21 -0
- package/dist/DevTools/dev-tools-prefs.d.ts.map +1 -0
- package/dist/DevTools/dev-tools-prefs.js +48 -0
- package/dist/DevTools/dev-tools-prefs.js.map +1 -0
- package/dist/DevTools/event-monitor.component.d.ts +78 -0
- package/dist/DevTools/event-monitor.component.d.ts.map +1 -0
- package/dist/DevTools/event-monitor.component.js +659 -0
- package/dist/DevTools/event-monitor.component.js.map +1 -0
- package/dist/DevTools/graphql-console.component.d.ts +153 -0
- package/dist/DevTools/graphql-console.component.d.ts.map +1 -0
- package/dist/DevTools/graphql-console.component.js +1463 -0
- package/dist/DevTools/graphql-console.component.js.map +1 -0
- package/dist/DevTools/index.d.ts +8 -0
- package/dist/DevTools/index.d.ts.map +1 -0
- package/dist/DevTools/index.js +8 -0
- package/dist/DevTools/index.js.map +1 -0
- package/dist/DevTools/layout-inspector.component.d.ts +42 -0
- package/dist/DevTools/layout-inspector.component.d.ts.map +1 -0
- package/dist/DevTools/layout-inspector.component.js +208 -0
- package/dist/DevTools/layout-inspector.component.js.map +1 -0
- package/dist/DevTools/lazy-module-status.component.d.ts +65 -0
- package/dist/DevTools/lazy-module-status.component.d.ts.map +1 -0
- package/dist/DevTools/lazy-module-status.component.js +388 -0
- package/dist/DevTools/lazy-module-status.component.js.map +1 -0
- package/dist/DevTools/settings-explorer.component.d.ts +55 -0
- package/dist/DevTools/settings-explorer.component.d.ts.map +1 -0
- package/dist/DevTools/settings-explorer.component.js +394 -0
- package/dist/DevTools/settings-explorer.component.js.map +1 -0
- package/dist/core-dashboards.module.d.ts +45 -34
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +57 -0
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +2 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +52 -52
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
|
|
2
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
interface SettingRow {
|
|
5
|
+
key: string;
|
|
6
|
+
rawValue: string;
|
|
7
|
+
parsedValue: unknown;
|
|
8
|
+
valueType: 'string' | 'number' | 'boolean' | 'json' | 'empty';
|
|
9
|
+
/** Pretty preview shown in the table cell. */
|
|
10
|
+
preview: string;
|
|
11
|
+
/** Optional secondary metadata shown next to the key. */
|
|
12
|
+
meta?: string;
|
|
13
|
+
updated?: Date | null;
|
|
14
|
+
}
|
|
15
|
+
type SettingsScope = 'user' | 'instance';
|
|
16
|
+
/**
|
|
17
|
+
* Settings Explorer — read-only browser for both `MJ: User Settings` (the
|
|
18
|
+
* current user's per-app key/value bag) and `MJ: Instance Configurations`
|
|
19
|
+
* (instance-level feature flags). Auto-detects JSON values, formats them
|
|
20
|
+
* nicely, supports search + copy.
|
|
21
|
+
*/
|
|
22
|
+
export declare class SettingsExplorerComponent extends BaseResourceComponent implements OnInit, OnDestroy {
|
|
23
|
+
private cdr;
|
|
24
|
+
Scope: SettingsScope;
|
|
25
|
+
UserRows: SettingRow[];
|
|
26
|
+
InstanceRows: SettingRow[];
|
|
27
|
+
SearchQuery: string;
|
|
28
|
+
Selected: SettingRow | null;
|
|
29
|
+
LastRefreshed: Date;
|
|
30
|
+
Counts: {
|
|
31
|
+
user: number;
|
|
32
|
+
instance: number;
|
|
33
|
+
};
|
|
34
|
+
constructor(cdr: ChangeDetectorRef);
|
|
35
|
+
ngOnInit(): void;
|
|
36
|
+
ngOnDestroy(): void;
|
|
37
|
+
PersistPrefs(): void;
|
|
38
|
+
GetResourceDisplayName(): Promise<string>;
|
|
39
|
+
GetResourceIconClass(): Promise<string>;
|
|
40
|
+
refresh(): void;
|
|
41
|
+
OnScopeChange(scope: SettingsScope): void;
|
|
42
|
+
get FilteredRows(): SettingRow[];
|
|
43
|
+
OnRowClick(row: SettingRow): void;
|
|
44
|
+
OnCopySelected(): Promise<void>;
|
|
45
|
+
get LastRefreshedLabel(): string;
|
|
46
|
+
get FormattedSelected(): string;
|
|
47
|
+
TrackByKey: (_i: number, r: SettingRow) => string;
|
|
48
|
+
private buildInstanceMeta;
|
|
49
|
+
private toRow;
|
|
50
|
+
private summarizeJson;
|
|
51
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SettingsExplorerComponent, never>;
|
|
52
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SettingsExplorerComponent, "mj-settings-explorer", never, {}, {}, never, never, false, never>;
|
|
53
|
+
}
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=settings-explorer.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-explorer.component.d.ts","sourceRoot":"","sources":["../../src/DevTools/settings-explorer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAUlE,UAAU,UAAU;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9D,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACzB;AAED,KAAK,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAEzC;;;;;GAKG;AACH,qBAOa,yBAA0B,SAAQ,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAWjF,OAAO,CAAC,GAAG;IAThB,KAAK,EAAE,aAAa,CAAU;IAC9B,QAAQ,EAAE,UAAU,EAAE,CAAM;IAC5B,YAAY,EAAE,UAAU,EAAE,CAAM;IAChC,WAAW,SAAM;IACjB,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAQ;IACnC,aAAa,OAAc;IAE3B,MAAM;;;MAA4B;gBAErB,GAAG,EAAE,iBAAiB;IAInC,QAAQ,IAAI,IAAI;IAQP,WAAW,IAAI,IAAI;IAK5B,YAAY,IAAI,IAAI;IAIL,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;IACzC,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAEtD,OAAO,IAAI,IAAI;IA4Bf,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAMhD,IAAW,YAAY,IAAI,UAAU,EAAE,CAKtC;IAEM,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAI3B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5C,IAAW,kBAAkB,IAAI,MAAM,CAEtC;IAED,IAAW,iBAAiB,IAAI,MAAM,CAMrC;IAEM,UAAU,GAAI,IAAI,MAAM,EAAE,GAAG,UAAU,YAAW;IAIzD,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,KAAK;IAsCb,OAAO,CAAC,aAAa;yCAzJZ,yBAAyB;2CAAzB,yBAAyB;CAkKrC"}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Component } from '@angular/core';
|
|
8
|
+
import { BaseResourceComponent } from '@memberjunction/ng-shared';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { UserInfoEngine, InstanceConfigEngine } from '@memberjunction/core-entities';
|
|
11
|
+
import { DevToolsPrefs } from './dev-tools-prefs';
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
import * as i1 from "@angular/forms";
|
|
14
|
+
function SettingsExplorerComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
15
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
16
|
+
i0.ɵɵelementStart(0, "button", 26);
|
|
17
|
+
i0.ɵɵlistener("click", function SettingsExplorerComponent_Conditional_29_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SearchQuery = ""); });
|
|
18
|
+
i0.ɵɵelement(1, "i", 27);
|
|
19
|
+
i0.ɵɵelementEnd();
|
|
20
|
+
} }
|
|
21
|
+
function SettingsExplorerComponent_Conditional_32_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
+
i0.ɵɵelement(0, "i", 28);
|
|
23
|
+
i0.ɵɵelementStart(1, "span");
|
|
24
|
+
i0.ɵɵtext(2);
|
|
25
|
+
i0.ɵɵelementEnd();
|
|
26
|
+
} if (rf & 2) {
|
|
27
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
28
|
+
i0.ɵɵadvance(2);
|
|
29
|
+
i0.ɵɵtextInterpolate1("No matches for \"", ctx_r1.SearchQuery, "\"");
|
|
30
|
+
} }
|
|
31
|
+
function SettingsExplorerComponent_Conditional_32_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
+
i0.ɵɵelement(0, "i", 29);
|
|
33
|
+
i0.ɵɵelementStart(1, "span");
|
|
34
|
+
i0.ɵɵtext(2);
|
|
35
|
+
i0.ɵɵelementEnd();
|
|
36
|
+
} if (rf & 2) {
|
|
37
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
38
|
+
i0.ɵɵadvance(2);
|
|
39
|
+
i0.ɵɵtextInterpolate1("No ", ctx_r1.Scope === "user" ? "user settings" : "instance configurations", " are defined.");
|
|
40
|
+
} }
|
|
41
|
+
function SettingsExplorerComponent_Conditional_32_Template(rf, ctx) { if (rf & 1) {
|
|
42
|
+
i0.ɵɵelementStart(0, "div", 22);
|
|
43
|
+
i0.ɵɵconditionalCreate(1, SettingsExplorerComponent_Conditional_32_Conditional_1_Template, 3, 1)(2, SettingsExplorerComponent_Conditional_32_Conditional_2_Template, 3, 1);
|
|
44
|
+
i0.ɵɵelementEnd();
|
|
45
|
+
} if (rf & 2) {
|
|
46
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
47
|
+
i0.ɵɵadvance();
|
|
48
|
+
i0.ɵɵconditional(ctx_r1.SearchQuery ? 1 : 2);
|
|
49
|
+
} }
|
|
50
|
+
function SettingsExplorerComponent_Conditional_33_For_11_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
51
|
+
i0.ɵɵelementStart(0, "div", 36);
|
|
52
|
+
i0.ɵɵtext(1);
|
|
53
|
+
i0.ɵɵelementEnd();
|
|
54
|
+
} if (rf & 2) {
|
|
55
|
+
const row_r4 = i0.ɵɵnextContext().$implicit;
|
|
56
|
+
i0.ɵɵadvance();
|
|
57
|
+
i0.ɵɵtextInterpolate(row_r4.meta);
|
|
58
|
+
} }
|
|
59
|
+
function SettingsExplorerComponent_Conditional_33_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
60
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
61
|
+
i0.ɵɵelementStart(0, "tr", 34);
|
|
62
|
+
i0.ɵɵlistener("click", function SettingsExplorerComponent_Conditional_33_For_11_Template_tr_click_0_listener() { const row_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnRowClick(row_r4)); });
|
|
63
|
+
i0.ɵɵelementStart(1, "td", 35)(2, "code");
|
|
64
|
+
i0.ɵɵtext(3);
|
|
65
|
+
i0.ɵɵelementEnd();
|
|
66
|
+
i0.ɵɵconditionalCreate(4, SettingsExplorerComponent_Conditional_33_For_11_Conditional_4_Template, 2, 1, "div", 36);
|
|
67
|
+
i0.ɵɵelementEnd();
|
|
68
|
+
i0.ɵɵelementStart(5, "td", 37)(6, "span", 38);
|
|
69
|
+
i0.ɵɵtext(7);
|
|
70
|
+
i0.ɵɵelementEnd()();
|
|
71
|
+
i0.ɵɵelementStart(8, "td", 39);
|
|
72
|
+
i0.ɵɵtext(9);
|
|
73
|
+
i0.ɵɵelementEnd()();
|
|
74
|
+
} if (rf & 2) {
|
|
75
|
+
const row_r4 = ctx.$implicit;
|
|
76
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
77
|
+
i0.ɵɵclassProp("se-row--selected", (ctx_r1.Selected == null ? null : ctx_r1.Selected.key) === row_r4.key);
|
|
78
|
+
i0.ɵɵadvance(3);
|
|
79
|
+
i0.ɵɵtextInterpolate(row_r4.key);
|
|
80
|
+
i0.ɵɵadvance();
|
|
81
|
+
i0.ɵɵconditional(row_r4.meta ? 4 : -1);
|
|
82
|
+
i0.ɵɵadvance(2);
|
|
83
|
+
i0.ɵɵclassMap("se-type-pill--" + row_r4.valueType);
|
|
84
|
+
i0.ɵɵadvance();
|
|
85
|
+
i0.ɵɵtextInterpolate1(" ", row_r4.valueType, " ");
|
|
86
|
+
i0.ɵɵadvance(2);
|
|
87
|
+
i0.ɵɵtextInterpolate(row_r4.preview);
|
|
88
|
+
} }
|
|
89
|
+
function SettingsExplorerComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
90
|
+
i0.ɵɵelementStart(0, "table", 23)(1, "thead")(2, "tr")(3, "th", 30);
|
|
91
|
+
i0.ɵɵtext(4, "Key");
|
|
92
|
+
i0.ɵɵelementEnd();
|
|
93
|
+
i0.ɵɵelementStart(5, "th", 31);
|
|
94
|
+
i0.ɵɵtext(6, "Type");
|
|
95
|
+
i0.ɵɵelementEnd();
|
|
96
|
+
i0.ɵɵelementStart(7, "th", 32);
|
|
97
|
+
i0.ɵɵtext(8, "Value");
|
|
98
|
+
i0.ɵɵelementEnd()()();
|
|
99
|
+
i0.ɵɵelementStart(9, "tbody");
|
|
100
|
+
i0.ɵɵrepeaterCreate(10, SettingsExplorerComponent_Conditional_33_For_11_Template, 10, 8, "tr", 33, i0.ɵɵcomponentInstance().TrackByKey, true);
|
|
101
|
+
i0.ɵɵelementEnd()();
|
|
102
|
+
} if (rf & 2) {
|
|
103
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
104
|
+
i0.ɵɵadvance(10);
|
|
105
|
+
i0.ɵɵrepeater(ctx_r1.FilteredRows);
|
|
106
|
+
} }
|
|
107
|
+
function SettingsExplorerComponent_Conditional_34_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
108
|
+
i0.ɵɵelementStart(0, "div", 42);
|
|
109
|
+
i0.ɵɵtext(1);
|
|
110
|
+
i0.ɵɵelementEnd();
|
|
111
|
+
} if (rf & 2) {
|
|
112
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
113
|
+
i0.ɵɵadvance();
|
|
114
|
+
i0.ɵɵtextInterpolate(ctx_r1.Selected.meta);
|
|
115
|
+
} }
|
|
116
|
+
function SettingsExplorerComponent_Conditional_34_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
117
|
+
i0.ɵɵelementStart(0, "span", 49);
|
|
118
|
+
i0.ɵɵtext(1);
|
|
119
|
+
i0.ɵɵelementEnd();
|
|
120
|
+
} if (rf & 2) {
|
|
121
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
122
|
+
i0.ɵɵadvance();
|
|
123
|
+
i0.ɵɵtextInterpolate1("Updated ", ctx_r1.Selected.updated.toLocaleString());
|
|
124
|
+
} }
|
|
125
|
+
function SettingsExplorerComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
126
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
127
|
+
i0.ɵɵelementStart(0, "aside", 24)(1, "div", 40)(2, "div")(3, "div", 41);
|
|
128
|
+
i0.ɵɵtext(4);
|
|
129
|
+
i0.ɵɵelementEnd();
|
|
130
|
+
i0.ɵɵconditionalCreate(5, SettingsExplorerComponent_Conditional_34_Conditional_5_Template, 2, 1, "div", 42);
|
|
131
|
+
i0.ɵɵelementEnd();
|
|
132
|
+
i0.ɵɵelementStart(6, "div", 43)(7, "button", 44);
|
|
133
|
+
i0.ɵɵlistener("click", function SettingsExplorerComponent_Conditional_34_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnCopySelected()); });
|
|
134
|
+
i0.ɵɵelement(8, "i", 45);
|
|
135
|
+
i0.ɵɵtext(9, " Copy ");
|
|
136
|
+
i0.ɵɵelementEnd();
|
|
137
|
+
i0.ɵɵelementStart(10, "button", 46);
|
|
138
|
+
i0.ɵɵlistener("click", function SettingsExplorerComponent_Conditional_34_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Selected = null); });
|
|
139
|
+
i0.ɵɵelement(11, "i", 27);
|
|
140
|
+
i0.ɵɵelementEnd()()();
|
|
141
|
+
i0.ɵɵelementStart(12, "div", 47)(13, "div", 48)(14, "span", 38);
|
|
142
|
+
i0.ɵɵtext(15);
|
|
143
|
+
i0.ɵɵelementEnd();
|
|
144
|
+
i0.ɵɵconditionalCreate(16, SettingsExplorerComponent_Conditional_34_Conditional_16_Template, 2, 1, "span", 49);
|
|
145
|
+
i0.ɵɵelementEnd();
|
|
146
|
+
i0.ɵɵelementStart(17, "pre", 50)(18, "code");
|
|
147
|
+
i0.ɵɵtext(19);
|
|
148
|
+
i0.ɵɵelementEnd()()()();
|
|
149
|
+
} if (rf & 2) {
|
|
150
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
151
|
+
i0.ɵɵadvance(4);
|
|
152
|
+
i0.ɵɵtextInterpolate(ctx_r1.Selected.key);
|
|
153
|
+
i0.ɵɵadvance();
|
|
154
|
+
i0.ɵɵconditional(ctx_r1.Selected.meta ? 5 : -1);
|
|
155
|
+
i0.ɵɵadvance(9);
|
|
156
|
+
i0.ɵɵclassMap("se-type-pill--" + ctx_r1.Selected.valueType);
|
|
157
|
+
i0.ɵɵadvance();
|
|
158
|
+
i0.ɵɵtextInterpolate(ctx_r1.Selected.valueType);
|
|
159
|
+
i0.ɵɵadvance();
|
|
160
|
+
i0.ɵɵconditional(ctx_r1.Selected.updated ? 16 : -1);
|
|
161
|
+
i0.ɵɵadvance(3);
|
|
162
|
+
i0.ɵɵtextInterpolate(ctx_r1.FormattedSelected || "(empty)");
|
|
163
|
+
} }
|
|
164
|
+
/**
|
|
165
|
+
* Settings Explorer — read-only browser for both `MJ: User Settings` (the
|
|
166
|
+
* current user's per-app key/value bag) and `MJ: Instance Configurations`
|
|
167
|
+
* (instance-level feature flags). Auto-detects JSON values, formats them
|
|
168
|
+
* nicely, supports search + copy.
|
|
169
|
+
*/
|
|
170
|
+
let SettingsExplorerComponent = class SettingsExplorerComponent extends BaseResourceComponent {
|
|
171
|
+
cdr;
|
|
172
|
+
Scope = 'user';
|
|
173
|
+
UserRows = [];
|
|
174
|
+
InstanceRows = [];
|
|
175
|
+
SearchQuery = '';
|
|
176
|
+
Selected = null;
|
|
177
|
+
LastRefreshed = new Date();
|
|
178
|
+
Counts = { user: 0, instance: 0 };
|
|
179
|
+
constructor(cdr) {
|
|
180
|
+
super();
|
|
181
|
+
this.cdr = cdr;
|
|
182
|
+
}
|
|
183
|
+
ngOnInit() {
|
|
184
|
+
const p = DevToolsPrefs.Get('settingsExplorer');
|
|
185
|
+
if (p?.scope)
|
|
186
|
+
this.Scope = p.scope;
|
|
187
|
+
if (p?.search)
|
|
188
|
+
this.SearchQuery = p.search;
|
|
189
|
+
this.refresh();
|
|
190
|
+
this.NotifyLoadComplete();
|
|
191
|
+
}
|
|
192
|
+
ngOnDestroy() {
|
|
193
|
+
DevToolsPrefs.Save('settingsExplorer', { scope: this.Scope, search: this.SearchQuery });
|
|
194
|
+
super.ngOnDestroy();
|
|
195
|
+
}
|
|
196
|
+
PersistPrefs() {
|
|
197
|
+
DevToolsPrefs.Save('settingsExplorer', { scope: this.Scope, search: this.SearchQuery });
|
|
198
|
+
}
|
|
199
|
+
async GetResourceDisplayName() { return 'Settings Explorer'; }
|
|
200
|
+
async GetResourceIconClass() { return 'fa-solid fa-sliders'; }
|
|
201
|
+
refresh() {
|
|
202
|
+
const userSettings = UserInfoEngine.Instance.UserSettings ?? [];
|
|
203
|
+
this.UserRows = userSettings.map(s => this.toRow(s.Setting ?? '(no key)', s.Value ?? '', s.User ? `User: ${s.User}` : undefined, s.__mj_UpdatedAt));
|
|
204
|
+
const instanceConfigs = InstanceConfigEngine.Instance.InstanceConfigs ?? [];
|
|
205
|
+
this.InstanceRows = instanceConfigs.map(c => this.toRow(c.FeatureKey ?? '(no key)', c.Value ?? '', this.buildInstanceMeta(c), c.__mj_UpdatedAt));
|
|
206
|
+
this.Counts = { user: this.UserRows.length, instance: this.InstanceRows.length };
|
|
207
|
+
// Sort each list by key
|
|
208
|
+
this.UserRows.sort((a, b) => a.key.localeCompare(b.key));
|
|
209
|
+
this.InstanceRows.sort((a, b) => a.key.localeCompare(b.key));
|
|
210
|
+
// Re-resolve selection if it still exists
|
|
211
|
+
if (this.Selected) {
|
|
212
|
+
const list = this.Scope === 'user' ? this.UserRows : this.InstanceRows;
|
|
213
|
+
this.Selected = list.find(r => r.key === this.Selected.key) ?? null;
|
|
214
|
+
}
|
|
215
|
+
this.LastRefreshed = new Date();
|
|
216
|
+
this.cdr.markForCheck();
|
|
217
|
+
}
|
|
218
|
+
OnScopeChange(scope) {
|
|
219
|
+
this.Scope = scope;
|
|
220
|
+
this.Selected = null;
|
|
221
|
+
this.PersistPrefs();
|
|
222
|
+
}
|
|
223
|
+
get FilteredRows() {
|
|
224
|
+
const list = this.Scope === 'user' ? this.UserRows : this.InstanceRows;
|
|
225
|
+
const q = this.SearchQuery.trim().toLowerCase();
|
|
226
|
+
if (!q)
|
|
227
|
+
return list;
|
|
228
|
+
return list.filter(r => r.key.toLowerCase().includes(q) || r.rawValue.toLowerCase().includes(q));
|
|
229
|
+
}
|
|
230
|
+
OnRowClick(row) {
|
|
231
|
+
this.Selected = this.Selected?.key === row.key ? null : row;
|
|
232
|
+
}
|
|
233
|
+
async OnCopySelected() {
|
|
234
|
+
if (!this.Selected)
|
|
235
|
+
return;
|
|
236
|
+
const text = this.Selected.valueType === 'json'
|
|
237
|
+
? JSON.stringify(this.Selected.parsedValue, null, 2)
|
|
238
|
+
: this.Selected.rawValue;
|
|
239
|
+
try {
|
|
240
|
+
await navigator.clipboard.writeText(text);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// unavailable
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
get LastRefreshedLabel() {
|
|
247
|
+
return this.LastRefreshed.toLocaleTimeString();
|
|
248
|
+
}
|
|
249
|
+
get FormattedSelected() {
|
|
250
|
+
if (!this.Selected)
|
|
251
|
+
return '';
|
|
252
|
+
if (this.Selected.valueType === 'json') {
|
|
253
|
+
return JSON.stringify(this.Selected.parsedValue, null, 2);
|
|
254
|
+
}
|
|
255
|
+
return this.Selected.rawValue;
|
|
256
|
+
}
|
|
257
|
+
TrackByKey = (_i, r) => r.key;
|
|
258
|
+
// ---------- private ----------
|
|
259
|
+
buildInstanceMeta(c) {
|
|
260
|
+
const parts = [];
|
|
261
|
+
if (c.Category)
|
|
262
|
+
parts.push(c.Category);
|
|
263
|
+
if (c.DisplayName && c.DisplayName !== c.FeatureKey)
|
|
264
|
+
parts.push(c.DisplayName);
|
|
265
|
+
return parts.length ? parts.join(' · ') : undefined;
|
|
266
|
+
}
|
|
267
|
+
toRow(key, rawValue, meta, updated) {
|
|
268
|
+
const raw = rawValue ?? '';
|
|
269
|
+
let valueType = 'string';
|
|
270
|
+
let parsedValue = raw;
|
|
271
|
+
let preview = raw;
|
|
272
|
+
if (raw === '') {
|
|
273
|
+
valueType = 'empty';
|
|
274
|
+
preview = '(empty)';
|
|
275
|
+
}
|
|
276
|
+
else if (raw === 'true' || raw === 'false') {
|
|
277
|
+
valueType = 'boolean';
|
|
278
|
+
parsedValue = raw === 'true';
|
|
279
|
+
}
|
|
280
|
+
else if (/^-?\d+(\.\d+)?$/.test(raw) && raw.length < 20) {
|
|
281
|
+
valueType = 'number';
|
|
282
|
+
parsedValue = Number(raw);
|
|
283
|
+
}
|
|
284
|
+
else if ((raw.startsWith('{') && raw.endsWith('}')) || (raw.startsWith('[') && raw.endsWith(']'))) {
|
|
285
|
+
try {
|
|
286
|
+
parsedValue = JSON.parse(raw);
|
|
287
|
+
valueType = 'json';
|
|
288
|
+
preview = this.summarizeJson(parsedValue);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
// not actually JSON — leave as string
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (preview.length > 80)
|
|
295
|
+
preview = preview.slice(0, 77) + '…';
|
|
296
|
+
return {
|
|
297
|
+
key,
|
|
298
|
+
rawValue: raw,
|
|
299
|
+
parsedValue,
|
|
300
|
+
valueType,
|
|
301
|
+
preview,
|
|
302
|
+
meta,
|
|
303
|
+
updated: updated ? (updated instanceof Date ? updated : new Date(updated)) : null
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
summarizeJson(value) {
|
|
307
|
+
if (Array.isArray(value))
|
|
308
|
+
return `[ ${value.length} item${value.length === 1 ? '' : 's'} ]`;
|
|
309
|
+
if (value && typeof value === 'object') {
|
|
310
|
+
const keys = Object.keys(value);
|
|
311
|
+
if (keys.length === 0)
|
|
312
|
+
return '{ }';
|
|
313
|
+
return `{ ${keys.slice(0, 3).join(', ')}${keys.length > 3 ? ', …' : ''} }`;
|
|
314
|
+
}
|
|
315
|
+
return String(value);
|
|
316
|
+
}
|
|
317
|
+
static ɵfac = function SettingsExplorerComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SettingsExplorerComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
318
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SettingsExplorerComponent, selectors: [["mj-settings-explorer"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 37, vars: 11, consts: [[1, "mj-inspector", "mj-inspector--solo"], [1, "mj-inspector__header"], [1, "mj-inspector__header-icon"], [1, "fa-solid", "fa-sliders"], [1, "mj-inspector__header-title"], [1, "mj-inspector__header-sub"], [1, "mj-inspector__header-spacer"], [1, "mj-inspector__header-actions"], ["type", "button", "title", "Refresh", 1, "mj-inspector__btn", 3, "click"], [1, "fa-solid", "fa-rotate"], [1, "se-toolbar"], [1, "se-tabs"], ["type", "button", 1, "se-tab", 3, "click"], [1, "fa-solid", "fa-user"], [1, "se-count"], [1, "fa-solid", "fa-server"], [1, "se-search-wrap"], [1, "fa-solid", "fa-search", "se-search-icon"], ["type", "search", "placeholder", "Search keys or values\u2026", 1, "se-search", 3, "ngModelChange", "ngModel"], ["title", "Clear", 1, "se-search-clear"], [1, "se-body"], [1, "se-list"], [1, "se-empty"], [1, "se-table"], [1, "se-detail"], [1, "mj-inspector__footer-meta"], ["title", "Clear", 1, "se-search-clear", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "fa-solid", "fa-magnifying-glass"], [1, "fa-regular", "fa-folder-open"], [1, "se-th-key"], [1, "se-th-type"], [1, "se-th-value"], [3, "se-row--selected"], [3, "click"], [1, "se-td-key"], [1, "se-td-meta"], [1, "se-td-type"], [1, "se-type-pill"], [1, "se-td-value"], [1, "se-detail-head"], [1, "se-detail-key"], [1, "se-detail-meta"], [1, "se-detail-actions"], ["title", "Copy value", 1, "mj-inspector__btn", 3, "click"], [1, "fa-solid", "fa-clipboard"], ["title", "Close", 1, "mj-inspector__btn", "mj-inspector__btn--ghost", 3, "click"], [1, "se-detail-body"], [1, "se-detail-meta-row"], [1, "se-detail-updated"], [1, "se-detail-value"]], template: function SettingsExplorerComponent_Template(rf, ctx) { if (rf & 1) {
|
|
319
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
|
|
320
|
+
i0.ɵɵelement(3, "i", 3);
|
|
321
|
+
i0.ɵɵelementEnd();
|
|
322
|
+
i0.ɵɵelementStart(4, "div")(5, "h3", 4);
|
|
323
|
+
i0.ɵɵtext(6, "Settings Explorer");
|
|
324
|
+
i0.ɵɵelementEnd();
|
|
325
|
+
i0.ɵɵelementStart(7, "div", 5);
|
|
326
|
+
i0.ɵɵtext(8, "User settings and instance-level configuration");
|
|
327
|
+
i0.ɵɵelementEnd()();
|
|
328
|
+
i0.ɵɵelement(9, "span", 6);
|
|
329
|
+
i0.ɵɵelementStart(10, "div", 7)(11, "button", 8);
|
|
330
|
+
i0.ɵɵlistener("click", function SettingsExplorerComponent_Template_button_click_11_listener() { return ctx.refresh(); });
|
|
331
|
+
i0.ɵɵelement(12, "i", 9);
|
|
332
|
+
i0.ɵɵtext(13, " Refresh ");
|
|
333
|
+
i0.ɵɵelementEnd()()();
|
|
334
|
+
i0.ɵɵelementStart(14, "div", 10)(15, "div", 11)(16, "button", 12);
|
|
335
|
+
i0.ɵɵlistener("click", function SettingsExplorerComponent_Template_button_click_16_listener() { return ctx.OnScopeChange("user"); });
|
|
336
|
+
i0.ɵɵelement(17, "i", 13);
|
|
337
|
+
i0.ɵɵtext(18, " User Settings ");
|
|
338
|
+
i0.ɵɵelementStart(19, "span", 14);
|
|
339
|
+
i0.ɵɵtext(20);
|
|
340
|
+
i0.ɵɵelementEnd()();
|
|
341
|
+
i0.ɵɵelementStart(21, "button", 12);
|
|
342
|
+
i0.ɵɵlistener("click", function SettingsExplorerComponent_Template_button_click_21_listener() { return ctx.OnScopeChange("instance"); });
|
|
343
|
+
i0.ɵɵelement(22, "i", 15);
|
|
344
|
+
i0.ɵɵtext(23, " Instance Configurations ");
|
|
345
|
+
i0.ɵɵelementStart(24, "span", 14);
|
|
346
|
+
i0.ɵɵtext(25);
|
|
347
|
+
i0.ɵɵelementEnd()()();
|
|
348
|
+
i0.ɵɵelementStart(26, "div", 16);
|
|
349
|
+
i0.ɵɵelement(27, "i", 17);
|
|
350
|
+
i0.ɵɵelementStart(28, "input", 18);
|
|
351
|
+
i0.ɵɵtwoWayListener("ngModelChange", function SettingsExplorerComponent_Template_input_ngModelChange_28_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.SearchQuery, $event) || (ctx.SearchQuery = $event); return $event; });
|
|
352
|
+
i0.ɵɵlistener("ngModelChange", function SettingsExplorerComponent_Template_input_ngModelChange_28_listener() { return ctx.PersistPrefs(); });
|
|
353
|
+
i0.ɵɵelementEnd();
|
|
354
|
+
i0.ɵɵconditionalCreate(29, SettingsExplorerComponent_Conditional_29_Template, 2, 0, "button", 19);
|
|
355
|
+
i0.ɵɵelementEnd()();
|
|
356
|
+
i0.ɵɵelementStart(30, "div", 20)(31, "div", 21);
|
|
357
|
+
i0.ɵɵconditionalCreate(32, SettingsExplorerComponent_Conditional_32_Template, 3, 1, "div", 22)(33, SettingsExplorerComponent_Conditional_33_Template, 12, 0, "table", 23);
|
|
358
|
+
i0.ɵɵelementEnd();
|
|
359
|
+
i0.ɵɵconditionalCreate(34, SettingsExplorerComponent_Conditional_34_Template, 20, 7, "aside", 24);
|
|
360
|
+
i0.ɵɵelementEnd();
|
|
361
|
+
i0.ɵɵelementStart(35, "div", 25);
|
|
362
|
+
i0.ɵɵtext(36);
|
|
363
|
+
i0.ɵɵelementEnd()();
|
|
364
|
+
} if (rf & 2) {
|
|
365
|
+
i0.ɵɵadvance(16);
|
|
366
|
+
i0.ɵɵclassProp("se-tab--active", ctx.Scope === "user");
|
|
367
|
+
i0.ɵɵadvance(4);
|
|
368
|
+
i0.ɵɵtextInterpolate(ctx.Counts.user);
|
|
369
|
+
i0.ɵɵadvance();
|
|
370
|
+
i0.ɵɵclassProp("se-tab--active", ctx.Scope === "instance");
|
|
371
|
+
i0.ɵɵadvance(4);
|
|
372
|
+
i0.ɵɵtextInterpolate(ctx.Counts.instance);
|
|
373
|
+
i0.ɵɵadvance(3);
|
|
374
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx.SearchQuery);
|
|
375
|
+
i0.ɵɵadvance();
|
|
376
|
+
i0.ɵɵconditional(ctx.SearchQuery ? 29 : -1);
|
|
377
|
+
i0.ɵɵadvance(3);
|
|
378
|
+
i0.ɵɵconditional(ctx.FilteredRows.length === 0 ? 32 : 33);
|
|
379
|
+
i0.ɵɵadvance(2);
|
|
380
|
+
i0.ɵɵconditional(ctx.Selected ? 34 : -1);
|
|
381
|
+
i0.ɵɵadvance(2);
|
|
382
|
+
i0.ɵɵtextInterpolate1("Refreshed ", ctx.LastRefreshedLabel);
|
|
383
|
+
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel], styles: ["[_nghost-%COMP%] { display: block; height: 100%; }\n\n.mj-inspector[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n\n\n.mj-inspector__header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.mj-inspector__header-icon[_ngcontent-%COMP%] {\n width: 36px; height: 36px;\n border-radius: 9px;\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: white;\n display: flex; align-items: center; justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n}\n.mj-inspector__header-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n letter-spacing: -0.2px;\n}\n.mj-inspector__header-sub[_ngcontent-%COMP%] {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n.mj-inspector__header-spacer[_ngcontent-%COMP%] { flex: 1; }\n.mj-inspector__header-actions[_ngcontent-%COMP%] {\n display: flex; gap: 6px;\n}\n.mj-inspector__btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: 7px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.15s;\n}\n.mj-inspector__btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__btn--success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-border-default));\n}\n\n\n\n.mj-inspector__body[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n.mj-inspector__sidebar[_ngcontent-%COMP%] {\n width: 220px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n overflow-y: auto;\n flex-shrink: 0;\n padding: 8px;\n}\n.mj-inspector__nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.12s;\n margin-bottom: 2px;\n font-family: inherit;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n text-align: left;\n width: 100%;\n}\n.mj-inspector__nav-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.mj-inspector__nav-item--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__nav-item--active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n}\n.mj-inspector__nav-icon[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n}\n.mj-inspector__nav-text[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n.mj-inspector__nav-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n}\n.mj-inspector__nav-desc[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n}\n.mj-inspector__nav-item--active[_ngcontent-%COMP%] .mj-inspector__nav-desc[_ngcontent-%COMP%] {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n}\n\n\n\n.mj-inspector__content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n.mj-inspector__content-head[_ngcontent-%COMP%] {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--mj-bg-surface-card);\n}\n.mj-inspector__content-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-inspector__content-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.mj-inspector__editor[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.mj-inspector__editor[_ngcontent-%COMP%] mj-code-editor[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: block;\n}\n\n\n\n.mj-inspector__empty[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n@media (max-width: 700px) {\n .mj-inspector__body[_ngcontent-%COMP%] { flex-direction: column; }\n .mj-inspector__sidebar[_ngcontent-%COMP%] {\n width: 100%;\n height: auto;\n max-height: 200px;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n .mj-inspector__nav-item[_ngcontent-%COMP%] { flex: 1 1 calc(50% - 8px); margin-bottom: 0; }\n .mj-inspector__nav-desc[_ngcontent-%COMP%] { display: none; }\n .mj-inspector__header[_ngcontent-%COMP%] { padding: 12px 14px; gap: 10px; }\n}", ".mj-inspector--solo[_ngcontent-%COMP%] { background: var(--mj-bg-page); }\n\n\n\n.se-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 10px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n}\n.se-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n background: var(--mj-bg-surface-sunken);\n padding: 3px;\n border-radius: 8px;\n}\n.se-tab[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n border-radius: 6px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12.5px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.15s;\n}\n.se-tab[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); }\n.se-tab--active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n}\n.se-count[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 10.5px;\n padding: 1px 7px;\n border-radius: 100px;\n font-weight: 600;\n}\n.se-tab--active[_ngcontent-%COMP%] .se-count[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.se-search-wrap[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n max-width: 360px;\n margin-left: auto;\n}\n.se-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n.se-search[_ngcontent-%COMP%] {\n width: 100%;\n padding: 7px 32px 7px 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12.5px;\n font-family: inherit;\n}\n.se-search[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.se-search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 22px;\n height: 22px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n}\n.se-search-clear[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n\n\n\n.se-body[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n.se-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n.se-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 12.5px;\n}\n.se-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n position: sticky;\n top: 0;\n z-index: 1;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 0 var(--mj-border-subtle);\n}\n.se-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 10px 18px;\n font-size: 10px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n.se-th-type[_ngcontent-%COMP%] { width: 100px; }\n.se-th-value[_ngcontent-%COMP%] { }\n.se-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 8px 18px;\n border-top: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n vertical-align: top;\n cursor: pointer;\n}\n.se-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.se-row--selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent) !important;\n}\n.se-row--selected[_ngcontent-%COMP%] td[_ngcontent-%COMP%]:first-child {\n box-shadow: inset 3px 0 0 var(--mj-brand-primary);\n}\n\n.se-td-key[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n padding: 2px 7px;\n border-radius: 5px;\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 11.5px;\n color: var(--mj-text-primary);\n}\n.se-td-meta[_ngcontent-%COMP%] {\n margin-top: 3px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.se-td-value[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 11.5px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 0;\n}\n\n.se-type-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 100px;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n.se-type-pill--string[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); }\n.se-type-pill--number[_ngcontent-%COMP%] { background: color-mix(in srgb, #7c3aed 14%, transparent); color: #5b21b6; }\n.se-type-pill--boolean[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 14%, transparent); color: color-mix(in srgb, var(--mj-status-success) 70%, var(--mj-text-primary)); }\n.se-type-pill--json[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 14%, transparent); color: color-mix(in srgb, var(--mj-status-warning) 70%, var(--mj-text-primary)); }\n.se-type-pill--empty[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n\n\n.se-detail[_ngcontent-%COMP%] {\n width: 420px;\n flex-shrink: 0;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n.se-detail-head[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.se-detail-key[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n word-break: break-all;\n}\n.se-detail-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n.se-detail-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n.mj-inspector__btn--ghost[_ngcontent-%COMP%] {\n background: transparent !important;\n border: 1px solid transparent !important;\n}\n.mj-inspector__btn--ghost[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover) !important;\n border-color: var(--mj-border-default) !important;\n}\n\n.se-detail-body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 14px 16px;\n}\n.se-detail-meta-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n}\n.se-detail-updated[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.se-detail-value[_ngcontent-%COMP%] {\n margin: 0;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 12px 14px;\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 100%;\n overflow: auto;\n}\n\n.se-empty[_ngcontent-%COMP%] {\n padding: 60px 40px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n}\n.se-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 28px; opacity: 0.7; }\n\n@media (max-width: 900px) {\n .se-body[_ngcontent-%COMP%] { flex-direction: column; }\n .se-detail[_ngcontent-%COMP%] { width: 100%; max-height: 50%; border-left: none; border-top: 1px solid var(--mj-border-default); }\n .se-toolbar[_ngcontent-%COMP%] { flex-direction: column; align-items: stretch; gap: 10px; }\n .se-search-wrap[_ngcontent-%COMP%] { max-width: 100%; }\n}"] });
|
|
384
|
+
};
|
|
385
|
+
SettingsExplorerComponent = __decorate([
|
|
386
|
+
RegisterClass(BaseResourceComponent, 'SettingsExplorerInspector')
|
|
387
|
+
], SettingsExplorerComponent);
|
|
388
|
+
export { SettingsExplorerComponent };
|
|
389
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SettingsExplorerComponent, [{
|
|
390
|
+
type: Component,
|
|
391
|
+
args: [{ standalone: false, selector: 'mj-settings-explorer', template: "<div class=\"mj-inspector mj-inspector--solo\">\n <div class=\"mj-inspector__header\">\n <div class=\"mj-inspector__header-icon\"><i class=\"fa-solid fa-sliders\"></i></div>\n <div>\n <h3 class=\"mj-inspector__header-title\">Settings Explorer</h3>\n <div class=\"mj-inspector__header-sub\">User settings and instance-level configuration</div>\n </div>\n <span class=\"mj-inspector__header-spacer\"></span>\n <div class=\"mj-inspector__header-actions\">\n <button class=\"mj-inspector__btn\" type=\"button\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\"></i> Refresh\n </button>\n </div>\n </div>\n\n <div class=\"se-toolbar\">\n <div class=\"se-tabs\">\n <button type=\"button\"\n class=\"se-tab\"\n [class.se-tab--active]=\"Scope === 'user'\"\n (click)=\"OnScopeChange('user')\">\n <i class=\"fa-solid fa-user\"></i>\n User Settings\n <span class=\"se-count\">{{ Counts.user }}</span>\n </button>\n <button type=\"button\"\n class=\"se-tab\"\n [class.se-tab--active]=\"Scope === 'instance'\"\n (click)=\"OnScopeChange('instance')\">\n <i class=\"fa-solid fa-server\"></i>\n Instance Configurations\n <span class=\"se-count\">{{ Counts.instance }}</span>\n </button>\n </div>\n <div class=\"se-search-wrap\">\n <i class=\"fa-solid fa-search se-search-icon\"></i>\n <input type=\"search\"\n class=\"se-search\"\n placeholder=\"Search keys or values\u2026\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"PersistPrefs()\" />\n @if (SearchQuery) {\n <button class=\"se-search-clear\" (click)=\"SearchQuery = ''\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n </div>\n\n <div class=\"se-body\">\n <div class=\"se-list\">\n @if (FilteredRows.length === 0) {\n <div class=\"se-empty\">\n @if (SearchQuery) {\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>No matches for \"{{ SearchQuery }}\"</span>\n } @else {\n <i class=\"fa-regular fa-folder-open\"></i>\n <span>No {{ Scope === 'user' ? 'user settings' : 'instance configurations' }} are defined.</span>\n }\n </div>\n } @else {\n <table class=\"se-table\">\n <thead>\n <tr>\n <th class=\"se-th-key\">Key</th>\n <th class=\"se-th-type\">Type</th>\n <th class=\"se-th-value\">Value</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRows; track TrackByKey($index, row)) {\n <tr [class.se-row--selected]=\"Selected?.key === row.key\"\n (click)=\"OnRowClick(row)\">\n <td class=\"se-td-key\">\n <code>{{ row.key }}</code>\n @if (row.meta) {\n <div class=\"se-td-meta\">{{ row.meta }}</div>\n }\n </td>\n <td class=\"se-td-type\">\n <span class=\"se-type-pill\" [class]=\"'se-type-pill--' + row.valueType\">\n {{ row.valueType }}\n </span>\n </td>\n <td class=\"se-td-value\">{{ row.preview }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n\n @if (Selected) {\n <aside class=\"se-detail\">\n <div class=\"se-detail-head\">\n <div>\n <div class=\"se-detail-key\">{{ Selected.key }}</div>\n @if (Selected.meta) {\n <div class=\"se-detail-meta\">{{ Selected.meta }}</div>\n }\n </div>\n <div class=\"se-detail-actions\">\n <button class=\"mj-inspector__btn\" (click)=\"OnCopySelected()\" title=\"Copy value\">\n <i class=\"fa-solid fa-clipboard\"></i> Copy\n </button>\n <button class=\"mj-inspector__btn mj-inspector__btn--ghost\" (click)=\"Selected = null\" title=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n <div class=\"se-detail-body\">\n <div class=\"se-detail-meta-row\">\n <span class=\"se-type-pill\" [class]=\"'se-type-pill--' + Selected.valueType\">{{ Selected.valueType }}</span>\n @if (Selected.updated) {\n <span class=\"se-detail-updated\">Updated {{ Selected.updated.toLocaleString() }}</span>\n }\n </div>\n <pre class=\"se-detail-value\"><code>{{ FormattedSelected || '(empty)' }}</code></pre>\n </div>\n </aside>\n }\n </div>\n\n <div class=\"mj-inspector__footer-meta\">Refreshed {{ LastRefreshedLabel }}</div>\n</div>\n", styles: [":host { display: block; height: 100%; }\n\n.mj-inspector {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n/* Header */\n.mj-inspector__header {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 14px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n}\n.mj-inspector__header-icon {\n width: 36px; height: 36px;\n border-radius: 9px;\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: white;\n display: flex; align-items: center; justify-content: center;\n font-size: 15px;\n flex-shrink: 0;\n}\n.mj-inspector__header-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n letter-spacing: -0.2px;\n}\n.mj-inspector__header-sub {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n.mj-inspector__header-spacer { flex: 1; }\n.mj-inspector__header-actions {\n display: flex; gap: 6px;\n}\n.mj-inspector__btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 7px 12px;\n border-radius: 7px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.15s;\n}\n.mj-inspector__btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__btn--success {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-border-default));\n}\n\n/* Layout: sidebar + content */\n.mj-inspector__body {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n.mj-inspector__sidebar {\n width: 220px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n overflow-y: auto;\n flex-shrink: 0;\n padding: 8px;\n}\n.mj-inspector__nav-item {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.12s;\n margin-bottom: 2px;\n font-family: inherit;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n text-align: left;\n width: 100%;\n}\n.mj-inspector__nav-item:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.mj-inspector__nav-item--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-inspector__nav-item--active:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n}\n.mj-inspector__nav-icon {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n}\n.mj-inspector__nav-text { flex: 1; min-width: 0; }\n.mj-inspector__nav-label {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n}\n.mj-inspector__nav-desc {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n}\n.mj-inspector__nav-item--active .mj-inspector__nav-desc {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n}\n\n/* Content area */\n.mj-inspector__content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n}\n.mj-inspector__content-head {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--mj-bg-surface-card);\n}\n.mj-inspector__content-title {\n margin: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-inspector__content-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.mj-inspector__editor {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.mj-inspector__editor mj-code-editor {\n flex: 1;\n min-height: 0;\n display: block;\n}\n\n/* Empty state */\n.mj-inspector__empty {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n@media (max-width: 700px) {\n .mj-inspector__body { flex-direction: column; }\n .mj-inspector__sidebar {\n width: 100%;\n height: auto;\n max-height: 200px;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n .mj-inspector__nav-item { flex: 1 1 calc(50% - 8px); margin-bottom: 0; }\n .mj-inspector__nav-desc { display: none; }\n .mj-inspector__header { padding: 12px 14px; gap: 10px; }\n}\n", ".mj-inspector--solo { background: var(--mj-bg-page); }\n\n/* Toolbar */\n.se-toolbar {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 10px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface);\n}\n.se-tabs {\n display: flex;\n gap: 2px;\n background: var(--mj-bg-surface-sunken);\n padding: 3px;\n border-radius: 8px;\n}\n.se-tab {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 6px 12px;\n border-radius: 6px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12.5px;\n font-weight: 500;\n cursor: pointer;\n font-family: inherit;\n transition: all 0.15s;\n}\n.se-tab:hover { color: var(--mj-text-primary); }\n.se-tab--active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n}\n.se-count {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 10.5px;\n padding: 1px 7px;\n border-radius: 100px;\n font-weight: 600;\n}\n.se-tab--active .se-count {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.se-search-wrap {\n position: relative;\n flex: 1;\n max-width: 360px;\n margin-left: auto;\n}\n.se-search-icon {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n}\n.se-search {\n width: 100%;\n padding: 7px 32px 7px 32px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12.5px;\n font-family: inherit;\n}\n.se-search:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n.se-search-clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n width: 22px;\n height: 22px;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n}\n.se-search-clear:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n\n/* Body */\n.se-body {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n.se-list {\n flex: 1;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n.se-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12.5px;\n}\n.se-table thead {\n position: sticky;\n top: 0;\n z-index: 1;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 0 var(--mj-border-subtle);\n}\n.se-table th {\n text-align: left;\n padding: 10px 18px;\n font-size: 10px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n.se-th-type { width: 100px; }\n.se-th-value { }\n.se-table td {\n padding: 8px 18px;\n border-top: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n vertical-align: top;\n cursor: pointer;\n}\n.se-table tbody tr:hover { background: var(--mj-bg-surface-hover); }\n.se-row--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent) !important;\n}\n.se-row--selected td:first-child {\n box-shadow: inset 3px 0 0 var(--mj-brand-primary);\n}\n\n.se-td-key code {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n padding: 2px 7px;\n border-radius: 5px;\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 11.5px;\n color: var(--mj-text-primary);\n}\n.se-td-meta {\n margin-top: 3px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.se-td-value {\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 11.5px;\n color: var(--mj-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n max-width: 0;\n}\n\n.se-type-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 10px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 100px;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n.se-type-pill--string { background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); color: var(--mj-brand-primary); }\n.se-type-pill--number { background: color-mix(in srgb, #7c3aed 14%, transparent); color: #5b21b6; }\n.se-type-pill--boolean { background: color-mix(in srgb, var(--mj-status-success) 14%, transparent); color: color-mix(in srgb, var(--mj-status-success) 70%, var(--mj-text-primary)); }\n.se-type-pill--json { background: color-mix(in srgb, var(--mj-status-warning) 14%, transparent); color: color-mix(in srgb, var(--mj-status-warning) 70%, var(--mj-text-primary)); }\n.se-type-pill--empty { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n/* Detail panel */\n.se-detail {\n width: 420px;\n flex-shrink: 0;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n.se-detail-head {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 12px;\n padding: 14px 16px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.se-detail-key {\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n word-break: break-all;\n}\n.se-detail-meta {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 4px;\n}\n.se-detail-actions {\n display: flex;\n gap: 4px;\n flex-shrink: 0;\n}\n.mj-inspector__btn--ghost {\n background: transparent !important;\n border: 1px solid transparent !important;\n}\n.mj-inspector__btn--ghost:hover {\n background: var(--mj-bg-surface-hover) !important;\n border-color: var(--mj-border-default) !important;\n}\n\n.se-detail-body {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 14px 16px;\n}\n.se-detail-meta-row {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n}\n.se-detail-updated {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n.se-detail-value {\n margin: 0;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 12px 14px;\n font-family: 'SF Mono', Menlo, Consolas, monospace;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-word;\n max-height: 100%;\n overflow: auto;\n}\n\n.se-empty {\n padding: 60px 40px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n}\n.se-empty i { font-size: 28px; opacity: 0.7; }\n\n@media (max-width: 900px) {\n .se-body { flex-direction: column; }\n .se-detail { width: 100%; max-height: 50%; border-left: none; border-top: 1px solid var(--mj-border-default); }\n .se-toolbar { flex-direction: column; align-items: stretch; gap: 10px; }\n .se-search-wrap { max-width: 100%; }\n}\n"] }]
|
|
392
|
+
}], () => [{ type: i0.ChangeDetectorRef }], null); })();
|
|
393
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SettingsExplorerComponent, { className: "SettingsExplorerComponent", filePath: "src/DevTools/settings-explorer.component.ts", lineNumber: 39 }); })();
|
|
394
|
+
//# sourceMappingURL=settings-explorer.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-explorer.component.js","sourceRoot":"","sources":["../../src/DevTools/settings-explorer.component.ts","../../src/DevTools/settings-explorer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { RegisterClass } from '@memberjunction/global';\nimport {\n UserInfoEngine,\n InstanceConfigEngine,\n MJUserSettingEntity,\n MJInstanceConfigurationEntity\n} from '@memberjunction/core-entities';\nimport { DevToolsPrefs } from './dev-tools-prefs';\n\ninterface SettingRow {\n key: string;\n rawValue: string;\n parsedValue: unknown;\n valueType: 'string' | 'number' | 'boolean' | 'json' | 'empty';\n /** Pretty preview shown in the table cell. */\n preview: string;\n /** Optional secondary metadata shown next to the key. */\n meta?: string;\n updated?: Date | null;\n}\n\ntype SettingsScope = 'user' | 'instance';\n\n/**\n * Settings Explorer — read-only browser for both `MJ: User Settings` (the\n * current user's per-app key/value bag) and `MJ: Instance Configurations`\n * (instance-level feature flags). Auto-detects JSON values, formats them\n * nicely, supports search + copy.\n */\n@RegisterClass(BaseResourceComponent, 'SettingsExplorerInspector')\n@Component({\n standalone: false,\n selector: 'mj-settings-explorer',\n templateUrl: './settings-explorer.component.html',\n styleUrls: ['./inspector-shared.css', './settings-explorer.component.css']\n})\nexport class SettingsExplorerComponent extends BaseResourceComponent implements OnInit, OnDestroy {\n\n public Scope: SettingsScope = 'user';\n public UserRows: SettingRow[] = [];\n public InstanceRows: SettingRow[] = [];\n public SearchQuery = '';\n public Selected: SettingRow | null = null;\n public LastRefreshed = new Date();\n\n public Counts = { user: 0, instance: 0 };\n\n constructor(private cdr: ChangeDetectorRef) {\n super();\n }\n\n public ngOnInit(): void {\n const p = DevToolsPrefs.Get<{ scope?: SettingsScope; search?: string }>('settingsExplorer');\n if (p?.scope) this.Scope = p.scope;\n if (p?.search) this.SearchQuery = p.search;\n this.refresh();\n this.NotifyLoadComplete();\n }\n\n public override ngOnDestroy(): void {\n DevToolsPrefs.Save('settingsExplorer', { scope: this.Scope, search: this.SearchQuery });\n super.ngOnDestroy();\n }\n\n public PersistPrefs(): void {\n DevToolsPrefs.Save('settingsExplorer', { scope: this.Scope, search: this.SearchQuery });\n }\n\n public override async GetResourceDisplayName(): Promise<string> { return 'Settings Explorer'; }\n public override async GetResourceIconClass(): Promise<string> { return 'fa-solid fa-sliders'; }\n\n public refresh(): void {\n const userSettings = UserInfoEngine.Instance.UserSettings ?? [];\n this.UserRows = userSettings.map(s => this.toRow(s.Setting ?? '(no key)', s.Value ?? '', s.User ? `User: ${s.User}` : undefined, s.__mj_UpdatedAt));\n\n const instanceConfigs = InstanceConfigEngine.Instance.InstanceConfigs ?? [];\n this.InstanceRows = instanceConfigs.map(c => this.toRow(\n c.FeatureKey ?? '(no key)',\n c.Value ?? '',\n this.buildInstanceMeta(c),\n c.__mj_UpdatedAt\n ));\n\n this.Counts = { user: this.UserRows.length, instance: this.InstanceRows.length };\n\n // Sort each list by key\n this.UserRows.sort((a, b) => a.key.localeCompare(b.key));\n this.InstanceRows.sort((a, b) => a.key.localeCompare(b.key));\n\n // Re-resolve selection if it still exists\n if (this.Selected) {\n const list = this.Scope === 'user' ? this.UserRows : this.InstanceRows;\n this.Selected = list.find(r => r.key === this.Selected!.key) ?? null;\n }\n\n this.LastRefreshed = new Date();\n this.cdr.markForCheck();\n }\n\n public OnScopeChange(scope: SettingsScope): void {\n this.Scope = scope;\n this.Selected = null;\n this.PersistPrefs();\n }\n\n public get FilteredRows(): SettingRow[] {\n const list = this.Scope === 'user' ? this.UserRows : this.InstanceRows;\n const q = this.SearchQuery.trim().toLowerCase();\n if (!q) return list;\n return list.filter(r => r.key.toLowerCase().includes(q) || r.rawValue.toLowerCase().includes(q));\n }\n\n public OnRowClick(row: SettingRow): void {\n this.Selected = this.Selected?.key === row.key ? null : row;\n }\n\n public async OnCopySelected(): Promise<void> {\n if (!this.Selected) return;\n const text = this.Selected.valueType === 'json'\n ? JSON.stringify(this.Selected.parsedValue, null, 2)\n : this.Selected.rawValue;\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n // unavailable\n }\n }\n\n public get LastRefreshedLabel(): string {\n return this.LastRefreshed.toLocaleTimeString();\n }\n\n public get FormattedSelected(): string {\n if (!this.Selected) return '';\n if (this.Selected.valueType === 'json') {\n return JSON.stringify(this.Selected.parsedValue, null, 2);\n }\n return this.Selected.rawValue;\n }\n\n public TrackByKey = (_i: number, r: SettingRow) => r.key;\n\n // ---------- private ----------\n\n private buildInstanceMeta(c: MJInstanceConfigurationEntity): string | undefined {\n const parts: string[] = [];\n if (c.Category) parts.push(c.Category);\n if (c.DisplayName && c.DisplayName !== c.FeatureKey) parts.push(c.DisplayName);\n return parts.length ? parts.join(' · ') : undefined;\n }\n\n private toRow(key: string, rawValue: string, meta: string | undefined, updated: Date | string | null | undefined): SettingRow {\n const raw = rawValue ?? '';\n let valueType: SettingRow['valueType'] = 'string';\n let parsedValue: unknown = raw;\n let preview = raw;\n\n if (raw === '') {\n valueType = 'empty';\n preview = '(empty)';\n } else if (raw === 'true' || raw === 'false') {\n valueType = 'boolean';\n parsedValue = raw === 'true';\n } else if (/^-?\\d+(\\.\\d+)?$/.test(raw) && raw.length < 20) {\n valueType = 'number';\n parsedValue = Number(raw);\n } else if ((raw.startsWith('{') && raw.endsWith('}')) || (raw.startsWith('[') && raw.endsWith(']'))) {\n try {\n parsedValue = JSON.parse(raw);\n valueType = 'json';\n preview = this.summarizeJson(parsedValue);\n } catch {\n // not actually JSON — leave as string\n }\n }\n\n if (preview.length > 80) preview = preview.slice(0, 77) + '…';\n\n return {\n key,\n rawValue: raw,\n parsedValue,\n valueType,\n preview,\n meta,\n updated: updated ? (updated instanceof Date ? updated : new Date(updated)) : null\n };\n }\n\n private summarizeJson(value: unknown): string {\n if (Array.isArray(value)) return `[ ${value.length} item${value.length === 1 ? '' : 's'} ]`;\n if (value && typeof value === 'object') {\n const keys = Object.keys(value as Record<string, unknown>);\n if (keys.length === 0) return '{ }';\n return `{ ${keys.slice(0, 3).join(', ')}${keys.length > 3 ? ', …' : ''} }`;\n }\n return String(value);\n }\n}\n","<div class=\"mj-inspector mj-inspector--solo\">\n <div class=\"mj-inspector__header\">\n <div class=\"mj-inspector__header-icon\"><i class=\"fa-solid fa-sliders\"></i></div>\n <div>\n <h3 class=\"mj-inspector__header-title\">Settings Explorer</h3>\n <div class=\"mj-inspector__header-sub\">User settings and instance-level configuration</div>\n </div>\n <span class=\"mj-inspector__header-spacer\"></span>\n <div class=\"mj-inspector__header-actions\">\n <button class=\"mj-inspector__btn\" type=\"button\" (click)=\"refresh()\" title=\"Refresh\">\n <i class=\"fa-solid fa-rotate\"></i> Refresh\n </button>\n </div>\n </div>\n\n <div class=\"se-toolbar\">\n <div class=\"se-tabs\">\n <button type=\"button\"\n class=\"se-tab\"\n [class.se-tab--active]=\"Scope === 'user'\"\n (click)=\"OnScopeChange('user')\">\n <i class=\"fa-solid fa-user\"></i>\n User Settings\n <span class=\"se-count\">{{ Counts.user }}</span>\n </button>\n <button type=\"button\"\n class=\"se-tab\"\n [class.se-tab--active]=\"Scope === 'instance'\"\n (click)=\"OnScopeChange('instance')\">\n <i class=\"fa-solid fa-server\"></i>\n Instance Configurations\n <span class=\"se-count\">{{ Counts.instance }}</span>\n </button>\n </div>\n <div class=\"se-search-wrap\">\n <i class=\"fa-solid fa-search se-search-icon\"></i>\n <input type=\"search\"\n class=\"se-search\"\n placeholder=\"Search keys or values…\"\n [(ngModel)]=\"SearchQuery\"\n (ngModelChange)=\"PersistPrefs()\" />\n @if (SearchQuery) {\n <button class=\"se-search-clear\" (click)=\"SearchQuery = ''\" title=\"Clear\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n </div>\n\n <div class=\"se-body\">\n <div class=\"se-list\">\n @if (FilteredRows.length === 0) {\n <div class=\"se-empty\">\n @if (SearchQuery) {\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span>No matches for \"{{ SearchQuery }}\"</span>\n } @else {\n <i class=\"fa-regular fa-folder-open\"></i>\n <span>No {{ Scope === 'user' ? 'user settings' : 'instance configurations' }} are defined.</span>\n }\n </div>\n } @else {\n <table class=\"se-table\">\n <thead>\n <tr>\n <th class=\"se-th-key\">Key</th>\n <th class=\"se-th-type\">Type</th>\n <th class=\"se-th-value\">Value</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRows; track TrackByKey($index, row)) {\n <tr [class.se-row--selected]=\"Selected?.key === row.key\"\n (click)=\"OnRowClick(row)\">\n <td class=\"se-td-key\">\n <code>{{ row.key }}</code>\n @if (row.meta) {\n <div class=\"se-td-meta\">{{ row.meta }}</div>\n }\n </td>\n <td class=\"se-td-type\">\n <span class=\"se-type-pill\" [class]=\"'se-type-pill--' + row.valueType\">\n {{ row.valueType }}\n </span>\n </td>\n <td class=\"se-td-value\">{{ row.preview }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n\n @if (Selected) {\n <aside class=\"se-detail\">\n <div class=\"se-detail-head\">\n <div>\n <div class=\"se-detail-key\">{{ Selected.key }}</div>\n @if (Selected.meta) {\n <div class=\"se-detail-meta\">{{ Selected.meta }}</div>\n }\n </div>\n <div class=\"se-detail-actions\">\n <button class=\"mj-inspector__btn\" (click)=\"OnCopySelected()\" title=\"Copy value\">\n <i class=\"fa-solid fa-clipboard\"></i> Copy\n </button>\n <button class=\"mj-inspector__btn mj-inspector__btn--ghost\" (click)=\"Selected = null\" title=\"Close\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n <div class=\"se-detail-body\">\n <div class=\"se-detail-meta-row\">\n <span class=\"se-type-pill\" [class]=\"'se-type-pill--' + Selected.valueType\">{{ Selected.valueType }}</span>\n @if (Selected.updated) {\n <span class=\"se-detail-updated\">Updated {{ Selected.updated.toLocaleString() }}</span>\n }\n </div>\n <pre class=\"se-detail-value\"><code>{{ FormattedSelected || '(empty)' }}</code></pre>\n </div>\n </aside>\n }\n </div>\n\n <div class=\"mj-inspector__footer-meta\">Refreshed {{ LastRefreshedLabel }}</div>\n</div>\n"]}
|