com-angel-authorization 1.0.5 → 1.0.7

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.
@@ -22,6 +22,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  var react_exports = {};
23
23
  __export(react_exports, {
24
24
  Can: () => Can,
25
+ MENU_LIST_TYPE_PARAM: () => MENU_LIST_TYPE_PARAM,
26
+ MENU_TYPE_BUTTON: () => MENU_TYPE_BUTTON,
27
+ MENU_TYPE_LABEL: () => MENU_TYPE_LABEL,
28
+ MENU_TYPE_MENU: () => MENU_TYPE_MENU,
29
+ MENU_TYPE_OPTIONS: () => MENU_TYPE_OPTIONS,
30
+ MENU_TYPE_PAGE: () => MENU_TYPE_PAGE,
31
+ MENU_VISIBILITY_OPTIONS: () => MENU_VISIBILITY_OPTIONS,
32
+ MenuManager: () => MenuManager,
25
33
  PermissionProvider: () => PermissionProvider,
26
34
  PermissionStore: () => PermissionStore,
27
35
  RESOURCE_PRIVATE_OPTIONS: () => RESOURCE_PRIVATE_OPTIONS,
@@ -29,18 +37,26 @@ __export(react_exports, {
29
37
  RESOURCE_STATUS_ENABLED: () => RESOURCE_STATUS_ENABLED,
30
38
  RESOURCE_STATUS_OPTIONS: () => RESOURCE_STATUS_OPTIONS,
31
39
  RESOURCE_TYPE_API: () => RESOURCE_TYPE_API,
40
+ ROOT_PARENT_ID: () => ROOT_PARENT_ID,
32
41
  ResourceManager: () => ResourceManager,
42
+ SYSTEM_ADMIN_DEFAULT_KEY: () => SYSTEM_ADMIN_DEFAULT_KEY,
43
+ SYSTEM_ADMIN_MENU: () => SYSTEM_ADMIN_MENU,
44
+ SystemAdmin: () => SystemAdmin,
33
45
  appendQueryParam: () => appendQueryParam,
34
46
  buildCreateBody: () => buildCreateBody,
47
+ buildCreateMenuBody: () => buildCreateMenuBody,
35
48
  buildUpdateBody: () => buildUpdateBody,
49
+ buildUpdateMenuBody: () => buildUpdateMenuBody,
36
50
  createAuthorizationResourceApi: () => createAuthorizationResourceApi,
37
51
  createDefaultResourceRequest: () => createDefaultResourceRequest,
52
+ createMenuResourceApi: () => createMenuResourceApi,
38
53
  createPermissionStore: () => createPermissionStore,
39
54
  extractPagination: () => extractPagination,
40
55
  extractRecords: () => extractRecords,
41
56
  getAppClientId: () => getAppClientId,
42
57
  getDeviceWorkerId: () => getDeviceWorkerId,
43
58
  mapAuthorizationResource: () => mapAuthorizationResource,
59
+ mapMenuResource: () => mapMenuResource,
44
60
  snowyflake: () => snowyflake,
45
61
  useHasPermission: () => useHasPermission,
46
62
  useHasRole: () => useHasRole,
@@ -268,16 +284,35 @@ var import_react2 = require("react");
268
284
 
269
285
  // src/resources/types.ts
270
286
  var RESOURCE_TYPE_API = "api";
287
+ var MENU_TYPE_PAGE = "page";
288
+ var MENU_TYPE_MENU = "menu";
289
+ var MENU_TYPE_BUTTON = "button";
290
+ var MENU_LIST_TYPE_PARAM = "page,menu,button";
291
+ var ROOT_PARENT_ID = "0";
271
292
  var RESOURCE_STATUS_ENABLED = 1;
272
293
  var RESOURCE_STATUS_DISABLED = 0;
273
294
  var RESOURCE_STATUS_OPTIONS = [
274
295
  { label: "\u542F\u7528", value: RESOURCE_STATUS_ENABLED },
275
296
  { label: "\u7981\u7528", value: RESOURCE_STATUS_DISABLED }
276
297
  ];
298
+ var MENU_VISIBILITY_OPTIONS = [
299
+ { label: "\u663E\u793A", value: RESOURCE_STATUS_ENABLED },
300
+ { label: "\u9690\u85CF", value: RESOURCE_STATUS_DISABLED }
301
+ ];
277
302
  var RESOURCE_PRIVATE_OPTIONS = [
278
303
  { label: "\u662F", value: true },
279
304
  { label: "\u5426", value: false }
280
305
  ];
306
+ var MENU_TYPE_OPTIONS = [
307
+ { label: "\u76EE\u5F55", value: MENU_TYPE_PAGE },
308
+ { label: "\u83DC\u5355", value: MENU_TYPE_MENU },
309
+ { label: "\u6309\u94AE", value: MENU_TYPE_BUTTON }
310
+ ];
311
+ var MENU_TYPE_LABEL = {
312
+ page: "\u76EE\u5F55",
313
+ menu: "\u83DC\u5355",
314
+ button: "\u6309\u94AE"
315
+ };
281
316
 
282
317
  // src/utils/snowflake.ts
283
318
  var DEVICE_WORKER_ID_KEY = "hgams_device_worker_id";
@@ -422,6 +457,29 @@ function toBoolean(value) {
422
457
  }
423
458
  return false;
424
459
  }
460
+ function toStringArray(value) {
461
+ if (Array.isArray(value)) {
462
+ return value.map((item) => {
463
+ if (item && typeof item === "object") {
464
+ const row = item;
465
+ const id = row.resourceId ?? row.resource_id ?? row.id;
466
+ return id === void 0 || id === null ? "" : String(id);
467
+ }
468
+ return String(item ?? "");
469
+ }).filter(Boolean);
470
+ }
471
+ if (typeof value === "string" && value.trim()) {
472
+ return value.split(",").map((s) => s.trim()).filter(Boolean);
473
+ }
474
+ return [];
475
+ }
476
+ function toMenuType(value) {
477
+ const v = String(value ?? "").toLowerCase();
478
+ if (v === MENU_TYPE_PAGE || v === MENU_TYPE_MENU || v === MENU_TYPE_BUTTON) {
479
+ return v;
480
+ }
481
+ return MENU_TYPE_MENU;
482
+ }
425
483
  function mapAuthorizationResource(item) {
426
484
  if (!item || typeof item !== "object") return null;
427
485
  const row = item;
@@ -437,9 +495,31 @@ function mapAuthorizationResource(item) {
437
495
  description: String(row.description ?? row.desc ?? "")
438
496
  };
439
497
  }
440
- function buildListUrl(params) {
498
+ function mapMenuResource(item) {
499
+ if (!item || typeof item !== "object") return null;
500
+ const row = item;
501
+ const resourceId = row.resourceId ?? row.resource_id ?? row.id;
502
+ if (resourceId === void 0 || resourceId === null || resourceId === "") return null;
503
+ const permissionPointIds = toStringArray(
504
+ row.permissionPointIds ?? row.permission_point_ids ?? row.permissionPoints ?? row.permissions
505
+ );
506
+ const permissionNamesRaw = row.permissionPointNames ?? row.permission_point_names ?? row.permissionNames;
507
+ const permissionPointNames = Array.isArray(permissionNamesRaw) ? permissionNamesRaw.map((n) => String(n ?? "")).filter(Boolean) : void 0;
508
+ const parentId = row.parentId ?? row.parent_id ?? ROOT_PARENT_ID;
509
+ return {
510
+ resourceId: String(resourceId),
511
+ parentId: parentId === void 0 || parentId === null ? ROOT_PARENT_ID : String(parentId),
512
+ type: toMenuType(row.type),
513
+ name: String(row.name ?? ""),
514
+ identification: String(row.identification ?? row.identity ?? row.path ?? ""),
515
+ permissionPointIds,
516
+ permissionPointNames,
517
+ status: toResourceStatus(row.status)
518
+ };
519
+ }
520
+ function buildListUrl(type, params) {
441
521
  const parts = [];
442
- appendQueryParam(parts, "type", RESOURCE_TYPE_API);
522
+ appendQueryParam(parts, "type", type);
443
523
  appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
444
524
  appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
445
525
  appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
@@ -466,12 +546,33 @@ function buildUpdateBody(values) {
466
546
  description: values.description.trim()
467
547
  };
468
548
  }
549
+ function buildCreateMenuBody(values, resourceId = getAppClientId()) {
550
+ return {
551
+ resourceId,
552
+ parentId: values.parentId || ROOT_PARENT_ID,
553
+ type: values.type,
554
+ name: values.name.trim(),
555
+ identification: values.identification.trim(),
556
+ permissionPointIds: [...values.permissionPointIds],
557
+ status: values.status
558
+ };
559
+ }
560
+ function buildUpdateMenuBody(values) {
561
+ return {
562
+ parentId: values.parentId || ROOT_PARENT_ID,
563
+ type: values.type,
564
+ name: values.name.trim(),
565
+ identification: values.identification.trim(),
566
+ permissionPointIds: [...values.permissionPointIds],
567
+ status: values.status
568
+ };
569
+ }
469
570
  function createAuthorizationResourceApi(request) {
470
571
  return {
471
572
  async list(params, signal) {
472
573
  const json = await request({
473
574
  method: "GET",
474
- url: buildListUrl(params),
575
+ url: buildListUrl(RESOURCE_TYPE_API, params),
475
576
  signal
476
577
  });
477
578
  const records = extractRecords(json).map(mapAuthorizationResource).filter((item) => item !== null);
@@ -506,6 +607,50 @@ function createAuthorizationResourceApi(request) {
506
607
  }
507
608
  };
508
609
  }
610
+ function createMenuResourceApi(request) {
611
+ const permissionApi = createAuthorizationResourceApi(request);
612
+ return {
613
+ async list(params, signal) {
614
+ const json = await request({
615
+ method: "GET",
616
+ url: buildListUrl(MENU_LIST_TYPE_PARAM, params),
617
+ signal
618
+ });
619
+ const records = extractRecords(json).map(mapMenuResource).filter((item) => item !== null);
620
+ const pagination = extractPagination(json);
621
+ return {
622
+ records,
623
+ ...pagination
624
+ };
625
+ },
626
+ listPermissionPoints(params, signal) {
627
+ return permissionApi.list(params, signal);
628
+ },
629
+ async create(values, signal) {
630
+ return request({
631
+ method: "POST",
632
+ url: "/authorization-resources",
633
+ body: buildCreateMenuBody(values),
634
+ signal
635
+ });
636
+ },
637
+ async update(resourceId, values, signal) {
638
+ return request({
639
+ method: "PATCH",
640
+ url: `/authorization-resources/${encodeURIComponent(resourceId)}`,
641
+ body: buildUpdateMenuBody(values),
642
+ signal
643
+ });
644
+ },
645
+ async remove(resourceId, signal) {
646
+ return request({
647
+ method: "DELETE",
648
+ url: `/authorization-resources/${encodeURIComponent(resourceId)}`,
649
+ signal
650
+ });
651
+ }
652
+ };
653
+ }
509
654
  function createDefaultResourceRequest(options = {}) {
510
655
  const baseUrl = (options.baseUrl ?? "").replace(/\/+$/, "");
511
656
  const credentials = options.credentials ?? "include";
@@ -1072,9 +1217,782 @@ var styles = {
1072
1217
  paddingTop: 4
1073
1218
  }
1074
1219
  };
1220
+
1221
+ // src/react/MenuManager.tsx
1222
+ var import_react3 = require("react");
1223
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1224
+ var PAGE_SIZE_OPTIONS2 = ["10", "20", "50", "100"];
1225
+ var emptyForm2 = () => ({
1226
+ parentId: ROOT_PARENT_ID,
1227
+ type: MENU_TYPE_MENU,
1228
+ name: "",
1229
+ identification: "",
1230
+ permissionPointIds: [],
1231
+ status: RESOURCE_STATUS_ENABLED
1232
+ });
1233
+ function MenuManager({
1234
+ api,
1235
+ title = "\u83DC\u5355\u7BA1\u7406",
1236
+ pageSize: initialPageSize = "20",
1237
+ toolbarExtra
1238
+ }) {
1239
+ const [records, setRecords] = (0, import_react3.useState)([]);
1240
+ const [permissionPoints, setPermissionPoints] = (0, import_react3.useState)([]);
1241
+ const [loading, setLoading] = (0, import_react3.useState)(false);
1242
+ const [error, setError] = (0, import_react3.useState)("");
1243
+ const [pageSize, setPageSize] = (0, import_react3.useState)(initialPageSize);
1244
+ const [pageToken, setPageToken] = (0, import_react3.useState)("");
1245
+ const [hasPreviousPage, setHasPreviousPage] = (0, import_react3.useState)(false);
1246
+ const [hasNextPage, setHasNextPage] = (0, import_react3.useState)(false);
1247
+ const [dialogOpen, setDialogOpen] = (0, import_react3.useState)(false);
1248
+ const [editing, setEditing] = (0, import_react3.useState)(null);
1249
+ const [form, setForm] = (0, import_react3.useState)(emptyForm2);
1250
+ const [saving, setSaving] = (0, import_react3.useState)(false);
1251
+ const [deletingRow, setDeletingRow] = (0, import_react3.useState)(null);
1252
+ const [deleting, setDeleting] = (0, import_react3.useState)(false);
1253
+ const permissionNameMap = (0, import_react3.useMemo)(() => {
1254
+ const map = /* @__PURE__ */ new Map();
1255
+ permissionPoints.forEach((p) => map.set(p.resourceId, p.name || p.identification));
1256
+ return map;
1257
+ }, [permissionPoints]);
1258
+ const parentOptions = (0, import_react3.useMemo)(() => {
1259
+ return records.filter((row) => !editing || row.resourceId !== editing.resourceId).map((row) => ({
1260
+ value: row.resourceId,
1261
+ label: `${row.name}\uFF08${MENU_TYPE_LABEL[row.type]}\uFF09`
1262
+ }));
1263
+ }, [records, editing]);
1264
+ const loadList = (0, import_react3.useCallback)(
1265
+ async (direction = "current", token = pageToken) => {
1266
+ setLoading(true);
1267
+ setError("");
1268
+ try {
1269
+ const result = await api.list({
1270
+ pagination: {
1271
+ pageToken: token,
1272
+ pageSize,
1273
+ pageDirection: direction
1274
+ }
1275
+ });
1276
+ setRecords(result.records);
1277
+ setPageToken(result.pageToken);
1278
+ setHasPreviousPage(result.hasPreviousPage);
1279
+ setHasNextPage(result.hasNextPage);
1280
+ } catch (err) {
1281
+ setError(err instanceof Error ? err.message : "\u52A0\u8F7D\u5931\u8D25");
1282
+ } finally {
1283
+ setLoading(false);
1284
+ }
1285
+ },
1286
+ [api, pageSize, pageToken]
1287
+ );
1288
+ const loadPermissionPoints = (0, import_react3.useCallback)(async () => {
1289
+ try {
1290
+ const result = await api.listPermissionPoints({
1291
+ pagination: { pageSize: "200", pageDirection: "current" }
1292
+ });
1293
+ setPermissionPoints(result.records);
1294
+ } catch {
1295
+ }
1296
+ }, [api]);
1297
+ (0, import_react3.useEffect)(() => {
1298
+ void loadList("current", "");
1299
+ void loadPermissionPoints();
1300
+ }, [api, pageSize]);
1301
+ const openCreate = () => {
1302
+ setEditing(null);
1303
+ setForm(emptyForm2());
1304
+ setDialogOpen(true);
1305
+ void loadPermissionPoints();
1306
+ };
1307
+ const openEdit = (row) => {
1308
+ setEditing(row);
1309
+ setForm({
1310
+ parentId: row.parentId || ROOT_PARENT_ID,
1311
+ type: row.type,
1312
+ name: row.name,
1313
+ identification: row.identification,
1314
+ permissionPointIds: [...row.permissionPointIds],
1315
+ status: row.status
1316
+ });
1317
+ setDialogOpen(true);
1318
+ void loadPermissionPoints();
1319
+ };
1320
+ const closeDialog = () => {
1321
+ if (saving) return;
1322
+ setDialogOpen(false);
1323
+ };
1324
+ const handleSubmit = async (event) => {
1325
+ event.preventDefault();
1326
+ if (!form.name.trim()) {
1327
+ setError("\u8BF7\u586B\u5199\u83DC\u5355\u540D\u79F0");
1328
+ return;
1329
+ }
1330
+ setSaving(true);
1331
+ setError("");
1332
+ try {
1333
+ if (editing) {
1334
+ await api.update(editing.resourceId, form);
1335
+ } else {
1336
+ await api.create(form);
1337
+ }
1338
+ setDialogOpen(false);
1339
+ await loadList("current", "");
1340
+ } catch (err) {
1341
+ setError(err instanceof Error ? err.message : "\u4FDD\u5B58\u5931\u8D25");
1342
+ } finally {
1343
+ setSaving(false);
1344
+ }
1345
+ };
1346
+ const askDelete = (row) => setDeletingRow(row);
1347
+ const closeDeleteDialog = () => {
1348
+ if (!deleting) setDeletingRow(null);
1349
+ };
1350
+ const confirmDelete = async () => {
1351
+ if (!deletingRow) return;
1352
+ setDeleting(true);
1353
+ setError("");
1354
+ try {
1355
+ await api.remove(deletingRow.resourceId);
1356
+ setDeletingRow(null);
1357
+ await loadList("current", "");
1358
+ } catch (err) {
1359
+ setError(err instanceof Error ? err.message : "\u5220\u9664\u5931\u8D25");
1360
+ } finally {
1361
+ setDeleting(false);
1362
+ }
1363
+ };
1364
+ const togglePermission = (id) => {
1365
+ setForm((prev) => {
1366
+ const exists = prev.permissionPointIds.includes(id);
1367
+ return {
1368
+ ...prev,
1369
+ permissionPointIds: exists ? prev.permissionPointIds.filter((x) => x !== id) : [...prev.permissionPointIds, id]
1370
+ };
1371
+ });
1372
+ };
1373
+ const renderPermissionLabels = (row) => {
1374
+ if (row.permissionPointNames?.length) {
1375
+ return row.permissionPointNames.join("\u3001");
1376
+ }
1377
+ if (!row.permissionPointIds.length) return "\u2014";
1378
+ return row.permissionPointIds.map((id) => permissionNameMap.get(id) ?? id).join("\u3001");
1379
+ };
1380
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.root, children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.toolbar, children: [
1382
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: styles2.title, children: title }),
1383
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.toolbarRight, children: [
1384
+ toolbarExtra,
1385
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.primaryBtn, onClick: openCreate, children: "\u65B0\u589E" })
1386
+ ] })
1387
+ ] }),
1388
+ error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.error, children: error }) : null,
1389
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.tableWrap, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { style: styles2.table, children: [
1390
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
1391
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: styles2.th, children: "\u83DC\u5355\u540D\u79F0" }),
1392
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: styles2.th, children: "\u8BF7\u6C42\u5730\u5740" }),
1393
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: { ...styles2.th, width: 90 }, children: "\u7C7B\u578B" }),
1394
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: { ...styles2.th, width: 80 }, children: "\u53EF\u89C1" }),
1395
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: styles2.th, children: "\u6743\u9650\u6807\u8BC6" }),
1396
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: { ...styles2.th, width: 140 }, children: "\u64CD\u4F5C" })
1397
+ ] }) }),
1398
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tbody", { children: loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { colSpan: 6, style: styles2.empty, children: "\u52A0\u8F7D\u4E2D\u2026" }) }) : records.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { colSpan: 6, style: styles2.empty, children: "\u6682\u65E0\u6570\u636E" }) }) : records.map((row) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
1399
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: row.name }),
1400
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { style: styles2.code, children: row.identification || "\u2014" }) }),
1401
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: MENU_TYPE_LABEL[row.type] }),
1402
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1403
+ "span",
1404
+ {
1405
+ style: {
1406
+ ...styles2.badge,
1407
+ background: row.status === RESOURCE_STATUS_ENABLED ? "#e8f7ef" : "#f4f4f5",
1408
+ color: row.status === RESOURCE_STATUS_ENABLED ? "#067647" : "#667085"
1409
+ },
1410
+ children: row.status === RESOURCE_STATUS_ENABLED ? "\u663E\u793A" : "\u9690\u85CF"
1411
+ }
1412
+ ) }),
1413
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: renderPermissionLabels(row) }),
1414
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("td", { style: styles2.td, children: [
1415
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.linkBtn, onClick: () => openEdit(row), children: "\u7F16\u8F91" }),
1416
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1417
+ "button",
1418
+ {
1419
+ type: "button",
1420
+ style: { ...styles2.linkBtn, color: "#d92d20" },
1421
+ onClick: () => askDelete(row),
1422
+ children: "\u5220\u9664"
1423
+ }
1424
+ )
1425
+ ] })
1426
+ ] }, row.resourceId)) })
1427
+ ] }) }),
1428
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.pagination, children: [
1429
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.pageSize, children: [
1430
+ "\u6BCF\u9875",
1431
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1432
+ "select",
1433
+ {
1434
+ value: pageSize,
1435
+ onChange: (e) => {
1436
+ setPageToken("");
1437
+ setPageSize(e.target.value);
1438
+ },
1439
+ style: styles2.select,
1440
+ children: PAGE_SIZE_OPTIONS2.map((size) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: size, children: size }, size))
1441
+ }
1442
+ )
1443
+ ] }),
1444
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.pageBtns, children: [
1445
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1446
+ "button",
1447
+ {
1448
+ type: "button",
1449
+ style: styles2.secondaryBtn,
1450
+ disabled: !hasPreviousPage || loading,
1451
+ onClick: () => void loadList("previous"),
1452
+ children: "\u4E0A\u4E00\u9875"
1453
+ }
1454
+ ),
1455
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1456
+ "button",
1457
+ {
1458
+ type: "button",
1459
+ style: styles2.secondaryBtn,
1460
+ disabled: !hasNextPage || loading,
1461
+ onClick: () => void loadList("next"),
1462
+ children: "\u4E0B\u4E00\u9875"
1463
+ }
1464
+ )
1465
+ ] })
1466
+ ] }),
1467
+ dialogOpen ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.mask, onClick: closeDialog, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1468
+ "div",
1469
+ {
1470
+ style: { ...styles2.dialog, maxWidth: 520 },
1471
+ onClick: (e) => e.stopPropagation(),
1472
+ role: "dialog",
1473
+ "aria-modal": "true",
1474
+ children: [
1475
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogHeader, children: [
1476
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: styles2.dialogTitle, children: editing ? "\u7F16\u8F91\u83DC\u5355" : "\u65B0\u589E\u83DC\u5355" }),
1477
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.iconBtn, onClick: closeDialog, "aria-label": "\u5173\u95ED", children: "\xD7" })
1478
+ ] }),
1479
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { style: styles2.form, onSubmit: (e) => void handleSubmit(e), children: [
1480
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.field, children: [
1481
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles2.label, children: "\u4E0A\u7EA7\u83DC\u5355" }),
1482
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1483
+ "select",
1484
+ {
1485
+ style: styles2.input,
1486
+ value: form.parentId,
1487
+ onChange: (e) => setForm((prev) => ({ ...prev, parentId: e.target.value })),
1488
+ children: [
1489
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: ROOT_PARENT_ID, children: "\u6839\u76EE\u5F55" }),
1490
+ parentOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1491
+ ]
1492
+ }
1493
+ )
1494
+ ] }),
1495
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("fieldset", { style: styles2.fieldset, children: [
1496
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("legend", { style: styles2.label, children: "\u83DC\u5355\u7C7B\u578B" }),
1497
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.radioGroup, children: MENU_TYPE_OPTIONS.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.radioItem, children: [
1498
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1499
+ "input",
1500
+ {
1501
+ type: "radio",
1502
+ name: "menu-type",
1503
+ checked: form.type === opt.value,
1504
+ onChange: () => setForm((prev) => ({
1505
+ ...prev,
1506
+ type: opt.value
1507
+ }))
1508
+ }
1509
+ ),
1510
+ opt.label
1511
+ ] }, opt.value)) })
1512
+ ] }),
1513
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.field, children: [
1514
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles2.label, children: "\u83DC\u5355\u540D\u79F0" }),
1515
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1516
+ "input",
1517
+ {
1518
+ style: styles2.input,
1519
+ value: form.name,
1520
+ onChange: (e) => setForm((prev) => ({ ...prev, name: e.target.value })),
1521
+ placeholder: "\u8BF7\u8F93\u5165\u83DC\u5355\u540D\u79F0",
1522
+ required: true
1523
+ }
1524
+ )
1525
+ ] }),
1526
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.field, children: [
1527
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles2.label, children: "\u8BF7\u6C42\u5730\u5740" }),
1528
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1529
+ "input",
1530
+ {
1531
+ style: styles2.input,
1532
+ value: form.identification,
1533
+ onChange: (e) => setForm((prev) => ({ ...prev, identification: e.target.value })),
1534
+ placeholder: "\u5982 /system/user"
1535
+ }
1536
+ )
1537
+ ] }),
1538
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("fieldset", { style: styles2.fieldset, children: [
1539
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("legend", { style: styles2.label, children: "\u6743\u9650\u6807\u8BC6" }),
1540
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.multiSelect, children: permissionPoints.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.hint, children: "\u6682\u65E0\u6743\u9650\u70B9\uFF0C\u8BF7\u5148\u5728\u6743\u9650\u70B9\u7BA1\u7406\u4E2D\u65B0\u589E" }) : permissionPoints.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.checkItem, children: [
1541
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1542
+ "input",
1543
+ {
1544
+ type: "checkbox",
1545
+ checked: form.permissionPointIds.includes(p.resourceId),
1546
+ onChange: () => togglePermission(p.resourceId)
1547
+ }
1548
+ ),
1549
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
1550
+ p.name,
1551
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { style: { ...styles2.code, marginLeft: 6 }, children: p.identification })
1552
+ ] })
1553
+ ] }, p.resourceId)) })
1554
+ ] }),
1555
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("fieldset", { style: styles2.fieldset, children: [
1556
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("legend", { style: styles2.label, children: "\u72B6\u6001" }),
1557
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.radioGroup, children: MENU_VISIBILITY_OPTIONS.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.radioItem, children: [
1558
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1559
+ "input",
1560
+ {
1561
+ type: "radio",
1562
+ name: "menu-status",
1563
+ checked: form.status === opt.value,
1564
+ onChange: () => setForm((prev) => ({ ...prev, status: opt.value }))
1565
+ }
1566
+ ),
1567
+ opt.label
1568
+ ] }, opt.value)) })
1569
+ ] }),
1570
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogFooter, children: [
1571
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.secondaryBtn, onClick: closeDialog, children: "\u53D6\u6D88" }),
1572
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", style: styles2.primaryBtn, disabled: saving, children: saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58" })
1573
+ ] })
1574
+ ] })
1575
+ ]
1576
+ }
1577
+ ) }) : null,
1578
+ deletingRow ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.mask, onClick: closeDeleteDialog, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1579
+ "div",
1580
+ {
1581
+ style: { ...styles2.dialog, maxWidth: 420 },
1582
+ onClick: (e) => e.stopPropagation(),
1583
+ role: "dialog",
1584
+ "aria-modal": "true",
1585
+ children: [
1586
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogHeader, children: [
1587
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: styles2.dialogTitle, children: "\u786E\u8BA4\u5220\u9664" }),
1588
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1589
+ "button",
1590
+ {
1591
+ type: "button",
1592
+ style: styles2.iconBtn,
1593
+ onClick: closeDeleteDialog,
1594
+ "aria-label": "\u5173\u95ED",
1595
+ children: "\xD7"
1596
+ }
1597
+ )
1598
+ ] }),
1599
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.confirmBody, children: [
1600
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { style: styles2.confirmText, children: [
1601
+ "\u786E\u8BA4\u5220\u9664\u83DC\u5355\u300C",
1602
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: deletingRow.name }),
1603
+ "\u300D\u5417\uFF1F\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\u3002"
1604
+ ] }),
1605
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogFooter, children: [
1606
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1607
+ "button",
1608
+ {
1609
+ type: "button",
1610
+ style: styles2.secondaryBtn,
1611
+ onClick: closeDeleteDialog,
1612
+ disabled: deleting,
1613
+ children: "\u53D6\u6D88"
1614
+ }
1615
+ ),
1616
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1617
+ "button",
1618
+ {
1619
+ type: "button",
1620
+ style: styles2.dangerBtn,
1621
+ onClick: () => void confirmDelete(),
1622
+ disabled: deleting,
1623
+ children: deleting ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u5220\u9664"
1624
+ }
1625
+ )
1626
+ ] })
1627
+ ] })
1628
+ ]
1629
+ }
1630
+ ) }) : null
1631
+ ] });
1632
+ }
1633
+ var styles2 = {
1634
+ root: {
1635
+ display: "flex",
1636
+ flexDirection: "column",
1637
+ gap: 16,
1638
+ padding: 16,
1639
+ color: "#101828",
1640
+ fontFamily: '"PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, sans-serif'
1641
+ },
1642
+ toolbar: {
1643
+ display: "flex",
1644
+ alignItems: "center",
1645
+ justifyContent: "space-between",
1646
+ gap: 12
1647
+ },
1648
+ title: { margin: 0, fontSize: 18, fontWeight: 600 },
1649
+ toolbarRight: { display: "flex", alignItems: "center", gap: 8 },
1650
+ error: {
1651
+ padding: "10px 12px",
1652
+ borderRadius: 8,
1653
+ background: "#fef3f2",
1654
+ color: "#b42318",
1655
+ fontSize: 13
1656
+ },
1657
+ tableWrap: {
1658
+ overflow: "auto",
1659
+ border: "1px solid #eaecf0",
1660
+ borderRadius: 10,
1661
+ background: "#fff"
1662
+ },
1663
+ table: { width: "100%", borderCollapse: "collapse", minWidth: 820 },
1664
+ th: {
1665
+ textAlign: "left",
1666
+ padding: "12px 14px",
1667
+ fontSize: 13,
1668
+ fontWeight: 600,
1669
+ color: "#475467",
1670
+ background: "#f9fafb",
1671
+ borderBottom: "1px solid #eaecf0"
1672
+ },
1673
+ td: {
1674
+ padding: "12px 14px",
1675
+ fontSize: 14,
1676
+ borderBottom: "1px solid #f2f4f7",
1677
+ verticalAlign: "middle"
1678
+ },
1679
+ empty: { padding: 28, textAlign: "center", color: "#98a2b3", fontSize: 14 },
1680
+ code: {
1681
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
1682
+ fontSize: 13,
1683
+ background: "#f2f4f7",
1684
+ padding: "2px 6px",
1685
+ borderRadius: 4
1686
+ },
1687
+ badge: {
1688
+ display: "inline-block",
1689
+ padding: "2px 8px",
1690
+ borderRadius: 999,
1691
+ fontSize: 12,
1692
+ fontWeight: 500
1693
+ },
1694
+ linkBtn: {
1695
+ border: "none",
1696
+ background: "transparent",
1697
+ color: "#049BAD",
1698
+ cursor: "pointer",
1699
+ padding: "0 8px 0 0",
1700
+ fontSize: 13
1701
+ },
1702
+ pagination: {
1703
+ display: "flex",
1704
+ alignItems: "center",
1705
+ justifyContent: "space-between",
1706
+ gap: 12
1707
+ },
1708
+ pageSize: { display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "#475467" },
1709
+ pageBtns: { display: "flex", gap: 8 },
1710
+ primaryBtn: {
1711
+ border: "none",
1712
+ background: "#049BAD",
1713
+ color: "#fff",
1714
+ borderRadius: 8,
1715
+ padding: "8px 14px",
1716
+ cursor: "pointer",
1717
+ fontSize: 14
1718
+ },
1719
+ secondaryBtn: {
1720
+ border: "1px solid #d0d5dd",
1721
+ background: "#fff",
1722
+ color: "#344054",
1723
+ borderRadius: 8,
1724
+ padding: "8px 14px",
1725
+ cursor: "pointer",
1726
+ fontSize: 14
1727
+ },
1728
+ dangerBtn: {
1729
+ border: "none",
1730
+ background: "#d92d20",
1731
+ color: "#fff",
1732
+ borderRadius: 8,
1733
+ padding: "8px 14px",
1734
+ cursor: "pointer",
1735
+ fontSize: 14
1736
+ },
1737
+ select: {
1738
+ border: "1px solid #d0d5dd",
1739
+ borderRadius: 6,
1740
+ padding: "4px 8px",
1741
+ fontSize: 13,
1742
+ backgroundColor: "#ffffff",
1743
+ color: "#101828"
1744
+ },
1745
+ mask: {
1746
+ position: "fixed",
1747
+ inset: 0,
1748
+ background: "rgba(16, 24, 40, 0.45)",
1749
+ display: "flex",
1750
+ alignItems: "center",
1751
+ justifyContent: "center",
1752
+ zIndex: 1e3,
1753
+ padding: 16
1754
+ },
1755
+ dialog: {
1756
+ width: "100%",
1757
+ maxWidth: 480,
1758
+ background: "#fff",
1759
+ borderRadius: 12,
1760
+ boxShadow: "0 20px 40px rgba(16,24,40,0.18)",
1761
+ maxHeight: "90vh",
1762
+ overflow: "auto"
1763
+ },
1764
+ dialogHeader: {
1765
+ display: "flex",
1766
+ alignItems: "center",
1767
+ justifyContent: "space-between",
1768
+ padding: "14px 16px",
1769
+ borderBottom: "1px solid #eaecf0",
1770
+ position: "sticky",
1771
+ top: 0,
1772
+ background: "#fff",
1773
+ zIndex: 1
1774
+ },
1775
+ dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },
1776
+ iconBtn: {
1777
+ border: "none",
1778
+ background: "transparent",
1779
+ fontSize: 22,
1780
+ lineHeight: 1,
1781
+ cursor: "pointer",
1782
+ color: "#667085"
1783
+ },
1784
+ form: { display: "flex", flexDirection: "column", gap: 12, padding: 16 },
1785
+ confirmBody: { display: "flex", flexDirection: "column", gap: 16, padding: 16 },
1786
+ confirmText: { margin: 0, fontSize: 14, color: "#344054", lineHeight: 1.6 },
1787
+ field: { display: "flex", flexDirection: "column", gap: 6 },
1788
+ fieldset: {
1789
+ margin: 0,
1790
+ padding: 0,
1791
+ border: "none",
1792
+ display: "flex",
1793
+ flexDirection: "column",
1794
+ gap: 8
1795
+ },
1796
+ label: { fontSize: 13, color: "#344054", fontWeight: 500 },
1797
+ input: {
1798
+ border: "1px solid #d0d5dd",
1799
+ borderRadius: 8,
1800
+ padding: "8px 10px",
1801
+ fontSize: 14,
1802
+ outline: "none",
1803
+ backgroundColor: "#ffffff",
1804
+ color: "#101828",
1805
+ boxSizing: "border-box",
1806
+ width: "100%"
1807
+ },
1808
+ radioGroup: { display: "flex", flexWrap: "wrap", gap: 16 },
1809
+ radioItem: {
1810
+ display: "flex",
1811
+ alignItems: "center",
1812
+ gap: 6,
1813
+ fontSize: 14,
1814
+ color: "#344054",
1815
+ cursor: "pointer"
1816
+ },
1817
+ multiSelect: {
1818
+ maxHeight: 160,
1819
+ overflow: "auto",
1820
+ border: "1px solid #eaecf0",
1821
+ borderRadius: 8,
1822
+ padding: 8,
1823
+ background: "#f9fafb"
1824
+ },
1825
+ checkItem: {
1826
+ display: "flex",
1827
+ alignItems: "center",
1828
+ gap: 8,
1829
+ padding: "6px 4px",
1830
+ fontSize: 13,
1831
+ color: "#344054",
1832
+ cursor: "pointer"
1833
+ },
1834
+ hint: { fontSize: 13, color: "#98a2b3", padding: 8 },
1835
+ dialogFooter: {
1836
+ display: "flex",
1837
+ justifyContent: "flex-end",
1838
+ gap: 8,
1839
+ paddingTop: 4
1840
+ }
1841
+ };
1842
+
1843
+ // src/react/SystemAdmin.tsx
1844
+ var import_react4 = require("react");
1845
+
1846
+ // src/admin/menu.ts
1847
+ var SYSTEM_ADMIN_MENU = {
1848
+ key: "system",
1849
+ label: "\u7CFB\u7EDF\u7BA1\u7406",
1850
+ children: [
1851
+ { key: "menu", label: "\u83DC\u5355\u7BA1\u7406" },
1852
+ { key: "resource", label: "\u6743\u9650\u70B9\u7BA1\u7406" }
1853
+ ]
1854
+ };
1855
+ var SYSTEM_ADMIN_DEFAULT_KEY = "menu";
1856
+
1857
+ // src/react/SystemAdmin.tsx
1858
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1859
+ function SystemAdmin({
1860
+ menuApi,
1861
+ resourceApi,
1862
+ defaultActiveKey = SYSTEM_ADMIN_DEFAULT_KEY,
1863
+ activeKey: controlledKey,
1864
+ onActiveKeyChange,
1865
+ title = SYSTEM_ADMIN_MENU.label,
1866
+ toolbarExtra
1867
+ }) {
1868
+ const [innerKey, setInnerKey] = (0, import_react4.useState)(defaultActiveKey);
1869
+ const activeKey = controlledKey ?? innerKey;
1870
+ const setActiveKey = (key) => {
1871
+ if (controlledKey === void 0) setInnerKey(key);
1872
+ onActiveKeyChange?.(key);
1873
+ };
1874
+ const activeLabel = (0, import_react4.useMemo)(
1875
+ () => SYSTEM_ADMIN_MENU.children.find((item) => item.key === activeKey)?.label ?? "",
1876
+ [activeKey]
1877
+ );
1878
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles3.root, children: [
1879
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("aside", { style: styles3.sidebar, children: [
1880
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles3.sidebarTitle, children: title }),
1881
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("nav", { style: styles3.nav, children: SYSTEM_ADMIN_MENU.children.map((item) => {
1882
+ const active = item.key === activeKey;
1883
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1884
+ "button",
1885
+ {
1886
+ type: "button",
1887
+ style: {
1888
+ ...styles3.navItem,
1889
+ ...active ? styles3.navItemActive : null
1890
+ },
1891
+ onClick: () => setActiveKey(item.key),
1892
+ children: item.label
1893
+ },
1894
+ item.key
1895
+ );
1896
+ }) })
1897
+ ] }),
1898
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("main", { style: styles3.content, children: [
1899
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles3.contentHeader, children: [
1900
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles3.breadcrumb, children: [
1901
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles3.breadcrumbParent, children: title }),
1902
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles3.breadcrumbSep, children: "/" }),
1903
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles3.breadcrumbCurrent, children: activeLabel })
1904
+ ] }),
1905
+ toolbarExtra
1906
+ ] }),
1907
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles3.panel, children: activeKey === "menu" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MenuManager, { api: menuApi, title: "\u83DC\u5355\u7BA1\u7406" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ResourceManager, { api: resourceApi, title: "\u6743\u9650\u70B9\u7BA1\u7406" }) })
1908
+ ] })
1909
+ ] });
1910
+ }
1911
+ var styles3 = {
1912
+ root: {
1913
+ display: "flex",
1914
+ minHeight: 560,
1915
+ border: "1px solid #eaecf0",
1916
+ borderRadius: 12,
1917
+ overflow: "hidden",
1918
+ background: "#fff",
1919
+ fontFamily: '"PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, sans-serif',
1920
+ color: "#101828"
1921
+ },
1922
+ sidebar: {
1923
+ width: 200,
1924
+ flexShrink: 0,
1925
+ borderRight: "1px solid #eaecf0",
1926
+ background: "#f9fafb",
1927
+ padding: "16px 12px"
1928
+ },
1929
+ sidebarTitle: {
1930
+ fontSize: 14,
1931
+ fontWeight: 600,
1932
+ color: "#344054",
1933
+ padding: "4px 10px 12px"
1934
+ },
1935
+ nav: {
1936
+ display: "flex",
1937
+ flexDirection: "column",
1938
+ gap: 4
1939
+ },
1940
+ navItem: {
1941
+ border: "none",
1942
+ background: "transparent",
1943
+ textAlign: "left",
1944
+ padding: "10px 12px",
1945
+ borderRadius: 8,
1946
+ fontSize: 14,
1947
+ color: "#475467",
1948
+ cursor: "pointer"
1949
+ },
1950
+ navItemActive: {
1951
+ background: "#e6f7f9",
1952
+ color: "#049BAD",
1953
+ fontWeight: 600
1954
+ },
1955
+ content: {
1956
+ flex: 1,
1957
+ minWidth: 0,
1958
+ display: "flex",
1959
+ flexDirection: "column",
1960
+ background: "#fff"
1961
+ },
1962
+ contentHeader: {
1963
+ display: "flex",
1964
+ alignItems: "center",
1965
+ justifyContent: "space-between",
1966
+ gap: 12,
1967
+ padding: "12px 16px",
1968
+ borderBottom: "1px solid #f2f4f7"
1969
+ },
1970
+ breadcrumb: {
1971
+ display: "flex",
1972
+ alignItems: "center",
1973
+ gap: 8,
1974
+ fontSize: 13
1975
+ },
1976
+ breadcrumbParent: { color: "#98a2b3" },
1977
+ breadcrumbSep: { color: "#d0d5dd" },
1978
+ breadcrumbCurrent: { color: "#344054", fontWeight: 600 },
1979
+ panel: {
1980
+ flex: 1,
1981
+ minHeight: 0,
1982
+ overflow: "auto"
1983
+ }
1984
+ };
1075
1985
  // Annotate the CommonJS export names for ESM import in node:
