xladmin 0.5.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/client.d.ts +3 -1
- package/dist/components/Shell.d.ts +5 -2
- package/dist/components/layout/Sidebar.d.ts +4 -1
- package/dist/index.js +217 -50
- package/dist/types/index.d.ts +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ You also need one router adapter:
|
|
|
34
34
|
- `createAxiosAdminClient(...)`
|
|
35
35
|
- `createFetchAdminClient(...)`
|
|
36
36
|
- `createBrowserAdminRouter(...)`
|
|
37
|
+
- `AdminCurrentUser`
|
|
37
38
|
- admin types, i18n helpers, and default theme
|
|
38
39
|
|
|
39
40
|
## Minimal Example
|
|
@@ -67,6 +68,49 @@ export function AdminApp() {
|
|
|
67
68
|
|
|
68
69
|
For framework routing, use one of the adapter packages instead of the default browser router.
|
|
69
70
|
|
|
71
|
+
## Current User And Logout
|
|
72
|
+
|
|
73
|
+
`Shell` shows a compact current-user panel pinned to the bottom of the sidebar when a user is available.
|
|
74
|
+
Long login values wrap inside the panel instead of overflowing the sidebar.
|
|
75
|
+
By default it calls:
|
|
76
|
+
|
|
77
|
+
- `client.getCurrentUser()` -> `GET /xladmin/me/`
|
|
78
|
+
- `client.logout()` -> `POST /xladmin/logout/`
|
|
79
|
+
|
|
80
|
+
After logout, `Shell` redirects to `/login`.
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
<Shell
|
|
84
|
+
client={client}
|
|
85
|
+
models={models}
|
|
86
|
+
blocks={blocks}
|
|
87
|
+
basePath="/admin"
|
|
88
|
+
loginPath="/login"
|
|
89
|
+
>
|
|
90
|
+
{content}
|
|
91
|
+
</Shell>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If your application already has the user or a custom logout flow, pass them explicitly:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
<Shell
|
|
98
|
+
client={client}
|
|
99
|
+
models={models}
|
|
100
|
+
blocks={blocks}
|
|
101
|
+
basePath="/admin"
|
|
102
|
+
currentUser={{login: auth.user.email}}
|
|
103
|
+
onLogout={async () => {
|
|
104
|
+
await auth.logout();
|
|
105
|
+
}}
|
|
106
|
+
loginPath="/sign-in"
|
|
107
|
+
>
|
|
108
|
+
{content}
|
|
109
|
+
</Shell>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Set `currentUser={null}` to hide the sidebar user panel.
|
|
113
|
+
|
|
70
114
|
## Development
|
|
71
115
|
|
|
72
116
|
```bash
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AdminChoicesResponse, AdminDeletePreviewResponse, AdminDetailResponse, AdminListResponse, AdminModelMeta, AdminModelsResponse, AdminObjectActionResponse } from './types';
|
|
1
|
+
import type { AdminChoicesResponse, AdminDeletePreviewResponse, AdminDetailResponse, AdminCurrentUser, AdminListResponse, AdminModelMeta, AdminModelsResponse, AdminObjectActionResponse } from './types';
|
|
2
2
|
export type AdminRequestOptions = {
|
|
3
3
|
signal?: AbortSignal;
|
|
4
4
|
};
|
|
@@ -11,6 +11,8 @@ export type AdminSelectionOptions = {
|
|
|
11
11
|
selectionScope?: AdminSelectionScope;
|
|
12
12
|
};
|
|
13
13
|
export type AdminClient = {
|
|
14
|
+
getCurrentUser: () => Promise<AdminCurrentUser>;
|
|
15
|
+
logout: () => Promise<void>;
|
|
14
16
|
getModels: () => Promise<AdminModelsResponse>;
|
|
15
17
|
getModel: (slug: string) => Promise<AdminModelMeta>;
|
|
16
18
|
getItems: (slug: string, params?: {
|
|
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react';
|
|
|
2
2
|
import { type Theme } from '@mui/material/styles';
|
|
3
3
|
import type { AdminClient } from '../client';
|
|
4
4
|
import type { AdminRouter } from '../router';
|
|
5
|
-
import type { AdminModelMeta, AdminModelsBlockMeta } from '../types';
|
|
5
|
+
import type { AdminCurrentUser, AdminModelMeta, AdminModelsBlockMeta } from '../types';
|
|
6
6
|
type AdminShellProps = {
|
|
7
7
|
client: AdminClient;
|
|
8
8
|
models: AdminModelMeta[];
|
|
@@ -12,7 +12,10 @@ type AdminShellProps = {
|
|
|
12
12
|
children: ReactNode;
|
|
13
13
|
theme?: Theme;
|
|
14
14
|
router?: AdminRouter;
|
|
15
|
+
currentUser?: AdminCurrentUser | string | null;
|
|
16
|
+
loginPath?: string | null;
|
|
17
|
+
onLogout?: () => void | Promise<void>;
|
|
15
18
|
};
|
|
16
19
|
export type ShellProps = AdminShellProps;
|
|
17
|
-
export declare function Shell({ client, models, blocks, basePath, locale, children, theme, router }: ShellProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export declare function Shell({ client, models, blocks, basePath, locale, children, theme, router, currentUser, loginPath, onLogout, }: ShellProps): import("react/jsx-runtime").JSX.Element;
|
|
18
21
|
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import type { AdminModelMeta, AdminModelsBlockMeta } from '@xladmin-core/types';
|
|
1
|
+
import type { AdminCurrentUser, AdminModelMeta, AdminModelsBlockMeta } from '@xladmin-core/types';
|
|
2
2
|
type SidebarProps = {
|
|
3
3
|
models: AdminModelMeta[];
|
|
4
4
|
blocks: AdminModelsBlockMeta[];
|
|
5
5
|
basePath: string;
|
|
6
|
+
currentUser?: AdminCurrentUser | null;
|
|
7
|
+
isLoggingOut?: boolean;
|
|
8
|
+
onLogout?: () => void;
|
|
6
9
|
};
|
|
7
10
|
export declare const Sidebar: import("react").NamedExoticComponent<SidebarProps>;
|
|
8
11
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
2
|
function createAdminClient(transport) {
|
|
3
3
|
return {
|
|
4
|
+
async getCurrentUser() {
|
|
5
|
+
return await transportGet(transport, "/xladmin/me/");
|
|
6
|
+
},
|
|
7
|
+
async logout() {
|
|
8
|
+
await transportPost(transport, "/xladmin/logout/", {});
|
|
9
|
+
},
|
|
4
10
|
async getModels() {
|
|
5
11
|
return await transportGet(transport, "/xladmin/models/");
|
|
6
12
|
},
|
|
@@ -148,7 +154,14 @@ function isWrappedTransportResponse(response) {
|
|
|
148
154
|
}
|
|
149
155
|
async function requestJson(fetchImpl, config, method, url, body, params, signal) {
|
|
150
156
|
const response = await requestRaw(fetchImpl, config, method, url, body, params, signal);
|
|
151
|
-
|
|
157
|
+
if (response.status === 204) {
|
|
158
|
+
return void 0;
|
|
159
|
+
}
|
|
160
|
+
const text = await response.text();
|
|
161
|
+
if (!text.trim()) {
|
|
162
|
+
return void 0;
|
|
163
|
+
}
|
|
164
|
+
return JSON.parse(text);
|
|
152
165
|
}
|
|
153
166
|
async function requestRaw(fetchImpl, config, method, url, body, params, signal) {
|
|
154
167
|
var _a;
|
|
@@ -5063,7 +5076,7 @@ function ObjectPage({ client, slug, id, router }) {
|
|
|
5063
5076
|
}
|
|
5064
5077
|
|
|
5065
5078
|
// src/components/Shell.tsx
|
|
5066
|
-
import { useEffect as useEffect14, useMemo as useMemo11, useState as useState13 } from "react";
|
|
5079
|
+
import { useCallback as useCallback8, useEffect as useEffect14, useMemo as useMemo11, useState as useState13 } from "react";
|
|
5067
5080
|
import { Box as Box17, CssBaseline, Drawer, GlobalStyles, Stack as Stack14, useMediaQuery as useMediaQuery4 } from "@mui/material";
|
|
5068
5081
|
import { ThemeProvider } from "@mui/material/styles";
|
|
5069
5082
|
|
|
@@ -5234,7 +5247,8 @@ function Main({ children }) {
|
|
|
5234
5247
|
|
|
5235
5248
|
// src/components/layout/Sidebar.tsx
|
|
5236
5249
|
import { memo as memo8, useEffect as useEffect13, useRef as useRef7 } from "react";
|
|
5237
|
-
import
|
|
5250
|
+
import LogoutIcon from "@mui/icons-material/Logout";
|
|
5251
|
+
import { Box as Box16, IconButton as IconButton5, ListItemButton as ListItemButton3, Tooltip as Tooltip2, Typography as Typography8 } from "@mui/material";
|
|
5238
5252
|
import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5239
5253
|
function getOffsetTopWithinContainer(element, container) {
|
|
5240
5254
|
let offsetTop = element.offsetTop;
|
|
@@ -5245,7 +5259,14 @@ function getOffsetTopWithinContainer(element, container) {
|
|
|
5245
5259
|
}
|
|
5246
5260
|
return offsetTop;
|
|
5247
5261
|
}
|
|
5248
|
-
var Sidebar = memo8(function Sidebar2({
|
|
5262
|
+
var Sidebar = memo8(function Sidebar2({
|
|
5263
|
+
models,
|
|
5264
|
+
blocks,
|
|
5265
|
+
basePath,
|
|
5266
|
+
currentUser,
|
|
5267
|
+
isLoggingOut = false,
|
|
5268
|
+
onLogout
|
|
5269
|
+
}) {
|
|
5249
5270
|
var _a;
|
|
5250
5271
|
const t = useAdminTranslation();
|
|
5251
5272
|
const { pathname } = useAdminLocation();
|
|
@@ -5328,59 +5349,124 @@ var Sidebar = memo8(function Sidebar2({ models, blocks, basePath }) {
|
|
|
5328
5349
|
}
|
|
5329
5350
|
};
|
|
5330
5351
|
}, [activeModelSlug, blocks]);
|
|
5331
|
-
return /* @__PURE__ */
|
|
5352
|
+
return /* @__PURE__ */ jsxs19(Box16, { sx: { height: "100%", overflow: "hidden", display: "flex", flexDirection: "column", minHeight: 0 }, children: [
|
|
5353
|
+
/* @__PURE__ */ jsx27(
|
|
5354
|
+
Box16,
|
|
5355
|
+
{
|
|
5356
|
+
ref: scrollContainerRef,
|
|
5357
|
+
sx: {
|
|
5358
|
+
flex: 1,
|
|
5359
|
+
minHeight: 0,
|
|
5360
|
+
overflowY: "scroll",
|
|
5361
|
+
overflowX: "hidden",
|
|
5362
|
+
scrollbarGutter: "stable",
|
|
5363
|
+
direction: "rtl",
|
|
5364
|
+
ml: 0,
|
|
5365
|
+
pl: 0
|
|
5366
|
+
},
|
|
5367
|
+
children: /* @__PURE__ */ jsxs19(Box16, { sx: { direction: "ltr", pl: 1 }, children: [
|
|
5368
|
+
/* @__PURE__ */ jsx27(
|
|
5369
|
+
NavLink,
|
|
5370
|
+
{
|
|
5371
|
+
href: basePath,
|
|
5372
|
+
style: { textDecoration: "none", display: "block" },
|
|
5373
|
+
onClick: () => startPendingNavigation(basePath, "overview"),
|
|
5374
|
+
children: /* @__PURE__ */ jsx27(
|
|
5375
|
+
ListItemButton3,
|
|
5376
|
+
{
|
|
5377
|
+
selected: isOverviewActive,
|
|
5378
|
+
sx: {
|
|
5379
|
+
mb: 2,
|
|
5380
|
+
borderRadius: "8px",
|
|
5381
|
+
backgroundColor: isOverviewActive ? "rgba(255, 255, 255, 0.18)" : "rgba(255, 255, 255, 0.035)",
|
|
5382
|
+
boxShadow: isOverviewActive ? "inset 0 0 0 1px rgba(255, 255, 255, 0.08)" : "none",
|
|
5383
|
+
"&:hover": {
|
|
5384
|
+
backgroundColor: isOverviewActive ? "rgba(255, 255, 255, 0.2)" : "rgba(255, 255, 255, 0.055)"
|
|
5385
|
+
}
|
|
5386
|
+
},
|
|
5387
|
+
children: /* @__PURE__ */ jsx27(Typography8, { variant: "subtitle1", sx: { fontWeight: 700 }, children: t("overview") })
|
|
5388
|
+
}
|
|
5389
|
+
)
|
|
5390
|
+
}
|
|
5391
|
+
),
|
|
5392
|
+
/* @__PURE__ */ jsx27(
|
|
5393
|
+
ModelsBlocks,
|
|
5394
|
+
{
|
|
5395
|
+
models,
|
|
5396
|
+
blocks,
|
|
5397
|
+
basePath,
|
|
5398
|
+
variant: "sidebar",
|
|
5399
|
+
activeModelSlug,
|
|
5400
|
+
onModelNavigate: (href) => startPendingNavigation(href, "model")
|
|
5401
|
+
}
|
|
5402
|
+
)
|
|
5403
|
+
] })
|
|
5404
|
+
}
|
|
5405
|
+
),
|
|
5406
|
+
/* @__PURE__ */ jsx27(SidebarCurrentUser, { currentUser, isLoggingOut, onLogout })
|
|
5407
|
+
] });
|
|
5408
|
+
});
|
|
5409
|
+
function SidebarCurrentUser({ currentUser, isLoggingOut, onLogout }) {
|
|
5410
|
+
if (!currentUser) {
|
|
5411
|
+
return null;
|
|
5412
|
+
}
|
|
5413
|
+
return /* @__PURE__ */ jsxs19(
|
|
5332
5414
|
Box16,
|
|
5333
5415
|
{
|
|
5334
|
-
ref: scrollContainerRef,
|
|
5335
5416
|
sx: {
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5417
|
+
flexShrink: 0,
|
|
5418
|
+
ml: 1,
|
|
5419
|
+
mt: 1.25,
|
|
5420
|
+
borderRadius: "8px",
|
|
5421
|
+
backgroundColor: "rgba(255, 255, 255, 0.02)",
|
|
5422
|
+
boxShadow: "inset 0 0 0 1px rgba(255, 255, 255, 0.03)",
|
|
5423
|
+
display: "flex",
|
|
5424
|
+
alignItems: "center",
|
|
5425
|
+
minHeight: 44,
|
|
5426
|
+
px: 1,
|
|
5427
|
+
gap: 1
|
|
5343
5428
|
},
|
|
5344
|
-
children:
|
|
5429
|
+
children: [
|
|
5345
5430
|
/* @__PURE__ */ jsx27(
|
|
5346
|
-
|
|
5431
|
+
Typography8,
|
|
5347
5432
|
{
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
"&:hover": {
|
|
5361
|
-
backgroundColor: isOverviewActive ? "rgba(255, 255, 255, 0.2)" : "rgba(255, 255, 255, 0.055)"
|
|
5362
|
-
}
|
|
5363
|
-
},
|
|
5364
|
-
children: /* @__PURE__ */ jsx27(Typography8, { variant: "subtitle1", sx: { fontWeight: 700 }, children: t("overview") })
|
|
5365
|
-
}
|
|
5366
|
-
)
|
|
5433
|
+
title: currentUser.login,
|
|
5434
|
+
sx: {
|
|
5435
|
+
flex: 1,
|
|
5436
|
+
minWidth: 0,
|
|
5437
|
+
overflowWrap: "anywhere",
|
|
5438
|
+
whiteSpace: "normal",
|
|
5439
|
+
wordBreak: "break-word",
|
|
5440
|
+
fontSize: 13,
|
|
5441
|
+
fontWeight: 650,
|
|
5442
|
+
lineHeight: 1.25
|
|
5443
|
+
},
|
|
5444
|
+
children: currentUser.login
|
|
5367
5445
|
}
|
|
5368
5446
|
),
|
|
5369
|
-
/* @__PURE__ */ jsx27(
|
|
5370
|
-
|
|
5447
|
+
onLogout ? /* @__PURE__ */ jsx27(Tooltip2, { title: "Logout", children: /* @__PURE__ */ jsx27("span", { children: /* @__PURE__ */ jsx27(
|
|
5448
|
+
IconButton5,
|
|
5371
5449
|
{
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5450
|
+
"aria-label": "Logout",
|
|
5451
|
+
size: "small",
|
|
5452
|
+
disabled: isLoggingOut,
|
|
5453
|
+
onClick: onLogout,
|
|
5454
|
+
sx: {
|
|
5455
|
+
width: 32,
|
|
5456
|
+
height: 32,
|
|
5457
|
+
color: "text.secondary",
|
|
5458
|
+
"&:hover": {
|
|
5459
|
+
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
|
5460
|
+
color: "text.primary"
|
|
5461
|
+
}
|
|
5462
|
+
},
|
|
5463
|
+
children: /* @__PURE__ */ jsx27(LogoutIcon, { sx: { fontSize: 18 } })
|
|
5378
5464
|
}
|
|
5379
|
-
)
|
|
5380
|
-
]
|
|
5465
|
+
) }) }) : null
|
|
5466
|
+
]
|
|
5381
5467
|
}
|
|
5382
|
-
)
|
|
5383
|
-
}
|
|
5468
|
+
);
|
|
5469
|
+
}
|
|
5384
5470
|
|
|
5385
5471
|
// src/components/Shell.tsx
|
|
5386
5472
|
import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
@@ -5388,8 +5474,19 @@ function normalizeAdminPath(path) {
|
|
|
5388
5474
|
const normalizedPath = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
|
|
5389
5475
|
return normalizedPath.replace(/^\/(ru|en)(?=\/|$)/, "") || "/";
|
|
5390
5476
|
}
|
|
5391
|
-
function Shell({
|
|
5392
|
-
|
|
5477
|
+
function Shell({
|
|
5478
|
+
client,
|
|
5479
|
+
models,
|
|
5480
|
+
blocks,
|
|
5481
|
+
basePath,
|
|
5482
|
+
locale,
|
|
5483
|
+
children,
|
|
5484
|
+
theme,
|
|
5485
|
+
router,
|
|
5486
|
+
currentUser,
|
|
5487
|
+
loginPath = "/login",
|
|
5488
|
+
onLogout
|
|
5489
|
+
}) {
|
|
5393
5490
|
const activeTheme = theme != null ? theme : defaultAdminTheme;
|
|
5394
5491
|
const resolvedRouter = useAdminRouter(router);
|
|
5395
5492
|
const location = useAdminLocation(resolvedRouter);
|
|
@@ -5398,6 +5495,12 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5398
5495
|
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState13(false);
|
|
5399
5496
|
const [pendingPath, setPendingPath] = useState13(null);
|
|
5400
5497
|
const [pendingView, setPendingView] = useState13(null);
|
|
5498
|
+
const [loadedCurrentUser, setLoadedCurrentUser] = useState13(null);
|
|
5499
|
+
const [isLoggingOut, setIsLoggingOut] = useState13(false);
|
|
5500
|
+
const sidebarCurrentUser = useMemo11(
|
|
5501
|
+
() => normalizeCurrentUser(currentUser === void 0 ? loadedCurrentUser : currentUser),
|
|
5502
|
+
[currentUser, loadedCurrentUser]
|
|
5503
|
+
);
|
|
5401
5504
|
useEffect14(() => {
|
|
5402
5505
|
if (isDesktopSidebar) {
|
|
5403
5506
|
setIsMobileSidebarOpen(false);
|
|
@@ -5406,6 +5509,40 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5406
5509
|
useEffect14(() => {
|
|
5407
5510
|
setIsMobileSidebarOpen(false);
|
|
5408
5511
|
}, [pathname]);
|
|
5512
|
+
useEffect14(() => {
|
|
5513
|
+
if (currentUser !== void 0) {
|
|
5514
|
+
return;
|
|
5515
|
+
}
|
|
5516
|
+
let isMounted = true;
|
|
5517
|
+
client.getCurrentUser().then((response) => {
|
|
5518
|
+
if (!isMounted) return;
|
|
5519
|
+
setLoadedCurrentUser(response);
|
|
5520
|
+
}).catch(() => {
|
|
5521
|
+
if (!isMounted) return;
|
|
5522
|
+
setLoadedCurrentUser(null);
|
|
5523
|
+
});
|
|
5524
|
+
return () => {
|
|
5525
|
+
isMounted = false;
|
|
5526
|
+
};
|
|
5527
|
+
}, [client, currentUser]);
|
|
5528
|
+
const handleLogout = useCallback8(async () => {
|
|
5529
|
+
if (isLoggingOut) {
|
|
5530
|
+
return;
|
|
5531
|
+
}
|
|
5532
|
+
setIsLoggingOut(true);
|
|
5533
|
+
try {
|
|
5534
|
+
if (onLogout) {
|
|
5535
|
+
await onLogout();
|
|
5536
|
+
} else {
|
|
5537
|
+
await client.logout();
|
|
5538
|
+
}
|
|
5539
|
+
if (loginPath) {
|
|
5540
|
+
resolvedRouter.replace(loginPath);
|
|
5541
|
+
}
|
|
5542
|
+
} finally {
|
|
5543
|
+
setIsLoggingOut(false);
|
|
5544
|
+
}
|
|
5545
|
+
}, [client, isLoggingOut, loginPath, onLogout, resolvedRouter]);
|
|
5409
5546
|
const shellContextValue = useMemo11(() => ({
|
|
5410
5547
|
isMobile: !isDesktopSidebar,
|
|
5411
5548
|
openMobileSidebar: () => setIsMobileSidebarOpen(true),
|
|
@@ -5500,7 +5637,17 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5500
5637
|
pl: 0,
|
|
5501
5638
|
pr: 1
|
|
5502
5639
|
},
|
|
5503
|
-
children: /* @__PURE__ */ jsx28(
|
|
5640
|
+
children: /* @__PURE__ */ jsx28(
|
|
5641
|
+
Sidebar,
|
|
5642
|
+
{
|
|
5643
|
+
models,
|
|
5644
|
+
blocks,
|
|
5645
|
+
basePath,
|
|
5646
|
+
currentUser: sidebarCurrentUser,
|
|
5647
|
+
isLoggingOut,
|
|
5648
|
+
onLogout: handleLogout
|
|
5649
|
+
}
|
|
5650
|
+
)
|
|
5504
5651
|
}
|
|
5505
5652
|
),
|
|
5506
5653
|
/* @__PURE__ */ jsx28(
|
|
@@ -5544,11 +5691,31 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5544
5691
|
}
|
|
5545
5692
|
}
|
|
5546
5693
|
},
|
|
5547
|
-
children: /* @__PURE__ */ jsx28(Box17, { sx: { height: "100%", minHeight: 0, pr: 1.5 }, children: /* @__PURE__ */ jsx28(
|
|
5694
|
+
children: /* @__PURE__ */ jsx28(Box17, { sx: { height: "100%", minHeight: 0, pr: 1.5 }, children: /* @__PURE__ */ jsx28(
|
|
5695
|
+
Sidebar,
|
|
5696
|
+
{
|
|
5697
|
+
models,
|
|
5698
|
+
blocks,
|
|
5699
|
+
basePath,
|
|
5700
|
+
currentUser: sidebarCurrentUser,
|
|
5701
|
+
isLoggingOut,
|
|
5702
|
+
onLogout: handleLogout
|
|
5703
|
+
}
|
|
5704
|
+
) })
|
|
5548
5705
|
}
|
|
5549
5706
|
)
|
|
5550
5707
|
] }) }) }) }) }) });
|
|
5551
5708
|
}
|
|
5709
|
+
function normalizeCurrentUser(user) {
|
|
5710
|
+
if (typeof user === "string") {
|
|
5711
|
+
const login = user.trim();
|
|
5712
|
+
return login ? { login } : null;
|
|
5713
|
+
}
|
|
5714
|
+
if (!user || !user.login.trim()) {
|
|
5715
|
+
return null;
|
|
5716
|
+
}
|
|
5717
|
+
return user;
|
|
5718
|
+
}
|
|
5552
5719
|
export {
|
|
5553
5720
|
AdminLocaleProvider,
|
|
5554
5721
|
AdminRouterProvider,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -135,6 +135,12 @@ export type AdminModelsResponse = {
|
|
|
135
135
|
items: AdminModelMeta[];
|
|
136
136
|
blocks: AdminModelsBlockMeta[];
|
|
137
137
|
};
|
|
138
|
+
export type AdminCurrentUser = {
|
|
139
|
+
id?: string | number | null;
|
|
140
|
+
login: string;
|
|
141
|
+
email?: string | null;
|
|
142
|
+
name?: string | null;
|
|
143
|
+
};
|
|
138
144
|
export type AdminChoicesResponse = {
|
|
139
145
|
items: Array<{
|
|
140
146
|
id: string | number;
|