@solidxai/core-ui 0.1.8 → 0.1.9-beta.1
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/components/core/common/SolidAccountSettings/SolidAccountSettings.module.css +149 -0
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.d.ts.map +1 -1
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.js +21 -4
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.js.map +1 -1
- package/dist/components/core/common/SolidAccountSettings/SolidVersionInfo.tsx +128 -1
- package/dist/components/core/form/SolidFormActionHeader.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormActionHeader.js +4 -2
- package/dist/components/core/form/SolidFormActionHeader.js.map +1 -1
- package/dist/components/core/form/SolidFormActionHeader.tsx +4 -2
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +2 -2
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +2 -2
- package/dist/components/core/list/SolidListViewConfigure.d.ts.map +1 -1
- package/dist/components/core/list/SolidListViewConfigure.js +31 -2
- package/dist/components/core/list/SolidListViewConfigure.js.map +1 -1
- package/dist/components/core/list/SolidListViewConfigure.tsx +34 -2
- package/dist/components/layout/user-profile-menu.d.ts.map +1 -1
- package/dist/components/layout/user-profile-menu.js +2 -1
- package/dist/components/layout/user-profile-menu.js.map +1 -1
- package/dist/components/layout/user-profile-menu.tsx +22 -27
- package/dist/components/shad-cn-ui/SolidButton.d.ts +14 -15
- package/dist/components/shad-cn-ui/SolidButton.d.ts.map +1 -1
- package/dist/components/shad-cn-ui/SolidButton.js +13 -3
- package/dist/components/shad-cn-ui/SolidButton.js.map +1 -1
- package/dist/components/shad-cn-ui/SolidButton.tsx +24 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.ts +1 -0
- package/dist/redux/api/solidEntityApi.d.ts.map +1 -1
- package/dist/redux/api/solidEntityApi.js +13 -0
- package/dist/redux/api/solidEntityApi.js.map +1 -1
- package/dist/redux/api/solidEntityApi.tsx +16 -0
- package/dist/redux/store/createSolidStore.d.ts +1 -1
- package/dist/redux/store/createSolidStore.d.ts.map +1 -1
- package/dist/redux/store/createSolidStore.js +20 -11
- package/dist/redux/store/createSolidStore.js.map +1 -1
- package/dist/redux/store/createSolidStore.ts +20 -11
- package/dist/redux/store/dynamicEntityApiMiddleware.d.ts +10 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.d.ts.map +1 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.js +44 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.js.map +1 -0
- package/dist/redux/store/dynamicEntityApiMiddleware.ts +58 -0
- package/dist/redux/store/dynamicReducerManager.d.ts +10 -0
- package/dist/redux/store/dynamicReducerManager.d.ts.map +1 -0
- package/dist/redux/store/dynamicReducerManager.js +51 -0
- package/dist/redux/store/dynamicReducerManager.js.map +1 -0
- package/dist/redux/store/dynamicReducerManager.ts +51 -0
- package/dist/redux/store/solidEntityApiPool.d.ts +31 -0
- package/dist/redux/store/solidEntityApiPool.d.ts.map +1 -0
- package/dist/redux/store/solidEntityApiPool.js +123 -0
- package/dist/redux/store/solidEntityApiPool.js.map +1 -0
- package/dist/redux/store/solidEntityApiPool.ts +167 -0
- package/dist/resources/globals.css +7 -1
- package/dist/resources/shadcn-base.css +8 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.d.ts +2 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.d.ts.map +1 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.js +48 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.js.map +1 -0
- package/dist/routes/pages/admin/core/DiagnosticsPage.tsx +167 -0
- package/package.json +1 -1
|
@@ -2753,6 +2753,10 @@ li.header-li-px {
|
|
|
2753
2753
|
height: auto;
|
|
2754
2754
|
}
|
|
2755
2755
|
|
|
2756
|
+
.solid-custom-filter-wrapper {
|
|
2757
|
+
z-index: 85;
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2756
2760
|
.custom-filter-button {
|
|
2757
2761
|
border-right: 0;
|
|
2758
2762
|
border-top: 0;
|
|
@@ -2897,6 +2901,7 @@ li.header-li-px {
|
|
|
2897
2901
|
.solid-chip-manager-panel {
|
|
2898
2902
|
top: calc(100% + 6px);
|
|
2899
2903
|
left: 0;
|
|
2904
|
+
z-index: 90 !important;
|
|
2900
2905
|
width: min(360px, 100%);
|
|
2901
2906
|
background: var(--card);
|
|
2902
2907
|
border: 1px solid color-mix(in srgb, var(--border) 86%, transparent);
|
|
@@ -3880,7 +3885,8 @@ li.header-li-px {
|
|
|
3880
3885
|
|
|
3881
3886
|
.solid-search-overlay-pannel {
|
|
3882
3887
|
top: calc(100% + 4px) !important;
|
|
3883
|
-
|
|
3888
|
+
/* Keep above datatable sticky headers/columns and other elevated surfaces. */
|
|
3889
|
+
z-index: 1004 !important;
|
|
3884
3890
|
background: var(--card);
|
|
3885
3891
|
border: 1px solid color-mix(in srgb, var(--border) 86%, transparent) !important;
|
|
3886
3892
|
border-radius: 10px;
|
|
@@ -1351,6 +1351,7 @@ body {
|
|
|
1351
1351
|
.solid-autocomplete {
|
|
1352
1352
|
position: relative;
|
|
1353
1353
|
width: 100%;
|
|
1354
|
+
min-width: 0;
|
|
1354
1355
|
}
|
|
1355
1356
|
|
|
1356
1357
|
.solid-autocomplete-control {
|
|
@@ -1358,6 +1359,7 @@ body {
|
|
|
1358
1359
|
display: flex;
|
|
1359
1360
|
align-items: center;
|
|
1360
1361
|
width: 100%;
|
|
1362
|
+
min-width: 0;
|
|
1361
1363
|
}
|
|
1362
1364
|
|
|
1363
1365
|
.solid-autocomplete-chip-control {
|
|
@@ -1385,6 +1387,8 @@ body {
|
|
|
1385
1387
|
min-height: 24px;
|
|
1386
1388
|
height: 24px;
|
|
1387
1389
|
flex: 1 1 110px;
|
|
1390
|
+
min-width: 0;
|
|
1391
|
+
max-width: 100%;
|
|
1388
1392
|
padding: 0 4px;
|
|
1389
1393
|
}
|
|
1390
1394
|
|
|
@@ -1458,6 +1462,8 @@ body {
|
|
|
1458
1462
|
align-items: center;
|
|
1459
1463
|
gap: 4px;
|
|
1460
1464
|
min-height: 22px;
|
|
1465
|
+
min-width: 0;
|
|
1466
|
+
max-width: 100%;
|
|
1461
1467
|
border-radius: 999px;
|
|
1462
1468
|
border: 1px solid color-mix(in srgb, var(--primary) 24%, transparent);
|
|
1463
1469
|
background: color-mix(in srgb, var(--primary) 10%, transparent);
|
|
@@ -1467,6 +1473,8 @@ body {
|
|
|
1467
1473
|
}
|
|
1468
1474
|
|
|
1469
1475
|
.solid-autocomplete-chip-label {
|
|
1476
|
+
min-width: 0;
|
|
1477
|
+
max-width: 100%;
|
|
1470
1478
|
overflow: hidden;
|
|
1471
1479
|
text-overflow: ellipsis;
|
|
1472
1480
|
white-space: nowrap;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiagnosticsPage.d.ts","sourceRoot":"","sources":["../../../../../src/routes/pages/admin/core/DiagnosticsPage.tsx"],"names":[],"mappings":"AAsBA,wBAAgB,eAAe,4CAgJ9B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from "react";
|
|
3
|
+
import { env } from "../../../../adapters/env";
|
|
4
|
+
import { loadSession } from "../../../../adapters/auth/storage";
|
|
5
|
+
import { hasAnyRole } from "../../../../helpers/rolesHelper";
|
|
6
|
+
import { useSession } from "../../../../hooks/useSession";
|
|
7
|
+
import { getSolidEntityApiPoolSnapshot, SOLID_ENTITY_API_POOL_LIMIT } from "../../../../redux/store/solidEntityApiPool";
|
|
8
|
+
import { SolidButton } from "../../../../components/shad-cn-ui/SolidButton";
|
|
9
|
+
var ALLOWED_ENVIRONMENTS = new Set([
|
|
10
|
+
"dev",
|
|
11
|
+
"development",
|
|
12
|
+
"staging",
|
|
13
|
+
"stage",
|
|
14
|
+
"uat",
|
|
15
|
+
"test",
|
|
16
|
+
"local",
|
|
17
|
+
]);
|
|
18
|
+
function toDisplayTime(counter) {
|
|
19
|
+
return "#".concat(counter);
|
|
20
|
+
}
|
|
21
|
+
export function DiagnosticsPage() {
|
|
22
|
+
var _a, _b, _c, _d;
|
|
23
|
+
var _e = useSession(), session = _e.data, status = _e.status;
|
|
24
|
+
var _f = useState(0), refreshTick = _f[0], setRefreshTick = _f[1];
|
|
25
|
+
var envName = (env("VITE_SOLIDX_ENV") || "unknown").toLowerCase();
|
|
26
|
+
var diagnosticsEnabled = ALLOWED_ENVIRONMENTS.has(envName);
|
|
27
|
+
var isAdmin = hasAnyRole((_a = session === null || session === void 0 ? void 0 : session.user) === null || _a === void 0 ? void 0 : _a.roles, ["Admin"]);
|
|
28
|
+
var poolSnapshot = useMemo(function () {
|
|
29
|
+
refreshTick;
|
|
30
|
+
return getSolidEntityApiPoolSnapshot();
|
|
31
|
+
}, [refreshTick]);
|
|
32
|
+
var activeCount = poolSnapshot.filter(function (entry) { return entry.active; }).length;
|
|
33
|
+
var cachedCount = poolSnapshot.length;
|
|
34
|
+
var loginRedirect = env("NEXT_PUBLIC_LOGIN_REDIRECT_URL") || "/admin";
|
|
35
|
+
var backendApi = env("NEXT_PUBLIC_BACKEND_API_URL") || env("API_URL", "");
|
|
36
|
+
var localSession = loadSession();
|
|
37
|
+
if (status === "loading") {
|
|
38
|
+
return (_jsx("div", { className: "solid-studio-home", children: _jsx("div", { className: "solid-studio-home-inner solid-studio-home-inner--wider", children: _jsx("div", { className: "solid-studio-card", children: _jsx("div", { className: "solid-studio-card-content", children: "Loading diagnostics..." }) }) }) }));
|
|
39
|
+
}
|
|
40
|
+
if (!isAdmin) {
|
|
41
|
+
return (_jsx("div", { className: "solid-studio-home", children: _jsx("div", { className: "solid-studio-home-inner solid-studio-home-inner--wider", children: _jsx("div", { className: "solid-studio-card", children: _jsxs("div", { className: "solid-studio-card-header", children: [_jsx("h3", { className: "solid-studio-card-title", children: "Diagnostics Access Restricted" }), _jsx("p", { className: "solid-studio-card-description", children: "You do not have permission to view this diagnostics page." })] }) }) }) }));
|
|
42
|
+
}
|
|
43
|
+
if (!diagnosticsEnabled) {
|
|
44
|
+
return (_jsx("div", { className: "solid-studio-home", children: _jsx("div", { className: "solid-studio-home-inner solid-studio-home-inner--wider", children: _jsx("div", { className: "solid-studio-card", children: _jsxs("div", { className: "solid-studio-card-header", children: [_jsx("h3", { className: "solid-studio-card-title", children: "Diagnostics Disabled" }), _jsxs("p", { className: "solid-studio-card-description", children: ["Diagnostics are enabled only in dev/staging-style environments. Current environment: ", _jsx("code", { children: envName }), "."] })] }) }) }) }));
|
|
45
|
+
}
|
|
46
|
+
return (_jsx("div", { className: "solid-studio-home solid-studio-home--top", children: _jsxs("div", { className: "solid-studio-home-inner solid-studio-home-inner--wider", children: [_jsxs("div", { className: "solid-studio-home-toolbar", style: { marginBottom: "14px" }, children: [_jsx("div", { className: "solid-studio-home-toolbar-left", children: _jsxs("div", { className: "solid-studio-home-heading", children: [_jsx("div", { className: "solid-studio-home-badge", children: "Diagnostics" }), _jsx("h1", { children: "SolidX Runtime Diagnostics" }), _jsx("p", { children: "Read-only runtime snapshot for support and debugging." })] }) }), _jsx("div", { className: "solid-studio-home-toolbar-right", children: _jsx(SolidButton, { size: "sm", variant: "outline", onClick: function () { return setRefreshTick(function (v) { return v + 1; }); }, children: "Refresh" }) })] }), _jsxs("div", { className: "solid-studio-card", style: { marginBottom: "14px" }, children: [_jsx("div", { className: "solid-studio-card-header", children: _jsx("h3", { className: "solid-studio-card-title", children: "Runtime" }) }), _jsx("div", { className: "solid-studio-card-content", children: _jsxs("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))", gap: "10px" }, children: [_jsxs("div", { children: [_jsx("strong", { children: "Environment:" }), " ", envName] }), _jsxs("div", { children: [_jsx("strong", { children: "Pool Limit:" }), " ", SOLID_ENTITY_API_POOL_LIMIT] }), _jsxs("div", { children: [_jsx("strong", { children: "Active Entity APIs:" }), " ", activeCount] }), _jsxs("div", { children: [_jsx("strong", { children: "Cached Entity APIs:" }), " ", cachedCount] }), _jsxs("div", { children: [_jsx("strong", { children: "Login Redirect:" }), " ", loginRedirect] }), _jsxs("div", { children: [_jsx("strong", { children: "Backend API:" }), " ", backendApi || "(not set)"] }), _jsxs("div", { children: [_jsx("strong", { children: "User:" }), " ", ((_b = localSession === null || localSession === void 0 ? void 0 : localSession.user) === null || _b === void 0 ? void 0 : _b.email) || ((_c = localSession === null || localSession === void 0 ? void 0 : localSession.user) === null || _c === void 0 ? void 0 : _c.name) || "(unknown)"] }), _jsxs("div", { children: [_jsx("strong", { children: "Roles:" }), " ", (((_d = localSession === null || localSession === void 0 ? void 0 : localSession.user) === null || _d === void 0 ? void 0 : _d.roles) || []).map(function (r) { return r.name || r; }).join(", ") || "(none)"] })] }) })] }), _jsxs("div", { className: "solid-studio-card", children: [_jsxs("div", { className: "solid-studio-card-header", children: [_jsx("h3", { className: "solid-studio-card-title", children: "Entity API Pool" }), _jsx("p", { className: "solid-studio-card-description", children: "Each entry represents a lazily created entity API. Active entries have reducer+middleware currently registered." })] }), _jsx("div", { className: "solid-studio-card-content", style: { overflowX: "auto" }, children: _jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: "13px" }, children: [_jsx("thead", { children: _jsxs("tr", { style: { borderBottom: "1px solid rgba(148, 163, 184, 0.35)" }, children: [_jsx("th", { style: { textAlign: "left", padding: "8px" }, children: "Entity" }), _jsx("th", { style: { textAlign: "left", padding: "8px" }, children: "Reducer Path" }), _jsx("th", { style: { textAlign: "left", padding: "8px" }, children: "Registered" }), _jsx("th", { style: { textAlign: "left", padding: "8px" }, children: "Last Accessed" }), _jsx("th", { style: { textAlign: "left", padding: "8px" }, children: "Active" })] }) }), _jsx("tbody", { children: poolSnapshot.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: 5, style: { padding: "12px", opacity: 0.7 }, children: "No entity APIs have been created in this session yet." }) })) : (poolSnapshot.map(function (entry) { return (_jsxs("tr", { style: { borderBottom: "1px solid rgba(148, 163, 184, 0.2)" }, children: [_jsx("td", { style: { padding: "8px" }, children: entry.entityName }), _jsx("td", { style: { padding: "8px", fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace" }, children: entry.reducerPath }), _jsx("td", { style: { padding: "8px" }, children: toDisplayTime(entry.registeredAt) }), _jsx("td", { style: { padding: "8px" }, children: toDisplayTime(entry.lastAccessedAt) }), _jsx("td", { style: { padding: "8px" }, children: entry.active ? "yes" : "no" })] }, entry.reducerPath)); })) })] }) })] })] }) }));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=DiagnosticsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiagnosticsPage.js","sourceRoot":"","sources":["../../../../../src/routes/pages/admin/core/DiagnosticsPage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo, useState } from \"react\";\nimport { env } from \"../../../../adapters/env\";\nimport { loadSession } from \"../../../../adapters/auth/storage\";\nimport { hasAnyRole } from \"../../../../helpers/rolesHelper\";\nimport { useSession } from \"../../../../hooks/useSession\";\nimport { getSolidEntityApiPoolSnapshot, SOLID_ENTITY_API_POOL_LIMIT } from \"../../../../redux/store/solidEntityApiPool\";\nimport { SolidButton } from \"../../../../components/shad-cn-ui/SolidButton\";\n\nconst ALLOWED_ENVIRONMENTS = new Set([\n \"dev\",\n \"development\",\n \"staging\",\n \"stage\",\n \"uat\",\n \"test\",\n \"local\",\n]);\n\nfunction toDisplayTime(counter: number) {\n return `#${counter}`;\n}\n\nexport function DiagnosticsPage() {\n const { data: session, status } = useSession();\n const [refreshTick, setRefreshTick] = useState(0);\n\n const envName = (env(\"VITE_SOLIDX_ENV\") || \"unknown\").toLowerCase();\n const diagnosticsEnabled = ALLOWED_ENVIRONMENTS.has(envName);\n const isAdmin = hasAnyRole(session?.user?.roles, [\"Admin\"]);\n\n const poolSnapshot = useMemo(() => {\n refreshTick;\n return getSolidEntityApiPoolSnapshot();\n }, [refreshTick]);\n\n const activeCount = poolSnapshot.filter((entry) => entry.active).length;\n const cachedCount = poolSnapshot.length;\n const loginRedirect = env(\"NEXT_PUBLIC_LOGIN_REDIRECT_URL\") || \"/admin\";\n const backendApi = env(\"NEXT_PUBLIC_BACKEND_API_URL\") || env(\"API_URL\", \"\");\n const localSession = loadSession();\n\n if (status === \"loading\") {\n return (\n <div className=\"solid-studio-home\">\n <div className=\"solid-studio-home-inner solid-studio-home-inner--wider\">\n <div className=\"solid-studio-card\">\n <div className=\"solid-studio-card-content\">Loading diagnostics...</div>\n </div>\n </div>\n </div>\n );\n }\n\n if (!isAdmin) {\n return (\n <div className=\"solid-studio-home\">\n <div className=\"solid-studio-home-inner solid-studio-home-inner--wider\">\n <div className=\"solid-studio-card\">\n <div className=\"solid-studio-card-header\">\n <h3 className=\"solid-studio-card-title\">Diagnostics Access Restricted</h3>\n <p className=\"solid-studio-card-description\">\n You do not have permission to view this diagnostics page.\n </p>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n if (!diagnosticsEnabled) {\n return (\n <div className=\"solid-studio-home\">\n <div className=\"solid-studio-home-inner solid-studio-home-inner--wider\">\n <div className=\"solid-studio-card\">\n <div className=\"solid-studio-card-header\">\n <h3 className=\"solid-studio-card-title\">Diagnostics Disabled</h3>\n <p className=\"solid-studio-card-description\">\n Diagnostics are enabled only in dev/staging-style environments. Current environment: <code>{envName}</code>.\n </p>\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"solid-studio-home solid-studio-home--top\">\n <div className=\"solid-studio-home-inner solid-studio-home-inner--wider\">\n <div className=\"solid-studio-home-toolbar\" style={{ marginBottom: \"14px\" }}>\n <div className=\"solid-studio-home-toolbar-left\">\n <div className=\"solid-studio-home-heading\">\n <div className=\"solid-studio-home-badge\">Diagnostics</div>\n <h1>SolidX Runtime Diagnostics</h1>\n <p>Read-only runtime snapshot for support and debugging.</p>\n </div>\n </div>\n <div className=\"solid-studio-home-toolbar-right\">\n <SolidButton size=\"sm\" variant=\"outline\" onClick={() => setRefreshTick((v) => v + 1)}>\n Refresh\n </SolidButton>\n </div>\n </div>\n\n <div className=\"solid-studio-card\" style={{ marginBottom: \"14px\" }}>\n <div className=\"solid-studio-card-header\">\n <h3 className=\"solid-studio-card-title\">Runtime</h3>\n </div>\n <div className=\"solid-studio-card-content\">\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit, minmax(220px, 1fr))\", gap: \"10px\" }}>\n <div><strong>Environment:</strong> {envName}</div>\n <div><strong>Pool Limit:</strong> {SOLID_ENTITY_API_POOL_LIMIT}</div>\n <div><strong>Active Entity APIs:</strong> {activeCount}</div>\n <div><strong>Cached Entity APIs:</strong> {cachedCount}</div>\n <div><strong>Login Redirect:</strong> {loginRedirect}</div>\n <div><strong>Backend API:</strong> {backendApi || \"(not set)\"}</div>\n <div><strong>User:</strong> {localSession?.user?.email || localSession?.user?.name || \"(unknown)\"}</div>\n <div><strong>Roles:</strong> {(localSession?.user?.roles || []).map((r: any) => r.name || r).join(\", \") || \"(none)\"}</div>\n </div>\n </div>\n </div>\n\n <div className=\"solid-studio-card\">\n <div className=\"solid-studio-card-header\">\n <h3 className=\"solid-studio-card-title\">Entity API Pool</h3>\n <p className=\"solid-studio-card-description\">\n Each entry represents a lazily created entity API. Active entries have reducer+middleware currently registered.\n </p>\n </div>\n <div className=\"solid-studio-card-content\" style={{ overflowX: \"auto\" }}>\n <table style={{ width: \"100%\", borderCollapse: \"collapse\", fontSize: \"13px\" }}>\n <thead>\n <tr style={{ borderBottom: \"1px solid rgba(148, 163, 184, 0.35)\" }}>\n <th style={{ textAlign: \"left\", padding: \"8px\" }}>Entity</th>\n <th style={{ textAlign: \"left\", padding: \"8px\" }}>Reducer Path</th>\n <th style={{ textAlign: \"left\", padding: \"8px\" }}>Registered</th>\n <th style={{ textAlign: \"left\", padding: \"8px\" }}>Last Accessed</th>\n <th style={{ textAlign: \"left\", padding: \"8px\" }}>Active</th>\n </tr>\n </thead>\n <tbody>\n {poolSnapshot.length === 0 ? (\n <tr>\n <td colSpan={5} style={{ padding: \"12px\", opacity: 0.7 }}>\n No entity APIs have been created in this session yet.\n </td>\n </tr>\n ) : (\n poolSnapshot.map((entry) => (\n <tr key={entry.reducerPath} style={{ borderBottom: \"1px solid rgba(148, 163, 184, 0.2)\" }}>\n <td style={{ padding: \"8px\" }}>{entry.entityName}</td>\n <td style={{ padding: \"8px\", fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\" }}>{entry.reducerPath}</td>\n <td style={{ padding: \"8px\" }}>{toDisplayTime(entry.registeredAt)}</td>\n <td style={{ padding: \"8px\" }}>{toDisplayTime(entry.lastAccessedAt)}</td>\n <td style={{ padding: \"8px\" }}>{entry.active ? \"yes\" : \"no\"}</td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { useMemo, useState } from "react";
|
|
2
|
+
import { env } from "../../../../adapters/env";
|
|
3
|
+
import { loadSession } from "../../../../adapters/auth/storage";
|
|
4
|
+
import { hasAnyRole } from "../../../../helpers/rolesHelper";
|
|
5
|
+
import { useSession } from "../../../../hooks/useSession";
|
|
6
|
+
import { getSolidEntityApiPoolSnapshot, SOLID_ENTITY_API_POOL_LIMIT } from "../../../../redux/store/solidEntityApiPool";
|
|
7
|
+
import { SolidButton } from "../../../../components/shad-cn-ui/SolidButton";
|
|
8
|
+
|
|
9
|
+
const ALLOWED_ENVIRONMENTS = new Set([
|
|
10
|
+
"dev",
|
|
11
|
+
"development",
|
|
12
|
+
"staging",
|
|
13
|
+
"stage",
|
|
14
|
+
"uat",
|
|
15
|
+
"test",
|
|
16
|
+
"local",
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
function toDisplayTime(counter: number) {
|
|
20
|
+
return `#${counter}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function DiagnosticsPage() {
|
|
24
|
+
const { data: session, status } = useSession();
|
|
25
|
+
const [refreshTick, setRefreshTick] = useState(0);
|
|
26
|
+
|
|
27
|
+
const envName = (env("VITE_SOLIDX_ENV") || "unknown").toLowerCase();
|
|
28
|
+
const diagnosticsEnabled = ALLOWED_ENVIRONMENTS.has(envName);
|
|
29
|
+
const isAdmin = hasAnyRole(session?.user?.roles, ["Admin"]);
|
|
30
|
+
|
|
31
|
+
const poolSnapshot = useMemo(() => {
|
|
32
|
+
refreshTick;
|
|
33
|
+
return getSolidEntityApiPoolSnapshot();
|
|
34
|
+
}, [refreshTick]);
|
|
35
|
+
|
|
36
|
+
const activeCount = poolSnapshot.filter((entry) => entry.active).length;
|
|
37
|
+
const cachedCount = poolSnapshot.length;
|
|
38
|
+
const loginRedirect = env("NEXT_PUBLIC_LOGIN_REDIRECT_URL") || "/admin";
|
|
39
|
+
const backendApi = env("NEXT_PUBLIC_BACKEND_API_URL") || env("API_URL", "");
|
|
40
|
+
const localSession = loadSession();
|
|
41
|
+
|
|
42
|
+
if (status === "loading") {
|
|
43
|
+
return (
|
|
44
|
+
<div className="solid-studio-home">
|
|
45
|
+
<div className="solid-studio-home-inner solid-studio-home-inner--wider">
|
|
46
|
+
<div className="solid-studio-card">
|
|
47
|
+
<div className="solid-studio-card-content">Loading diagnostics...</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!isAdmin) {
|
|
55
|
+
return (
|
|
56
|
+
<div className="solid-studio-home">
|
|
57
|
+
<div className="solid-studio-home-inner solid-studio-home-inner--wider">
|
|
58
|
+
<div className="solid-studio-card">
|
|
59
|
+
<div className="solid-studio-card-header">
|
|
60
|
+
<h3 className="solid-studio-card-title">Diagnostics Access Restricted</h3>
|
|
61
|
+
<p className="solid-studio-card-description">
|
|
62
|
+
You do not have permission to view this diagnostics page.
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!diagnosticsEnabled) {
|
|
72
|
+
return (
|
|
73
|
+
<div className="solid-studio-home">
|
|
74
|
+
<div className="solid-studio-home-inner solid-studio-home-inner--wider">
|
|
75
|
+
<div className="solid-studio-card">
|
|
76
|
+
<div className="solid-studio-card-header">
|
|
77
|
+
<h3 className="solid-studio-card-title">Diagnostics Disabled</h3>
|
|
78
|
+
<p className="solid-studio-card-description">
|
|
79
|
+
Diagnostics are enabled only in dev/staging-style environments. Current environment: <code>{envName}</code>.
|
|
80
|
+
</p>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<div className="solid-studio-home solid-studio-home--top">
|
|
90
|
+
<div className="solid-studio-home-inner solid-studio-home-inner--wider">
|
|
91
|
+
<div className="solid-studio-home-toolbar" style={{ marginBottom: "14px" }}>
|
|
92
|
+
<div className="solid-studio-home-toolbar-left">
|
|
93
|
+
<div className="solid-studio-home-heading">
|
|
94
|
+
<div className="solid-studio-home-badge">Diagnostics</div>
|
|
95
|
+
<h1>SolidX Runtime Diagnostics</h1>
|
|
96
|
+
<p>Read-only runtime snapshot for support and debugging.</p>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
<div className="solid-studio-home-toolbar-right">
|
|
100
|
+
<SolidButton size="sm" variant="outline" onClick={() => setRefreshTick((v) => v + 1)}>
|
|
101
|
+
Refresh
|
|
102
|
+
</SolidButton>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div className="solid-studio-card" style={{ marginBottom: "14px" }}>
|
|
107
|
+
<div className="solid-studio-card-header">
|
|
108
|
+
<h3 className="solid-studio-card-title">Runtime</h3>
|
|
109
|
+
</div>
|
|
110
|
+
<div className="solid-studio-card-content">
|
|
111
|
+
<div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))", gap: "10px" }}>
|
|
112
|
+
<div><strong>Environment:</strong> {envName}</div>
|
|
113
|
+
<div><strong>Pool Limit:</strong> {SOLID_ENTITY_API_POOL_LIMIT}</div>
|
|
114
|
+
<div><strong>Active Entity APIs:</strong> {activeCount}</div>
|
|
115
|
+
<div><strong>Cached Entity APIs:</strong> {cachedCount}</div>
|
|
116
|
+
<div><strong>Login Redirect:</strong> {loginRedirect}</div>
|
|
117
|
+
<div><strong>Backend API:</strong> {backendApi || "(not set)"}</div>
|
|
118
|
+
<div><strong>User:</strong> {localSession?.user?.email || localSession?.user?.name || "(unknown)"}</div>
|
|
119
|
+
<div><strong>Roles:</strong> {(localSession?.user?.roles || []).map((r: any) => r.name || r).join(", ") || "(none)"}</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div className="solid-studio-card">
|
|
125
|
+
<div className="solid-studio-card-header">
|
|
126
|
+
<h3 className="solid-studio-card-title">Entity API Pool</h3>
|
|
127
|
+
<p className="solid-studio-card-description">
|
|
128
|
+
Each entry represents a lazily created entity API. Active entries have reducer+middleware currently registered.
|
|
129
|
+
</p>
|
|
130
|
+
</div>
|
|
131
|
+
<div className="solid-studio-card-content" style={{ overflowX: "auto" }}>
|
|
132
|
+
<table style={{ width: "100%", borderCollapse: "collapse", fontSize: "13px" }}>
|
|
133
|
+
<thead>
|
|
134
|
+
<tr style={{ borderBottom: "1px solid rgba(148, 163, 184, 0.35)" }}>
|
|
135
|
+
<th style={{ textAlign: "left", padding: "8px" }}>Entity</th>
|
|
136
|
+
<th style={{ textAlign: "left", padding: "8px" }}>Reducer Path</th>
|
|
137
|
+
<th style={{ textAlign: "left", padding: "8px" }}>Registered</th>
|
|
138
|
+
<th style={{ textAlign: "left", padding: "8px" }}>Last Accessed</th>
|
|
139
|
+
<th style={{ textAlign: "left", padding: "8px" }}>Active</th>
|
|
140
|
+
</tr>
|
|
141
|
+
</thead>
|
|
142
|
+
<tbody>
|
|
143
|
+
{poolSnapshot.length === 0 ? (
|
|
144
|
+
<tr>
|
|
145
|
+
<td colSpan={5} style={{ padding: "12px", opacity: 0.7 }}>
|
|
146
|
+
No entity APIs have been created in this session yet.
|
|
147
|
+
</td>
|
|
148
|
+
</tr>
|
|
149
|
+
) : (
|
|
150
|
+
poolSnapshot.map((entry) => (
|
|
151
|
+
<tr key={entry.reducerPath} style={{ borderBottom: "1px solid rgba(148, 163, 184, 0.2)" }}>
|
|
152
|
+
<td style={{ padding: "8px" }}>{entry.entityName}</td>
|
|
153
|
+
<td style={{ padding: "8px", fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace" }}>{entry.reducerPath}</td>
|
|
154
|
+
<td style={{ padding: "8px" }}>{toDisplayTime(entry.registeredAt)}</td>
|
|
155
|
+
<td style={{ padding: "8px" }}>{toDisplayTime(entry.lastAccessedAt)}</td>
|
|
156
|
+
<td style={{ padding: "8px" }}>{entry.active ? "yes" : "no"}</td>
|
|
157
|
+
</tr>
|
|
158
|
+
))
|
|
159
|
+
)}
|
|
160
|
+
</tbody>
|
|
161
|
+
</table>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
}
|