1076
1986
  0 && (module.exports = {
1077
1987
  Can,
1988
+ MENU_LIST_TYPE_PARAM,
1989
+ MENU_TYPE_BUTTON,
1990
+ MENU_TYPE_LABEL,
1991
+ MENU_TYPE_MENU,
1992
+ MENU_TYPE_OPTIONS,
1993
+ MENU_TYPE_PAGE,
1994
+ MENU_VISIBILITY_OPTIONS,
1995
+ MenuManager,
1078
1996
  PermissionProvider,
1079
1997
  PermissionStore,
1080
1998
  RESOURCE_PRIVATE_OPTIONS,
@@ -1082,18 +2000,26 @@ var styles = {
1082
2000
  RESOURCE_STATUS_ENABLED,
1083
2001
  RESOURCE_STATUS_OPTIONS,
1084
2002
  RESOURCE_TYPE_API,
2003
+ ROOT_PARENT_ID,
1085
2004
  ResourceManager,
2005
+ SYSTEM_ADMIN_DEFAULT_KEY,
2006
+ SYSTEM_ADMIN_MENU,
2007
+ SystemAdmin,
1086
2008
  appendQueryParam,
1087
2009
  buildCreateBody,
2010
+ buildCreateMenuBody,
1088
2011
  buildUpdateBody,
2012
+ buildUpdateMenuBody,
1089
2013
  createAuthorizationResourceApi,
1090
2014
  createDefaultResourceRequest,
2015
+ createMenuResourceApi,
1091
2016
  createPermissionStore,
1092
2017
  extractPagination,
1093
2018
  extractRecords,
1094
2019
  getAppClientId,
1095
2020
  getDeviceWorkerId,
1096
2021
  mapAuthorizationResource,
2022
+ mapMenuResource,
1097
2023
  snowyflake,
1098
2024
  useHasPermission,
1099
2025
  useHasRole,