xladmin 0.4.0 → 0.6.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 +43 -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 +311 -155
- package/dist/types/index.d.ts +6 -0
- package/package.json +4 -4
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,48 @@ 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
|
+
By default it calls:
|
|
75
|
+
|
|
76
|
+
- `client.getCurrentUser()` -> `GET /xladmin/me/`
|
|
77
|
+
- `client.logout()` -> `POST /xladmin/logout/`
|
|
78
|
+
|
|
79
|
+
After logout, `Shell` redirects to `/login`.
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
<Shell
|
|
83
|
+
client={client}
|
|
84
|
+
models={models}
|
|
85
|
+
blocks={blocks}
|
|
86
|
+
basePath="/admin"
|
|
87
|
+
loginPath="/login"
|
|
88
|
+
>
|
|
89
|
+
{content}
|
|
90
|
+
</Shell>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If your application already has the user or a custom logout flow, pass them explicitly:
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
<Shell
|
|
97
|
+
client={client}
|
|
98
|
+
models={models}
|
|
99
|
+
blocks={blocks}
|
|
100
|
+
basePath="/admin"
|
|
101
|
+
currentUser={{login: auth.user.email}}
|
|
102
|
+
onLogout={async () => {
|
|
103
|
+
await auth.logout();
|
|
104
|
+
}}
|
|
105
|
+
loginPath="/sign-in"
|
|
106
|
+
>
|
|
107
|
+
{content}
|
|
108
|
+
</Shell>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Set `currentUser={null}` to hide the sidebar user panel.
|
|
112
|
+
|
|
70
113
|
## Development
|
|
71
114
|
|
|
72
115
|
```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;
|
|
@@ -876,9 +889,13 @@ var FieldEditor = memo(function FieldEditor2({
|
|
|
876
889
|
size: "small",
|
|
877
890
|
required: field.required,
|
|
878
891
|
sx: buildRequiredLabelSx(),
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
892
|
+
helperText: (_a = field.help_text) != null ? _a : void 0,
|
|
893
|
+
slotProps: {
|
|
894
|
+
htmlInput: {
|
|
895
|
+
...buildHtmlInputProps(field),
|
|
896
|
+
placeholder: (_b = field.placeholder) != null ? _b : void 0
|
|
897
|
+
}
|
|
898
|
+
}
|
|
882
899
|
}
|
|
883
900
|
}
|
|
884
901
|
}
|
|
@@ -910,9 +927,13 @@ var FieldEditor = memo(function FieldEditor2({
|
|
|
910
927
|
size: "small",
|
|
911
928
|
required: field.required,
|
|
912
929
|
sx: buildRequiredLabelSx(),
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
930
|
+
helperText: (_c = field.help_text) != null ? _c : void 0,
|
|
931
|
+
slotProps: {
|
|
932
|
+
htmlInput: {
|
|
933
|
+
...buildHtmlInputProps(field),
|
|
934
|
+
placeholder: (_d = field.placeholder) != null ? _d : void 0
|
|
935
|
+
}
|
|
936
|
+
}
|
|
916
937
|
}
|
|
917
938
|
}
|
|
918
939
|
}
|
|
@@ -1044,8 +1065,8 @@ function renderChoiceEditor({
|
|
|
1044
1065
|
listbox: { sx: { maxHeight: 240 } }
|
|
1045
1066
|
},
|
|
1046
1067
|
renderInput: (params) => (() => {
|
|
1047
|
-
var _a2, _b;
|
|
1048
|
-
const {
|
|
1068
|
+
var _a2, _b, _c;
|
|
1069
|
+
const { slotProps, ...textFieldParams } = params;
|
|
1049
1070
|
return /* @__PURE__ */ jsx3(
|
|
1050
1071
|
TextField,
|
|
1051
1072
|
{
|
|
@@ -1056,15 +1077,16 @@ function renderChoiceEditor({
|
|
|
1056
1077
|
placeholder: (_a2 = field.placeholder) != null ? _a2 : searchPlaceholder,
|
|
1057
1078
|
helperText: (_b = field.help_text) != null ? _b : void 0,
|
|
1058
1079
|
slotProps: {
|
|
1080
|
+
inputLabel: slotProps.inputLabel,
|
|
1059
1081
|
input: {
|
|
1060
|
-
...
|
|
1082
|
+
...slotProps.input,
|
|
1061
1083
|
endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1062
1084
|
isLoadingChoices ? /* @__PURE__ */ jsx3(CircularProgress, { color: "inherit", size: 16 }) : null,
|
|
1063
|
-
|
|
1085
|
+
(_c = slotProps.input) == null ? void 0 : _c.endAdornment
|
|
1064
1086
|
] })
|
|
1065
1087
|
},
|
|
1066
1088
|
htmlInput: {
|
|
1067
|
-
...
|
|
1089
|
+
...slotProps.htmlInput,
|
|
1068
1090
|
autoComplete: "new-password",
|
|
1069
1091
|
name: `admin-choice-${field.name}`
|
|
1070
1092
|
}
|
|
@@ -1104,8 +1126,8 @@ function renderChoiceEditor({
|
|
|
1104
1126
|
listbox: { sx: { maxHeight: 240 } }
|
|
1105
1127
|
},
|
|
1106
1128
|
renderInput: (params) => (() => {
|
|
1107
|
-
var _a2, _b;
|
|
1108
|
-
const {
|
|
1129
|
+
var _a2, _b, _c;
|
|
1130
|
+
const { slotProps, ...textFieldParams } = params;
|
|
1109
1131
|
return /* @__PURE__ */ jsx3(
|
|
1110
1132
|
TextField,
|
|
1111
1133
|
{
|
|
@@ -1116,15 +1138,16 @@ function renderChoiceEditor({
|
|
|
1116
1138
|
placeholder: (_a2 = field.placeholder) != null ? _a2 : searchPlaceholder,
|
|
1117
1139
|
helperText: (_b = field.help_text) != null ? _b : void 0,
|
|
1118
1140
|
slotProps: {
|
|
1141
|
+
inputLabel: slotProps.inputLabel,
|
|
1119
1142
|
input: {
|
|
1120
|
-
...
|
|
1143
|
+
...slotProps.input,
|
|
1121
1144
|
endAdornment: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1122
1145
|
isLoadingChoices ? /* @__PURE__ */ jsx3(CircularProgress, { color: "inherit", size: 16 }) : null,
|
|
1123
|
-
|
|
1146
|
+
(_c = slotProps.input) == null ? void 0 : _c.endAdornment
|
|
1124
1147
|
] })
|
|
1125
1148
|
},
|
|
1126
1149
|
htmlInput: {
|
|
1127
|
-
...
|
|
1150
|
+
...slotProps.htmlInput,
|
|
1128
1151
|
autoComplete: "new-password",
|
|
1129
1152
|
name: `admin-choice-${field.name}`
|
|
1130
1153
|
}
|
|
@@ -1294,8 +1317,8 @@ function stringifyJsonValue(value) {
|
|
|
1294
1317
|
|
|
1295
1318
|
// src/components/layout/AdminMessageContext.tsx
|
|
1296
1319
|
import { createContext as createContext3, useCallback as useCallback2, useContext as useContext3, useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState3 } from "react";
|
|
1297
|
-
import
|
|
1298
|
-
import
|
|
1320
|
+
import CheckCircleOutlinedIcon from "@mui/icons-material/CheckCircleOutlined";
|
|
1321
|
+
import ErrorOutlinedIcon from "@mui/icons-material/ErrorOutlined";
|
|
1299
1322
|
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
|
1300
1323
|
import { Box, Paper, Portal, Stack, Typography } from "@mui/material";
|
|
1301
1324
|
import { alpha, useTheme } from "@mui/material/styles";
|
|
@@ -1435,7 +1458,7 @@ function AdminMessageBubble({
|
|
|
1435
1458
|
}
|
|
1436
1459
|
}
|
|
1437
1460
|
},
|
|
1438
|
-
children: /* @__PURE__ */ jsxs2(Stack, { direction: "row", spacing: 1.125, alignItems: "center", children: [
|
|
1461
|
+
children: /* @__PURE__ */ jsxs2(Stack, { direction: "row", spacing: 1.125, sx: { alignItems: "center" }, children: [
|
|
1439
1462
|
/* @__PURE__ */ jsx4(
|
|
1440
1463
|
Box,
|
|
1441
1464
|
{
|
|
@@ -1477,7 +1500,7 @@ function AdminMessageBubble({
|
|
|
1477
1500
|
function getBubbleAppearance(theme, kind) {
|
|
1478
1501
|
if (kind === "success") {
|
|
1479
1502
|
return {
|
|
1480
|
-
icon:
|
|
1503
|
+
icon: CheckCircleOutlinedIcon,
|
|
1481
1504
|
backgroundColor: alpha(theme.palette.success.main, 0.6),
|
|
1482
1505
|
iconColor: theme.palette.common.white,
|
|
1483
1506
|
iconBackgroundColor: alpha(theme.palette.common.white, 0.14),
|
|
@@ -1486,7 +1509,7 @@ function getBubbleAppearance(theme, kind) {
|
|
|
1486
1509
|
}
|
|
1487
1510
|
if (kind === "error") {
|
|
1488
1511
|
return {
|
|
1489
|
-
icon:
|
|
1512
|
+
icon: ErrorOutlinedIcon,
|
|
1490
1513
|
backgroundColor: alpha(theme.palette.error.main, 0.6),
|
|
1491
1514
|
iconColor: theme.palette.common.white,
|
|
1492
1515
|
iconBackgroundColor: alpha(theme.palette.common.white, 0.14),
|
|
@@ -2150,84 +2173,64 @@ function MainHeader({ title, subtitle, details, error, beforeTitle, beforeSubtit
|
|
|
2150
2173
|
},
|
|
2151
2174
|
children: [
|
|
2152
2175
|
/* @__PURE__ */ jsxs7(Stack5, { spacing: 0.5, children: [
|
|
2153
|
-
/* @__PURE__ */ jsxs7(
|
|
2154
|
-
Stack5,
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
},
|
|
2183
|
-
children: title
|
|
2184
|
-
}
|
|
2185
|
-
)
|
|
2186
|
-
] }),
|
|
2187
|
-
actions ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: actions }) : null
|
|
2188
|
-
]
|
|
2189
|
-
}
|
|
2190
|
-
),
|
|
2191
|
-
subtitle && !details ? /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, alignItems: "center", sx: { minWidth: 0 }, children: [
|
|
2176
|
+
/* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 1.5, sx: { minWidth: 0, alignItems: "center", justifyContent: "space-between" }, children: [
|
|
2177
|
+
/* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 1, sx: { minWidth: 0, flex: 1, alignItems: "center" }, children: [
|
|
2178
|
+
isMobile ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: /* @__PURE__ */ jsx13(
|
|
2179
|
+
IconButton,
|
|
2180
|
+
{
|
|
2181
|
+
"aria-label": t("menu"),
|
|
2182
|
+
onClick: openMobileSidebar,
|
|
2183
|
+
size: "small",
|
|
2184
|
+
sx: { ml: -0.5 },
|
|
2185
|
+
children: /* @__PURE__ */ jsx13(MenuIcon, { fontSize: "small" })
|
|
2186
|
+
}
|
|
2187
|
+
) }) : null,
|
|
2188
|
+
beforeTitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeTitle }) : null,
|
|
2189
|
+
/* @__PURE__ */ jsx13(
|
|
2190
|
+
Typography3,
|
|
2191
|
+
{
|
|
2192
|
+
variant: "h5",
|
|
2193
|
+
sx: {
|
|
2194
|
+
fontWeight: 600,
|
|
2195
|
+
lineHeight: "2.125rem",
|
|
2196
|
+
minWidth: 0
|
|
2197
|
+
},
|
|
2198
|
+
children: title
|
|
2199
|
+
}
|
|
2200
|
+
)
|
|
2201
|
+
] }),
|
|
2202
|
+
actions ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: actions }) : null
|
|
2203
|
+
] }),
|
|
2204
|
+
subtitle && !details ? /* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, sx: { minWidth: 0, alignItems: "center" }, children: [
|
|
2192
2205
|
beforeSubtitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeSubtitle }) : null,
|
|
2193
2206
|
/* @__PURE__ */ jsx13(Typography3, { color: "text.secondary", sx: { lineHeight: "1rem", minWidth: 0 }, children: subtitle })
|
|
2194
2207
|
] }) : null,
|
|
2195
2208
|
details ? /* @__PURE__ */ jsxs7(Stack5, { spacing: 0.5, children: [
|
|
2196
|
-
/* @__PURE__ */ jsxs7(
|
|
2197
|
-
Stack5,
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
IconButton,
|
|
2209
|
+
/* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, sx: { minWidth: 0, alignItems: "center", justifyContent: "space-between" }, children: [
|
|
2210
|
+
/* @__PURE__ */ jsxs7(Stack5, { direction: "row", spacing: 0.5, sx: { minWidth: 0, flex: 1, alignItems: "center" }, children: [
|
|
2211
|
+
beforeSubtitle ? /* @__PURE__ */ jsx13(Box5, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforeSubtitle }) : null,
|
|
2212
|
+
/* @__PURE__ */ jsx13(Typography3, { color: "text.secondary", sx: { lineHeight: "1rem", minWidth: 0 }, children: subtitle })
|
|
2213
|
+
] }),
|
|
2214
|
+
/* @__PURE__ */ jsx13(
|
|
2215
|
+
IconButton,
|
|
2216
|
+
{
|
|
2217
|
+
"aria-label": isDetailsOpen ? t("hide_details") : t("show_details"),
|
|
2218
|
+
onClick: () => setIsDetailsOpen((current) => !current),
|
|
2219
|
+
size: "small",
|
|
2220
|
+
sx: { mr: -0.5 },
|
|
2221
|
+
children: /* @__PURE__ */ jsx13(
|
|
2222
|
+
ExpandMoreIcon3,
|
|
2211
2223
|
{
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
ExpandMoreIcon3,
|
|
2218
|
-
{
|
|
2219
|
-
fontSize: "small",
|
|
2220
|
-
sx: {
|
|
2221
|
-
transform: isDetailsOpen ? "rotate(180deg)" : "rotate(0deg)",
|
|
2222
|
-
transition: "transform 0.2s ease"
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
)
|
|
2224
|
+
fontSize: "small",
|
|
2225
|
+
sx: {
|
|
2226
|
+
transform: isDetailsOpen ? "rotate(180deg)" : "rotate(0deg)",
|
|
2227
|
+
transition: "transform 0.2s ease"
|
|
2228
|
+
}
|
|
2226
2229
|
}
|
|
2227
2230
|
)
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
),
|
|
2231
|
+
}
|
|
2232
|
+
)
|
|
2233
|
+
] }),
|
|
2231
2234
|
/* @__PURE__ */ jsx13(Collapse, { in: isDetailsOpen, children: /* @__PURE__ */ jsx13(Box5, { sx: { pt: 0.5 }, children: details }) })
|
|
2232
2235
|
] }) : null
|
|
2233
2236
|
] }),
|
|
@@ -2638,7 +2641,7 @@ function DeletePreviewDialog({
|
|
|
2638
2641
|
children: [
|
|
2639
2642
|
/* @__PURE__ */ jsx16(DialogTitle3, { children: title }),
|
|
2640
2643
|
/* @__PURE__ */ jsxs10(DialogContent3, { dividers: true, children: [
|
|
2641
|
-
isLoading ? /* @__PURE__ */ jsxs10(Stack7, { spacing: 1.5, alignItems: "center", justifyContent: "center"
|
|
2644
|
+
isLoading ? /* @__PURE__ */ jsxs10(Stack7, { spacing: 1.5, sx: { minHeight: 180, alignItems: "center", justifyContent: "center" }, children: [
|
|
2642
2645
|
/* @__PURE__ */ jsx16(CircularProgress2, { size: 28, thickness: 4.2, color: "inherit" }),
|
|
2643
2646
|
/* @__PURE__ */ jsx16(Typography4, { color: "text.secondary", children: t("delete_preview_loading") })
|
|
2644
2647
|
] }) : null,
|
|
@@ -2796,7 +2799,7 @@ var ListFiltersSidebar = memo3(function ListFiltersSidebar2({
|
|
|
2796
2799
|
overflow: "auto"
|
|
2797
2800
|
},
|
|
2798
2801
|
children: /* @__PURE__ */ jsxs11(Stack8, { spacing: 1.5, children: [
|
|
2799
|
-
/* @__PURE__ */ jsxs11(Stack8, { direction: "row", spacing: 1, alignItems: "center", justifyContent: "space-between", children: [
|
|
2802
|
+
/* @__PURE__ */ jsxs11(Stack8, { direction: "row", spacing: 1, sx: { alignItems: "center", justifyContent: "space-between" }, children: [
|
|
2800
2803
|
/* @__PURE__ */ jsxs11(Stack8, { spacing: 0.25, children: [
|
|
2801
2804
|
/* @__PURE__ */ jsx17(Typography5, { sx: { fontSize: 15, fontWeight: 700 }, children: t("filters") }),
|
|
2802
2805
|
activeFiltersCount > 0 ? /* @__PURE__ */ jsx17(Typography5, { color: "text.secondary", sx: { fontSize: 12 }, children: t("active_filters", { count: activeFiltersCount }) }) : null
|
|
@@ -2949,8 +2952,8 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
|
|
|
2949
2952
|
},
|
|
2950
2953
|
onInputChange: (_, nextInputValue) => setSearchValue(nextInputValue),
|
|
2951
2954
|
renderInput: (params) => (() => {
|
|
2952
|
-
var _a2;
|
|
2953
|
-
const {
|
|
2955
|
+
var _a2, _b2;
|
|
2956
|
+
const { slotProps, ...textFieldParams } = params;
|
|
2954
2957
|
return /* @__PURE__ */ jsx17(
|
|
2955
2958
|
TextField2,
|
|
2956
2959
|
{
|
|
@@ -2958,14 +2961,15 @@ function ListFilterField({ client, slug, filter, value, onChange, debounceMs })
|
|
|
2958
2961
|
label: filter.label,
|
|
2959
2962
|
placeholder: (_a2 = filter.placeholder) != null ? _a2 : t("search"),
|
|
2960
2963
|
slotProps: {
|
|
2964
|
+
inputLabel: slotProps.inputLabel,
|
|
2961
2965
|
input: {
|
|
2962
|
-
...
|
|
2966
|
+
...slotProps.input,
|
|
2963
2967
|
endAdornment: /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
2964
2968
|
isLoadingChoices ? /* @__PURE__ */ jsx17(CircularProgress3, { color: "inherit", size: 16 }) : null,
|
|
2965
|
-
|
|
2969
|
+
(_b2 = slotProps.input) == null ? void 0 : _b2.endAdornment
|
|
2966
2970
|
] })
|
|
2967
2971
|
},
|
|
2968
|
-
htmlInput:
|
|
2972
|
+
htmlInput: slotProps.htmlInput
|
|
2969
2973
|
}
|
|
2970
2974
|
}
|
|
2971
2975
|
);
|
|
@@ -3866,7 +3870,7 @@ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
|
3866
3870
|
function ModelPageSkeleton() {
|
|
3867
3871
|
return /* @__PURE__ */ jsxs13(Stack9, { spacing: 1.5, sx: { height: "100%", minHeight: 0 }, children: [
|
|
3868
3872
|
/* @__PURE__ */ jsx20(MainHeaderSkeleton, { titleWidth: 240, subtitleWidth: "38%" }),
|
|
3869
|
-
/* @__PURE__ */ jsx20(Paper6, { sx: { p: 1.5, borderRadius: "10px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs13(Stack9, { direction: { xs: "column", lg: "row" }, spacing: 1.5, alignItems: { lg: "center" }, children: [
|
|
3873
|
+
/* @__PURE__ */ jsx20(Paper6, { sx: { p: 1.5, borderRadius: "10px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs13(Stack9, { direction: { xs: "column", lg: "row" }, spacing: 1.5, sx: { alignItems: { lg: "center" } }, children: [
|
|
3870
3874
|
/* @__PURE__ */ jsx20(Skeleton3, { variant: "rounded", width: 360, height: 40 }),
|
|
3871
3875
|
/* @__PURE__ */ jsx20(Skeleton3, { variant: "rounded", width: 128, height: 40 }),
|
|
3872
3876
|
/* @__PURE__ */ jsx20(Box10, { sx: { flex: 1 } }),
|
|
@@ -3979,14 +3983,13 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
|
|
|
3979
3983
|
borderRadius: "10px",
|
|
3980
3984
|
flexShrink: 0
|
|
3981
3985
|
},
|
|
3982
|
-
children: /* @__PURE__ */ jsxs14(Stack10, { direction: { xs: "column", lg: "row" }, spacing: 1.5, alignItems: { lg: "center" }, children: [
|
|
3986
|
+
children: /* @__PURE__ */ jsxs14(Stack10, { direction: { xs: "column", lg: "row" }, spacing: 1.5, sx: { alignItems: { lg: "center" } }, children: [
|
|
3983
3987
|
/* @__PURE__ */ jsxs14(
|
|
3984
3988
|
Stack10,
|
|
3985
3989
|
{
|
|
3986
3990
|
direction: { xs: "column", xl: "row" },
|
|
3987
3991
|
spacing: 1.5,
|
|
3988
|
-
alignItems: { xl: "center" },
|
|
3989
|
-
sx: { flex: 1, minWidth: 0 },
|
|
3992
|
+
sx: { flex: 1, minWidth: 0, alignItems: { xl: "center" } },
|
|
3990
3993
|
children: [
|
|
3991
3994
|
/* @__PURE__ */ jsx21(
|
|
3992
3995
|
SearchField,
|
|
@@ -3997,7 +4000,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
|
|
|
3997
4000
|
placeholder: t("search")
|
|
3998
4001
|
}
|
|
3999
4002
|
),
|
|
4000
|
-
controller.hasSelection ? /* @__PURE__ */ jsxs14(Stack10, { direction: "row", spacing: 1,
|
|
4003
|
+
controller.hasSelection ? /* @__PURE__ */ jsxs14(Stack10, { direction: "row", spacing: 1, sx: { minWidth: 0, flexWrap: "wrap", alignItems: "center" }, children: [
|
|
4001
4004
|
/* @__PURE__ */ jsx21(
|
|
4002
4005
|
Button5,
|
|
4003
4006
|
{
|
|
@@ -4025,7 +4028,7 @@ function ModelPage({ client, basePath, slug, router, renderBeforePagination }) {
|
|
|
4025
4028
|
]
|
|
4026
4029
|
}
|
|
4027
4030
|
),
|
|
4028
|
-
/* @__PURE__ */ jsxs14(Stack10, { direction: "row", spacing: 1,
|
|
4031
|
+
/* @__PURE__ */ jsxs14(Stack10, { direction: "row", spacing: 1, sx: { marginLeft: "auto", alignItems: "center" }, children: [
|
|
4029
4032
|
beforePagination ? /* @__PURE__ */ jsx21(Box11, { sx: { display: "flex", alignItems: "center", flexShrink: 0 }, children: beforePagination }) : null,
|
|
4030
4033
|
isMobile && controller.hasListFilters ? /* @__PURE__ */ jsx21(Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsx21(
|
|
4031
4034
|
IconButton3,
|
|
@@ -5073,7 +5076,7 @@ function ObjectPage({ client, slug, id, router }) {
|
|
|
5073
5076
|
}
|
|
5074
5077
|
|
|
5075
5078
|
// src/components/Shell.tsx
|
|
5076
|
-
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";
|
|
5077
5080
|
import { Box as Box17, CssBaseline, Drawer, GlobalStyles, Stack as Stack14, useMediaQuery as useMediaQuery4 } from "@mui/material";
|
|
5078
5081
|
import { ThemeProvider } from "@mui/material/styles";
|
|
5079
5082
|
|
|
@@ -5244,7 +5247,8 @@ function Main({ children }) {
|
|
|
5244
5247
|
|
|
5245
5248
|
// src/components/layout/Sidebar.tsx
|
|
5246
5249
|
import { memo as memo8, useEffect as useEffect13, useRef as useRef7 } from "react";
|
|
5247
|
-
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";
|
|
5248
5252
|
import { jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5249
5253
|
function getOffsetTopWithinContainer(element, container) {
|
|
5250
5254
|
let offsetTop = element.offsetTop;
|
|
@@ -5255,7 +5259,14 @@ function getOffsetTopWithinContainer(element, container) {
|
|
|
5255
5259
|
}
|
|
5256
5260
|
return offsetTop;
|
|
5257
5261
|
}
|
|
5258
|
-
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
|
+
}) {
|
|
5259
5270
|
var _a;
|
|
5260
5271
|
const t = useAdminTranslation();
|
|
5261
5272
|
const { pathname } = useAdminLocation();
|
|
@@ -5338,59 +5349,123 @@ var Sidebar = memo8(function Sidebar2({ models, blocks, basePath }) {
|
|
|
5338
5349
|
}
|
|
5339
5350
|
};
|
|
5340
5351
|
}, [activeModelSlug, blocks]);
|
|
5341
|
-
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(
|
|
5342
5414
|
Box16,
|
|
5343
5415
|
{
|
|
5344
|
-
ref: scrollContainerRef,
|
|
5345
5416
|
sx: {
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
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
|
|
5353
5428
|
},
|
|
5354
|
-
children:
|
|
5429
|
+
children: [
|
|
5355
5430
|
/* @__PURE__ */ jsx27(
|
|
5356
|
-
|
|
5431
|
+
Typography8,
|
|
5357
5432
|
{
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
boxShadow: isOverviewActive ? "inset 0 0 0 1px rgba(255, 255, 255, 0.08)" : "none",
|
|
5370
|
-
"&:hover": {
|
|
5371
|
-
backgroundColor: isOverviewActive ? "rgba(255, 255, 255, 0.2)" : "rgba(255, 255, 255, 0.055)"
|
|
5372
|
-
}
|
|
5373
|
-
},
|
|
5374
|
-
children: /* @__PURE__ */ jsx27(Typography8, { variant: "subtitle1", sx: { fontWeight: 700 }, children: t("overview") })
|
|
5375
|
-
}
|
|
5376
|
-
)
|
|
5433
|
+
title: currentUser.login,
|
|
5434
|
+
sx: {
|
|
5435
|
+
flex: 1,
|
|
5436
|
+
minWidth: 0,
|
|
5437
|
+
overflow: "hidden",
|
|
5438
|
+
textOverflow: "ellipsis",
|
|
5439
|
+
whiteSpace: "nowrap",
|
|
5440
|
+
fontSize: 13,
|
|
5441
|
+
fontWeight: 650
|
|
5442
|
+
},
|
|
5443
|
+
children: currentUser.login
|
|
5377
5444
|
}
|
|
5378
5445
|
),
|
|
5379
|
-
/* @__PURE__ */ jsx27(
|
|
5380
|
-
|
|
5446
|
+
onLogout ? /* @__PURE__ */ jsx27(Tooltip2, { title: "Logout", children: /* @__PURE__ */ jsx27("span", { children: /* @__PURE__ */ jsx27(
|
|
5447
|
+
IconButton5,
|
|
5381
5448
|
{
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5449
|
+
"aria-label": "Logout",
|
|
5450
|
+
size: "small",
|
|
5451
|
+
disabled: isLoggingOut,
|
|
5452
|
+
onClick: onLogout,
|
|
5453
|
+
sx: {
|
|
5454
|
+
width: 32,
|
|
5455
|
+
height: 32,
|
|
5456
|
+
color: "text.secondary",
|
|
5457
|
+
"&:hover": {
|
|
5458
|
+
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
|
5459
|
+
color: "text.primary"
|
|
5460
|
+
}
|
|
5461
|
+
},
|
|
5462
|
+
children: /* @__PURE__ */ jsx27(LogoutIcon, { sx: { fontSize: 18 } })
|
|
5388
5463
|
}
|
|
5389
|
-
)
|
|
5390
|
-
]
|
|
5464
|
+
) }) }) : null
|
|
5465
|
+
]
|
|
5391
5466
|
}
|
|
5392
|
-
)
|
|
5393
|
-
}
|
|
5467
|
+
);
|
|
5468
|
+
}
|
|
5394
5469
|
|
|
5395
5470
|
// src/components/Shell.tsx
|
|
5396
5471
|
import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
@@ -5398,8 +5473,19 @@ function normalizeAdminPath(path) {
|
|
|
5398
5473
|
const normalizedPath = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
|
|
5399
5474
|
return normalizedPath.replace(/^\/(ru|en)(?=\/|$)/, "") || "/";
|
|
5400
5475
|
}
|
|
5401
|
-
function Shell({
|
|
5402
|
-
|
|
5476
|
+
function Shell({
|
|
5477
|
+
client,
|
|
5478
|
+
models,
|
|
5479
|
+
blocks,
|
|
5480
|
+
basePath,
|
|
5481
|
+
locale,
|
|
5482
|
+
children,
|
|
5483
|
+
theme,
|
|
5484
|
+
router,
|
|
5485
|
+
currentUser,
|
|
5486
|
+
loginPath = "/login",
|
|
5487
|
+
onLogout
|
|
5488
|
+
}) {
|
|
5403
5489
|
const activeTheme = theme != null ? theme : defaultAdminTheme;
|
|
5404
5490
|
const resolvedRouter = useAdminRouter(router);
|
|
5405
5491
|
const location = useAdminLocation(resolvedRouter);
|
|
@@ -5408,6 +5494,12 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5408
5494
|
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState13(false);
|
|
5409
5495
|
const [pendingPath, setPendingPath] = useState13(null);
|
|
5410
5496
|
const [pendingView, setPendingView] = useState13(null);
|
|
5497
|
+
const [loadedCurrentUser, setLoadedCurrentUser] = useState13(null);
|
|
5498
|
+
const [isLoggingOut, setIsLoggingOut] = useState13(false);
|
|
5499
|
+
const sidebarCurrentUser = useMemo11(
|
|
5500
|
+
() => normalizeCurrentUser(currentUser === void 0 ? loadedCurrentUser : currentUser),
|
|
5501
|
+
[currentUser, loadedCurrentUser]
|
|
5502
|
+
);
|
|
5411
5503
|
useEffect14(() => {
|
|
5412
5504
|
if (isDesktopSidebar) {
|
|
5413
5505
|
setIsMobileSidebarOpen(false);
|
|
@@ -5416,6 +5508,40 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5416
5508
|
useEffect14(() => {
|
|
5417
5509
|
setIsMobileSidebarOpen(false);
|
|
5418
5510
|
}, [pathname]);
|
|
5511
|
+
useEffect14(() => {
|
|
5512
|
+
if (currentUser !== void 0) {
|
|
5513
|
+
return;
|
|
5514
|
+
}
|
|
5515
|
+
let isMounted = true;
|
|
5516
|
+
client.getCurrentUser().then((response) => {
|
|
5517
|
+
if (!isMounted) return;
|
|
5518
|
+
setLoadedCurrentUser(response);
|
|
5519
|
+
}).catch(() => {
|
|
5520
|
+
if (!isMounted) return;
|
|
5521
|
+
setLoadedCurrentUser(null);
|
|
5522
|
+
});
|
|
5523
|
+
return () => {
|
|
5524
|
+
isMounted = false;
|
|
5525
|
+
};
|
|
5526
|
+
}, [client, currentUser]);
|
|
5527
|
+
const handleLogout = useCallback8(async () => {
|
|
5528
|
+
if (isLoggingOut) {
|
|
5529
|
+
return;
|
|
5530
|
+
}
|
|
5531
|
+
setIsLoggingOut(true);
|
|
5532
|
+
try {
|
|
5533
|
+
if (onLogout) {
|
|
5534
|
+
await onLogout();
|
|
5535
|
+
} else {
|
|
5536
|
+
await client.logout();
|
|
5537
|
+
}
|
|
5538
|
+
if (loginPath) {
|
|
5539
|
+
resolvedRouter.replace(loginPath);
|
|
5540
|
+
}
|
|
5541
|
+
} finally {
|
|
5542
|
+
setIsLoggingOut(false);
|
|
5543
|
+
}
|
|
5544
|
+
}, [client, isLoggingOut, loginPath, onLogout, resolvedRouter]);
|
|
5419
5545
|
const shellContextValue = useMemo11(() => ({
|
|
5420
5546
|
isMobile: !isDesktopSidebar,
|
|
5421
5547
|
openMobileSidebar: () => setIsMobileSidebarOpen(true),
|
|
@@ -5510,7 +5636,17 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5510
5636
|
pl: 0,
|
|
5511
5637
|
pr: 1
|
|
5512
5638
|
},
|
|
5513
|
-
children: /* @__PURE__ */ jsx28(
|
|
5639
|
+
children: /* @__PURE__ */ jsx28(
|
|
5640
|
+
Sidebar,
|
|
5641
|
+
{
|
|
5642
|
+
models,
|
|
5643
|
+
blocks,
|
|
5644
|
+
basePath,
|
|
5645
|
+
currentUser: sidebarCurrentUser,
|
|
5646
|
+
isLoggingOut,
|
|
5647
|
+
onLogout: handleLogout
|
|
5648
|
+
}
|
|
5649
|
+
)
|
|
5514
5650
|
}
|
|
5515
5651
|
),
|
|
5516
5652
|
/* @__PURE__ */ jsx28(
|
|
@@ -5554,11 +5690,31 @@ function Shell({ client, models, blocks, basePath, locale, children, theme, rout
|
|
|
5554
5690
|
}
|
|
5555
5691
|
}
|
|
5556
5692
|
},
|
|
5557
|
-
children: /* @__PURE__ */ jsx28(Box17, { sx: { height: "100%", minHeight: 0, pr: 1.5 }, children: /* @__PURE__ */ jsx28(
|
|
5693
|
+
children: /* @__PURE__ */ jsx28(Box17, { sx: { height: "100%", minHeight: 0, pr: 1.5 }, children: /* @__PURE__ */ jsx28(
|
|
5694
|
+
Sidebar,
|
|
5695
|
+
{
|
|
5696
|
+
models,
|
|
5697
|
+
blocks,
|
|
5698
|
+
basePath,
|
|
5699
|
+
currentUser: sidebarCurrentUser,
|
|
5700
|
+
isLoggingOut,
|
|
5701
|
+
onLogout: handleLogout
|
|
5702
|
+
}
|
|
5703
|
+
) })
|
|
5558
5704
|
}
|
|
5559
5705
|
)
|
|
5560
5706
|
] }) }) }) }) }) });
|
|
5561
5707
|
}
|
|
5708
|
+
function normalizeCurrentUser(user) {
|
|
5709
|
+
if (typeof user === "string") {
|
|
5710
|
+
const login = user.trim();
|
|
5711
|
+
return login ? { login } : null;
|
|
5712
|
+
}
|
|
5713
|
+
if (!user || !user.login.trim()) {
|
|
5714
|
+
return null;
|
|
5715
|
+
}
|
|
5716
|
+
return user;
|
|
5717
|
+
}
|
|
5562
5718
|
export {
|
|
5563
5719
|
AdminLocaleProvider,
|
|
5564
5720
|
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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xladmin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Framework-agnostic React + MUI admin frontend for xladmin.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@emotion/react": ">=11.14.0 <12.0.0",
|
|
40
40
|
"@emotion/styled": ">=11.14.0 <12.0.0",
|
|
41
|
-
"@mui/icons-material": ">=
|
|
42
|
-
"@mui/material": ">=
|
|
43
|
-
"@mui/x-date-pickers": ">=
|
|
41
|
+
"@mui/icons-material": ">=9.0.0 <10.0.0",
|
|
42
|
+
"@mui/material": ">=9.0.0 <10.0.0",
|
|
43
|
+
"@mui/x-date-pickers": ">=9.0.0 <10.0.0",
|
|
44
44
|
"axios": ">=1.0.0 <2.0.0",
|
|
45
45
|
"dayjs": ">=1.11.0 <2.0.0",
|
|
46
46
|
"react": ">=19.0.0 <20.0.0",
|