com-angel-authorization 1.0.4 → 1.0.6

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,23 @@ __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,
33
42
  appendQueryParam: () => appendQueryParam,
34
43
  buildCreateBody: () => buildCreateBody,
44
+ buildCreateMenuBody: () => buildCreateMenuBody,
35
45
  buildUpdateBody: () => buildUpdateBody,
46
+ buildUpdateMenuBody: () => buildUpdateMenuBody,
36
47
  createAuthorizationResourceApi: () => createAuthorizationResourceApi,
37
48
  createDefaultResourceRequest: () => createDefaultResourceRequest,
49
+ createMenuResourceApi: () => createMenuResourceApi,
38
50
  createPermissionStore: () => createPermissionStore,
39
51
  extractPagination: () => extractPagination,
40
52
  extractRecords: () => extractRecords,
41
53
  getAppClientId: () => getAppClientId,
42
54
  getDeviceWorkerId: () => getDeviceWorkerId,
43
55
  mapAuthorizationResource: () => mapAuthorizationResource,
56
+ mapMenuResource: () => mapMenuResource,
44
57
  snowyflake: () => snowyflake,
45
58
  useHasPermission: () => useHasPermission,
46
59
  useHasRole: () => useHasRole,
@@ -268,16 +281,35 @@ var import_react2 = require("react");
268
281
 
269
282
  // src/resources/types.ts
270
283
  var RESOURCE_TYPE_API = "api";
284
+ var MENU_TYPE_PAGE = "page";
285
+ var MENU_TYPE_MENU = "menu";
286
+ var MENU_TYPE_BUTTON = "button";
287
+ var MENU_LIST_TYPE_PARAM = "page,menu,button";
288
+ var ROOT_PARENT_ID = "0";
271
289
  var RESOURCE_STATUS_ENABLED = 1;
272
290
  var RESOURCE_STATUS_DISABLED = 0;
273
291
  var RESOURCE_STATUS_OPTIONS = [
274
292
  { label: "\u542F\u7528", value: RESOURCE_STATUS_ENABLED },
275
293
  { label: "\u7981\u7528", value: RESOURCE_STATUS_DISABLED }
276
294
  ];
295
+ var MENU_VISIBILITY_OPTIONS = [
296
+ { label: "\u663E\u793A", value: RESOURCE_STATUS_ENABLED },
297
+ { label: "\u9690\u85CF", value: RESOURCE_STATUS_DISABLED }
298
+ ];
277
299
  var RESOURCE_PRIVATE_OPTIONS = [
278
300
  { label: "\u662F", value: true },
279
301
  { label: "\u5426", value: false }
280
302
  ];
303
+ var MENU_TYPE_OPTIONS = [
304
+ { label: "\u76EE\u5F55", value: MENU_TYPE_PAGE },
305
+ { label: "\u83DC\u5355", value: MENU_TYPE_MENU },
306
+ { label: "\u6309\u94AE", value: MENU_TYPE_BUTTON }
307
+ ];
308
+ var MENU_TYPE_LABEL = {
309
+ page: "\u76EE\u5F55",
310
+ menu: "\u83DC\u5355",
311
+ button: "\u6309\u94AE"
312
+ };
281
313
 
282
314
  // src/utils/snowflake.ts
283
315
  var DEVICE_WORKER_ID_KEY = "hgams_device_worker_id";
@@ -422,6 +454,29 @@ function toBoolean(value) {
422
454
  }
423
455
  return false;
424
456
  }
457
+ function toStringArray(value) {
458
+ if (Array.isArray(value)) {
459
+ return value.map((item) => {
460
+ if (item && typeof item === "object") {
461
+ const row = item;
462
+ const id = row.resourceId ?? row.resource_id ?? row.id;
463
+ return id === void 0 || id === null ? "" : String(id);
464
+ }
465
+ return String(item ?? "");
466
+ }).filter(Boolean);
467
+ }
468
+ if (typeof value === "string" && value.trim()) {
469
+ return value.split(",").map((s) => s.trim()).filter(Boolean);
470
+ }
471
+ return [];
472
+ }
473
+ function toMenuType(value) {
474
+ const v = String(value ?? "").toLowerCase();
475
+ if (v === MENU_TYPE_PAGE || v === MENU_TYPE_MENU || v === MENU_TYPE_BUTTON) {
476
+ return v;
477
+ }
478
+ return MENU_TYPE_MENU;
479
+ }
425
480
  function mapAuthorizationResource(item) {
426
481
  if (!item || typeof item !== "object") return null;
427
482
  const row = item;
@@ -437,9 +492,31 @@ function mapAuthorizationResource(item) {
437
492
  description: String(row.description ?? row.desc ?? "")
438
493
  };
439
494
  }
440
- function buildListUrl(params) {
495
+ function mapMenuResource(item) {
496
+ if (!item || typeof item !== "object") return null;
497
+ const row = item;
498
+ const resourceId = row.resourceId ?? row.resource_id ?? row.id;
499
+ if (resourceId === void 0 || resourceId === null || resourceId === "") return null;
500
+ const permissionPointIds = toStringArray(
501
+ row.permissionPointIds ?? row.permission_point_ids ?? row.permissionPoints ?? row.permissions
502
+ );
503
+ const permissionNamesRaw = row.permissionPointNames ?? row.permission_point_names ?? row.permissionNames;
504
+ const permissionPointNames = Array.isArray(permissionNamesRaw) ? permissionNamesRaw.map((n) => String(n ?? "")).filter(Boolean) : void 0;
505
+ const parentId = row.parentId ?? row.parent_id ?? ROOT_PARENT_ID;
506
+ return {
507
+ resourceId: String(resourceId),
508
+ parentId: parentId === void 0 || parentId === null ? ROOT_PARENT_ID : String(parentId),
509
+ type: toMenuType(row.type),
510
+ name: String(row.name ?? ""),
511
+ identification: String(row.identification ?? row.identity ?? row.path ?? ""),
512
+ permissionPointIds,
513
+ permissionPointNames,
514
+ status: toResourceStatus(row.status)
515
+ };
516
+ }
517
+ function buildListUrl(type, params) {
441
518
  const parts = [];
442
- appendQueryParam(parts, "type", RESOURCE_TYPE_API);
519
+ appendQueryParam(parts, "type", type);
443
520
  appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
444
521
  appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
445
522
  appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
@@ -466,12 +543,33 @@ function buildUpdateBody(values) {
466
543
  description: values.description.trim()
467
544
  };
468
545
  }
546
+ function buildCreateMenuBody(values, resourceId = getAppClientId()) {
547
+ return {
548
+ resourceId,
549
+ parentId: values.parentId || ROOT_PARENT_ID,
550
+ type: values.type,
551
+ name: values.name.trim(),
552
+ identification: values.identification.trim(),
553
+ permissionPointIds: [...values.permissionPointIds],
554
+ status: values.status
555
+ };
556
+ }
557
+ function buildUpdateMenuBody(values) {
558
+ return {
559
+ parentId: values.parentId || ROOT_PARENT_ID,
560
+ type: values.type,
561
+ name: values.name.trim(),
562
+ identification: values.identification.trim(),
563
+ permissionPointIds: [...values.permissionPointIds],
564
+ status: values.status
565
+ };
566
+ }
469
567
  function createAuthorizationResourceApi(request) {
470
568
  return {
471
569
  async list(params, signal) {
472
570
  const json = await request({
473
571
  method: "GET",
474
- url: buildListUrl(params),
572
+ url: buildListUrl(RESOURCE_TYPE_API, params),
475
573
  signal
476
574
  });
477
575
  const records = extractRecords(json).map(mapAuthorizationResource).filter((item) => item !== null);
@@ -506,6 +604,50 @@ function createAuthorizationResourceApi(request) {
506
604
  }
507
605
  };
508
606
  }
607
+ function createMenuResourceApi(request) {
608
+ const permissionApi = createAuthorizationResourceApi(request);
609
+ return {
610
+ async list(params, signal) {
611
+ const json = await request({
612
+ method: "GET",
613
+ url: buildListUrl(MENU_LIST_TYPE_PARAM, params),
614
+ signal
615
+ });
616
+ const records = extractRecords(json).map(mapMenuResource).filter((item) => item !== null);
617
+ const pagination = extractPagination(json);
618
+ return {
619
+ records,
620
+ ...pagination
621
+ };
622
+ },
623
+ listPermissionPoints(params, signal) {
624
+ return permissionApi.list(params, signal);
625
+ },
626
+ async create(values, signal) {
627
+ return request({
628
+ method: "POST",
629
+ url: "/authorization-resources",
630
+ body: buildCreateMenuBody(values),
631
+ signal
632
+ });
633
+ },
634
+ async update(resourceId, values, signal) {
635
+ return request({
636
+ method: "PATCH",
637
+ url: `/authorization-resources/${encodeURIComponent(resourceId)}`,
638
+ body: buildUpdateMenuBody(values),
639
+ signal
640
+ });
641
+ },
642
+ async remove(resourceId, signal) {
643
+ return request({
644
+ method: "DELETE",
645
+ url: `/authorization-resources/${encodeURIComponent(resourceId)}`,
646
+ signal
647
+ });
648
+ }
649
+ };
650
+ }
509
651
  function createDefaultResourceRequest(options = {}) {
510
652
  const baseUrl = (options.baseUrl ?? "").replace(/\/+$/, "");
511
653
  const credentials = options.credentials ?? "include";
@@ -572,6 +714,8 @@ function ResourceManager({
572
714
  const [editing, setEditing] = (0, import_react2.useState)(null);
573
715
  const [form, setForm] = (0, import_react2.useState)(emptyForm);
574
716
  const [saving, setSaving] = (0, import_react2.useState)(false);
717
+ const [deletingRow, setDeletingRow] = (0, import_react2.useState)(null);
718
+ const [deleting, setDeleting] = (0, import_react2.useState)(false);
575
719
  const loadList = (0, import_react2.useCallback)(
576
720
  async (direction = "current", token = pageToken) => {
577
721
  setLoading(true);
@@ -645,14 +789,25 @@ function ResourceManager({
645
789
  setSaving(false);
646
790
  }
647
791
  };
648
- const handleDelete = async (row) => {
649
- if (!window.confirm(`\u786E\u8BA4\u5220\u9664\u6743\u9650\u70B9\u300C${row.name}\u300D\uFF1F`)) return;
792
+ const askDelete = (row) => {
793
+ setDeletingRow(row);
794
+ };
795
+ const closeDeleteDialog = () => {
796
+ if (deleting) return;
797
+ setDeletingRow(null);
798
+ };
799
+ const confirmDelete = async () => {
800
+ if (!deletingRow) return;
801
+ setDeleting(true);
650
802
  setError("");
651
803
  try {
652
- await api.remove(row.resourceId);
804
+ await api.remove(deletingRow.resourceId);
805
+ setDeletingRow(null);
653
806
  await loadList("current", "");
654
807
  } catch (err) {
655
808
  setError(err instanceof Error ? err.message : "\u5220\u9664\u5931\u8D25");
809
+ } finally {
810
+ setDeleting(false);
656
811
  }
657
812
  };
658
813
  const statusLabel = (0, import_react2.useMemo)(
@@ -698,7 +853,7 @@ function ResourceManager({
698
853
  {
699
854
  type: "button",
700
855
  style: { ...styles.linkBtn, color: "#d92d20" },
701
- onClick: () => void handleDelete(row),
856
+ onClick: () => askDelete(row),
702
857
  children: "\u5220\u9664"
703
858
  }
704
859
  )
@@ -829,6 +984,60 @@ function ResourceManager({
829
984
  ] })
830
985
  ]
831
986
  }
987
+ ) }) : null,
988
+ deletingRow ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.mask, onClick: closeDeleteDialog, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
989
+ "div",
990
+ {
991
+ style: { ...styles.dialog, maxWidth: 420 },
992
+ onClick: (e) => e.stopPropagation(),
993
+ role: "dialog",
994
+ "aria-modal": "true",
995
+ "aria-labelledby": "angel-auth-delete-title",
996
+ children: [
997
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.dialogHeader, children: [
998
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { id: "angel-auth-delete-title", style: styles.dialogTitle, children: "\u786E\u8BA4\u5220\u9664" }),
999
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1000
+ "button",
1001
+ {
1002
+ type: "button",
1003
+ style: styles.iconBtn,
1004
+ onClick: closeDeleteDialog,
1005
+ "aria-label": "\u5173\u95ED",
1006
+ children: "\xD7"
1007
+ }
1008
+ )
1009
+ ] }),
1010
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.confirmBody, children: [
1011
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { style: styles.confirmText, children: [
1012
+ "\u786E\u8BA4\u5220\u9664\u6743\u9650\u70B9\u300C",
1013
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: deletingRow.name }),
1014
+ "\u300D\u5417\uFF1F\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\u3002"
1015
+ ] }),
1016
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.dialogFooter, children: [
1017
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1018
+ "button",
1019
+ {
1020
+ type: "button",
1021
+ style: styles.secondaryBtn,
1022
+ onClick: closeDeleteDialog,
1023
+ disabled: deleting,
1024
+ children: "\u53D6\u6D88"
1025
+ }
1026
+ ),
1027
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1028
+ "button",
1029
+ {
1030
+ type: "button",
1031
+ style: styles.dangerBtn,
1032
+ onClick: () => void confirmDelete(),
1033
+ disabled: deleting,
1034
+ children: deleting ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u5220\u9664"
1035
+ }
1036
+ )
1037
+ ] })
1038
+ ] })
1039
+ ]
1040
+ }
832
1041
  ) }) : null
833
1042
  ] });
834
1043
  }
@@ -932,11 +1141,22 @@ var styles = {
932
1141
  cursor: "pointer",
933
1142
  fontSize: 14
934
1143
  },
1144
+ dangerBtn: {
1145
+ border: "none",
1146
+ background: "#d92d20",
1147
+ color: "#fff",
1148
+ borderRadius: 8,
1149
+ padding: "8px 14px",
1150
+ cursor: "pointer",
1151
+ fontSize: 14
1152
+ },
935
1153
  select: {
936
1154
  border: "1px solid #d0d5dd",
937
1155
  borderRadius: 6,
938
1156
  padding: "4px 8px",
939
- fontSize: 13
1157
+ fontSize: 13,
1158
+ backgroundColor: "#ffffff",
1159
+ color: "#101828"
940
1160
  },
941
1161
  mask: {
942
1162
  position: "fixed",
@@ -972,15 +1192,643 @@ var styles = {
972
1192
  color: "#667085"
973
1193
  },
974
1194
  form: { display: "flex", flexDirection: "column", gap: 12, padding: 16 },
1195
+ confirmBody: { display: "flex", flexDirection: "column", gap: 16, padding: 16 },
1196
+ confirmText: { margin: 0, fontSize: 14, color: "#344054", lineHeight: 1.6 },
1197
+ field: { display: "flex", flexDirection: "column", gap: 6 },
1198
+ label: { fontSize: 13, color: "#344054", fontWeight: 500 },
1199
+ input: {
1200
+ border: "1px solid #d0d5dd",
1201
+ borderRadius: 8,
1202
+ padding: "8px 10px",
1203
+ fontSize: 14,
1204
+ outline: "none",
1205
+ backgroundColor: "#ffffff",
1206
+ color: "#101828",
1207
+ boxSizing: "border-box",
1208
+ width: "100%"
1209
+ },
1210
+ dialogFooter: {
1211
+ display: "flex",
1212
+ justifyContent: "flex-end",
1213
+ gap: 8,
1214
+ paddingTop: 4
1215
+ }
1216
+ };
1217
+
1218
+ // src/react/MenuManager.tsx
1219
+ var import_react3 = require("react");
1220
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1221
+ var PAGE_SIZE_OPTIONS2 = ["10", "20", "50", "100"];
1222
+ var emptyForm2 = () => ({
1223
+ parentId: ROOT_PARENT_ID,
1224
+ type: MENU_TYPE_MENU,
1225
+ name: "",
1226
+ identification: "",
1227
+ permissionPointIds: [],
1228
+ status: RESOURCE_STATUS_ENABLED
1229
+ });
1230
+ function MenuManager({
1231
+ api,
1232
+ title = "\u83DC\u5355\u7BA1\u7406",
1233
+ pageSize: initialPageSize = "20",
1234
+ toolbarExtra
1235
+ }) {
1236
+ const [records, setRecords] = (0, import_react3.useState)([]);
1237
+ const [permissionPoints, setPermissionPoints] = (0, import_react3.useState)([]);
1238
+ const [loading, setLoading] = (0, import_react3.useState)(false);
1239
+ const [error, setError] = (0, import_react3.useState)("");
1240
+ const [pageSize, setPageSize] = (0, import_react3.useState)(initialPageSize);
1241
+ const [pageToken, setPageToken] = (0, import_react3.useState)("");
1242
+ const [hasPreviousPage, setHasPreviousPage] = (0, import_react3.useState)(false);
1243
+ const [hasNextPage, setHasNextPage] = (0, import_react3.useState)(false);
1244
+ const [dialogOpen, setDialogOpen] = (0, import_react3.useState)(false);
1245
+ const [editing, setEditing] = (0, import_react3.useState)(null);
1246
+ const [form, setForm] = (0, import_react3.useState)(emptyForm2);
1247
+ const [saving, setSaving] = (0, import_react3.useState)(false);
1248
+ const [deletingRow, setDeletingRow] = (0, import_react3.useState)(null);
1249
+ const [deleting, setDeleting] = (0, import_react3.useState)(false);
1250
+ const permissionNameMap = (0, import_react3.useMemo)(() => {
1251
+ const map = /* @__PURE__ */ new Map();
1252
+ permissionPoints.forEach((p) => map.set(p.resourceId, p.name || p.identification));
1253
+ return map;
1254
+ }, [permissionPoints]);
1255
+ const parentOptions = (0, import_react3.useMemo)(() => {
1256
+ return records.filter((row) => !editing || row.resourceId !== editing.resourceId).map((row) => ({
1257
+ value: row.resourceId,
1258
+ label: `${row.name}\uFF08${MENU_TYPE_LABEL[row.type]}\uFF09`
1259
+ }));
1260
+ }, [records, editing]);
1261
+ const loadList = (0, import_react3.useCallback)(
1262
+ async (direction = "current", token = pageToken) => {
1263
+ setLoading(true);
1264
+ setError("");
1265
+ try {
1266
+ const result = await api.list({
1267
+ pagination: {
1268
+ pageToken: token,
1269
+ pageSize,
1270
+ pageDirection: direction
1271
+ }
1272
+ });
1273
+ setRecords(result.records);
1274
+ setPageToken(result.pageToken);
1275
+ setHasPreviousPage(result.hasPreviousPage);
1276
+ setHasNextPage(result.hasNextPage);
1277
+ } catch (err) {
1278
+ setError(err instanceof Error ? err.message : "\u52A0\u8F7D\u5931\u8D25");
1279
+ } finally {
1280
+ setLoading(false);
1281
+ }
1282
+ },
1283
+ [api, pageSize, pageToken]
1284
+ );
1285
+ const loadPermissionPoints = (0, import_react3.useCallback)(async () => {
1286
+ try {
1287
+ const result = await api.listPermissionPoints({
1288
+ pagination: { pageSize: "200", pageDirection: "current" }
1289
+ });
1290
+ setPermissionPoints(result.records);
1291
+ } catch {
1292
+ }
1293
+ }, [api]);
1294
+ (0, import_react3.useEffect)(() => {
1295
+ void loadList("current", "");
1296
+ void loadPermissionPoints();
1297
+ }, [api, pageSize]);
1298
+ const openCreate = () => {
1299
+ setEditing(null);
1300
+ setForm(emptyForm2());
1301
+ setDialogOpen(true);
1302
+ void loadPermissionPoints();
1303
+ };
1304
+ const openEdit = (row) => {
1305
+ setEditing(row);
1306
+ setForm({
1307
+ parentId: row.parentId || ROOT_PARENT_ID,
1308
+ type: row.type,
1309
+ name: row.name,
1310
+ identification: row.identification,
1311
+ permissionPointIds: [...row.permissionPointIds],
1312
+ status: row.status
1313
+ });
1314
+ setDialogOpen(true);
1315
+ void loadPermissionPoints();
1316
+ };
1317
+ const closeDialog = () => {
1318
+ if (saving) return;
1319
+ setDialogOpen(false);
1320
+ };
1321
+ const handleSubmit = async (event) => {
1322
+ event.preventDefault();
1323
+ if (!form.name.trim()) {
1324
+ setError("\u8BF7\u586B\u5199\u83DC\u5355\u540D\u79F0");
1325
+ return;
1326
+ }
1327
+ setSaving(true);
1328
+ setError("");
1329
+ try {
1330
+ if (editing) {
1331
+ await api.update(editing.resourceId, form);
1332
+ } else {
1333
+ await api.create(form);
1334
+ }
1335
+ setDialogOpen(false);
1336
+ await loadList("current", "");
1337
+ } catch (err) {
1338
+ setError(err instanceof Error ? err.message : "\u4FDD\u5B58\u5931\u8D25");
1339
+ } finally {
1340
+ setSaving(false);
1341
+ }
1342
+ };
1343
+ const askDelete = (row) => setDeletingRow(row);
1344
+ const closeDeleteDialog = () => {
1345
+ if (!deleting) setDeletingRow(null);
1346
+ };
1347
+ const confirmDelete = async () => {
1348
+ if (!deletingRow) return;
1349
+ setDeleting(true);
1350
+ setError("");
1351
+ try {
1352
+ await api.remove(deletingRow.resourceId);
1353
+ setDeletingRow(null);
1354
+ await loadList("current", "");
1355
+ } catch (err) {
1356
+ setError(err instanceof Error ? err.message : "\u5220\u9664\u5931\u8D25");
1357
+ } finally {
1358
+ setDeleting(false);
1359
+ }
1360
+ };
1361
+ const togglePermission = (id) => {
1362
+ setForm((prev) => {
1363
+ const exists = prev.permissionPointIds.includes(id);
1364
+ return {
1365
+ ...prev,
1366
+ permissionPointIds: exists ? prev.permissionPointIds.filter((x) => x !== id) : [...prev.permissionPointIds, id]
1367
+ };
1368
+ });
1369
+ };
1370
+ const renderPermissionLabels = (row) => {
1371
+ if (row.permissionPointNames?.length) {
1372
+ return row.permissionPointNames.join("\u3001");
1373
+ }
1374
+ if (!row.permissionPointIds.length) return "\u2014";
1375
+ return row.permissionPointIds.map((id) => permissionNameMap.get(id) ?? id).join("\u3001");
1376
+ };
1377
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.root, children: [
1378
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.toolbar, children: [
1379
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: styles2.title, children: title }),
1380
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.toolbarRight, children: [
1381
+ toolbarExtra,
1382
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.primaryBtn, onClick: openCreate, children: "\u65B0\u589E" })
1383
+ ] })
1384
+ ] }),
1385
+ error ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.error, children: error }) : null,
1386
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.tableWrap, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("table", { style: styles2.table, children: [
1387
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("tr", { children: [
1388
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: styles2.th, children: "\u83DC\u5355\u540D\u79F0" }),
1389
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: styles2.th, children: "\u8BF7\u6C42\u5730\u5740" }),
1390
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: { ...styles2.th, width: 90 }, children: "\u7C7B\u578B" }),
1391
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: { ...styles2.th, width: 80 }, children: "\u53EF\u89C1" }),
1392
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: styles2.th, children: "\u6743\u9650\u6807\u8BC6" }),
1393
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("th", { style: { ...styles2.th, width: 140 }, children: "\u64CD\u4F5C" })
1394
+ ] }) }),
1395
+ /* @__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: [
1396
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: row.name }),
1397
+ /* @__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" }) }),
1398
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: MENU_TYPE_LABEL[row.type] }),
1399
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1400
+ "span",
1401
+ {
1402
+ style: {
1403
+ ...styles2.badge,
1404
+ background: row.status === RESOURCE_STATUS_ENABLED ? "#e8f7ef" : "#f4f4f5",
1405
+ color: row.status === RESOURCE_STATUS_ENABLED ? "#067647" : "#667085"
1406
+ },
1407
+ children: row.status === RESOURCE_STATUS_ENABLED ? "\u663E\u793A" : "\u9690\u85CF"
1408
+ }
1409
+ ) }),
1410
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("td", { style: styles2.td, children: renderPermissionLabels(row) }),
1411
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("td", { style: styles2.td, children: [
1412
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.linkBtn, onClick: () => openEdit(row), children: "\u7F16\u8F91" }),
1413
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1414
+ "button",
1415
+ {
1416
+ type: "button",
1417
+ style: { ...styles2.linkBtn, color: "#d92d20" },
1418
+ onClick: () => askDelete(row),
1419
+ children: "\u5220\u9664"
1420
+ }
1421
+ )
1422
+ ] })
1423
+ ] }, row.resourceId)) })
1424
+ ] }) }),
1425
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.pagination, children: [
1426
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.pageSize, children: [
1427
+ "\u6BCF\u9875",
1428
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1429
+ "select",
1430
+ {
1431
+ value: pageSize,
1432
+ onChange: (e) => {
1433
+ setPageToken("");
1434
+ setPageSize(e.target.value);
1435
+ },
1436
+ style: styles2.select,
1437
+ children: PAGE_SIZE_OPTIONS2.map((size) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: size, children: size }, size))
1438
+ }
1439
+ )
1440
+ ] }),
1441
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.pageBtns, children: [
1442
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1443
+ "button",
1444
+ {
1445
+ type: "button",
1446
+ style: styles2.secondaryBtn,
1447
+ disabled: !hasPreviousPage || loading,
1448
+ onClick: () => void loadList("previous"),
1449
+ children: "\u4E0A\u4E00\u9875"
1450
+ }
1451
+ ),
1452
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1453
+ "button",
1454
+ {
1455
+ type: "button",
1456
+ style: styles2.secondaryBtn,
1457
+ disabled: !hasNextPage || loading,
1458
+ onClick: () => void loadList("next"),
1459
+ children: "\u4E0B\u4E00\u9875"
1460
+ }
1461
+ )
1462
+ ] })
1463
+ ] }),
1464
+ dialogOpen ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.mask, onClick: closeDialog, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1465
+ "div",
1466
+ {
1467
+ style: { ...styles2.dialog, maxWidth: 520 },
1468
+ onClick: (e) => e.stopPropagation(),
1469
+ role: "dialog",
1470
+ "aria-modal": "true",
1471
+ children: [
1472
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogHeader, children: [
1473
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: styles2.dialogTitle, children: editing ? "\u7F16\u8F91\u83DC\u5355" : "\u65B0\u589E\u83DC\u5355" }),
1474
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.iconBtn, onClick: closeDialog, "aria-label": "\u5173\u95ED", children: "\xD7" })
1475
+ ] }),
1476
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { style: styles2.form, onSubmit: (e) => void handleSubmit(e), children: [
1477
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.field, children: [
1478
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles2.label, children: "\u4E0A\u7EA7\u83DC\u5355" }),
1479
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1480
+ "select",
1481
+ {
1482
+ style: styles2.input,
1483
+ value: form.parentId,
1484
+ onChange: (e) => setForm((prev) => ({ ...prev, parentId: e.target.value })),
1485
+ children: [
1486
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: ROOT_PARENT_ID, children: "\u6839\u76EE\u5F55" }),
1487
+ parentOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1488
+ ]
1489
+ }
1490
+ )
1491
+ ] }),
1492
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("fieldset", { style: styles2.fieldset, children: [
1493
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("legend", { style: styles2.label, children: "\u83DC\u5355\u7C7B\u578B" }),
1494
+ /* @__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: [
1495
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1496
+ "input",
1497
+ {
1498
+ type: "radio",
1499
+ name: "menu-type",
1500
+ checked: form.type === opt.value,
1501
+ onChange: () => setForm((prev) => ({
1502
+ ...prev,
1503
+ type: opt.value
1504
+ }))
1505
+ }
1506
+ ),
1507
+ opt.label
1508
+ ] }, opt.value)) })
1509
+ ] }),
1510
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.field, children: [
1511
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles2.label, children: "\u83DC\u5355\u540D\u79F0" }),
1512
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1513
+ "input",
1514
+ {
1515
+ style: styles2.input,
1516
+ value: form.name,
1517
+ onChange: (e) => setForm((prev) => ({ ...prev, name: e.target.value })),
1518
+ placeholder: "\u8BF7\u8F93\u5165\u83DC\u5355\u540D\u79F0",
1519
+ required: true
1520
+ }
1521
+ )
1522
+ ] }),
1523
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { style: styles2.field, children: [
1524
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles2.label, children: "\u8BF7\u6C42\u5730\u5740" }),
1525
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1526
+ "input",
1527
+ {
1528
+ style: styles2.input,
1529
+ value: form.identification,
1530
+ onChange: (e) => setForm((prev) => ({ ...prev, identification: e.target.value })),
1531
+ placeholder: "\u5982 /system/user"
1532
+ }
1533
+ )
1534
+ ] }),
1535
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("fieldset", { style: styles2.fieldset, children: [
1536
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("legend", { style: styles2.label, children: "\u6743\u9650\u6807\u8BC6" }),
1537
+ /* @__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: [
1538
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1539
+ "input",
1540
+ {
1541
+ type: "checkbox",
1542
+ checked: form.permissionPointIds.includes(p.resourceId),
1543
+ onChange: () => togglePermission(p.resourceId)
1544
+ }
1545
+ ),
1546
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
1547
+ p.name,
1548
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { style: { ...styles2.code, marginLeft: 6 }, children: p.identification })
1549
+ ] })
1550
+ ] }, p.resourceId)) })
1551
+ ] }),
1552
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("fieldset", { style: styles2.fieldset, children: [
1553
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("legend", { style: styles2.label, children: "\u72B6\u6001" }),
1554
+ /* @__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: [
1555
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1556
+ "input",
1557
+ {
1558
+ type: "radio",
1559
+ name: "menu-status",
1560
+ checked: form.status === opt.value,
1561
+ onChange: () => setForm((prev) => ({ ...prev, status: opt.value }))
1562
+ }
1563
+ ),
1564
+ opt.label
1565
+ ] }, opt.value)) })
1566
+ ] }),
1567
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogFooter, children: [
1568
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", style: styles2.secondaryBtn, onClick: closeDialog, children: "\u53D6\u6D88" }),
1569
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", style: styles2.primaryBtn, disabled: saving, children: saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58" })
1570
+ ] })
1571
+ ] })
1572
+ ]
1573
+ }
1574
+ ) }) : null,
1575
+ deletingRow ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles2.mask, onClick: closeDeleteDialog, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1576
+ "div",
1577
+ {
1578
+ style: { ...styles2.dialog, maxWidth: 420 },
1579
+ onClick: (e) => e.stopPropagation(),
1580
+ role: "dialog",
1581
+ "aria-modal": "true",
1582
+ children: [
1583
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogHeader, children: [
1584
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { style: styles2.dialogTitle, children: "\u786E\u8BA4\u5220\u9664" }),
1585
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1586
+ "button",
1587
+ {
1588
+ type: "button",
1589
+ style: styles2.iconBtn,
1590
+ onClick: closeDeleteDialog,
1591
+ "aria-label": "\u5173\u95ED",
1592
+ children: "\xD7"
1593
+ }
1594
+ )
1595
+ ] }),
1596
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.confirmBody, children: [
1597
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { style: styles2.confirmText, children: [
1598
+ "\u786E\u8BA4\u5220\u9664\u83DC\u5355\u300C",
1599
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: deletingRow.name }),
1600
+ "\u300D\u5417\uFF1F\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\u3002"
1601
+ ] }),
1602
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: styles2.dialogFooter, children: [
1603
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1604
+ "button",
1605
+ {
1606
+ type: "button",
1607
+ style: styles2.secondaryBtn,
1608
+ onClick: closeDeleteDialog,
1609
+ disabled: deleting,
1610
+ children: "\u53D6\u6D88"
1611
+ }
1612
+ ),
1613
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1614
+ "button",
1615
+ {
1616
+ type: "button",
1617
+ style: styles2.dangerBtn,
1618
+ onClick: () => void confirmDelete(),
1619
+ disabled: deleting,
1620
+ children: deleting ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u5220\u9664"
1621
+ }
1622
+ )
1623
+ ] })
1624
+ ] })
1625
+ ]
1626
+ }
1627
+ ) }) : null
1628
+ ] });
1629
+ }
1630
+ var styles2 = {
1631
+ root: {
1632
+ display: "flex",
1633
+ flexDirection: "column",
1634
+ gap: 16,
1635
+ padding: 16,
1636
+ color: "#101828",
1637
+ fontFamily: '"PingFang SC", "Microsoft YaHei", -apple-system, BlinkMacSystemFont, sans-serif'
1638
+ },
1639
+ toolbar: {
1640
+ display: "flex",
1641
+ alignItems: "center",
1642
+ justifyContent: "space-between",
1643
+ gap: 12
1644
+ },
1645
+ title: { margin: 0, fontSize: 18, fontWeight: 600 },
1646
+ toolbarRight: { display: "flex", alignItems: "center", gap: 8 },
1647
+ error: {
1648
+ padding: "10px 12px",
1649
+ borderRadius: 8,
1650
+ background: "#fef3f2",
1651
+ color: "#b42318",
1652
+ fontSize: 13
1653
+ },
1654
+ tableWrap: {
1655
+ overflow: "auto",
1656
+ border: "1px solid #eaecf0",
1657
+ borderRadius: 10,
1658
+ background: "#fff"
1659
+ },
1660
+ table: { width: "100%", borderCollapse: "collapse", minWidth: 820 },
1661
+ th: {
1662
+ textAlign: "left",
1663
+ padding: "12px 14px",
1664
+ fontSize: 13,
1665
+ fontWeight: 600,
1666
+ color: "#475467",
1667
+ background: "#f9fafb",
1668
+ borderBottom: "1px solid #eaecf0"
1669
+ },
1670
+ td: {
1671
+ padding: "12px 14px",
1672
+ fontSize: 14,
1673
+ borderBottom: "1px solid #f2f4f7",
1674
+ verticalAlign: "middle"
1675
+ },
1676
+ empty: { padding: 28, textAlign: "center", color: "#98a2b3", fontSize: 14 },
1677
+ code: {
1678
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
1679
+ fontSize: 13,
1680
+ background: "#f2f4f7",
1681
+ padding: "2px 6px",
1682
+ borderRadius: 4
1683
+ },
1684
+ badge: {
1685
+ display: "inline-block",
1686
+ padding: "2px 8px",
1687
+ borderRadius: 999,
1688
+ fontSize: 12,
1689
+ fontWeight: 500
1690
+ },
1691
+ linkBtn: {
1692
+ border: "none",
1693
+ background: "transparent",
1694
+ color: "#049BAD",
1695
+ cursor: "pointer",
1696
+ padding: "0 8px 0 0",
1697
+ fontSize: 13
1698
+ },
1699
+ pagination: {
1700
+ display: "flex",
1701
+ alignItems: "center",
1702
+ justifyContent: "space-between",
1703
+ gap: 12
1704
+ },
1705
+ pageSize: { display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: "#475467" },
1706
+ pageBtns: { display: "flex", gap: 8 },
1707
+ primaryBtn: {
1708
+ border: "none",
1709
+ background: "#049BAD",
1710
+ color: "#fff",
1711
+ borderRadius: 8,
1712
+ padding: "8px 14px",
1713
+ cursor: "pointer",
1714
+ fontSize: 14
1715
+ },
1716
+ secondaryBtn: {
1717
+ border: "1px solid #d0d5dd",
1718
+ background: "#fff",
1719
+ color: "#344054",
1720
+ borderRadius: 8,
1721
+ padding: "8px 14px",
1722
+ cursor: "pointer",
1723
+ fontSize: 14
1724
+ },
1725
+ dangerBtn: {
1726
+ border: "none",
1727
+ background: "#d92d20",
1728
+ color: "#fff",
1729
+ borderRadius: 8,
1730
+ padding: "8px 14px",
1731
+ cursor: "pointer",
1732
+ fontSize: 14
1733
+ },
1734
+ select: {
1735
+ border: "1px solid #d0d5dd",
1736
+ borderRadius: 6,
1737
+ padding: "4px 8px",
1738
+ fontSize: 13,
1739
+ backgroundColor: "#ffffff",
1740
+ color: "#101828"
1741
+ },
1742
+ mask: {
1743
+ position: "fixed",
1744
+ inset: 0,
1745
+ background: "rgba(16, 24, 40, 0.45)",
1746
+ display: "flex",
1747
+ alignItems: "center",
1748
+ justifyContent: "center",
1749
+ zIndex: 1e3,
1750
+ padding: 16
1751
+ },
1752
+ dialog: {
1753
+ width: "100%",
1754
+ maxWidth: 480,
1755
+ background: "#fff",
1756
+ borderRadius: 12,
1757
+ boxShadow: "0 20px 40px rgba(16,24,40,0.18)",
1758
+ maxHeight: "90vh",
1759
+ overflow: "auto"
1760
+ },
1761
+ dialogHeader: {
1762
+ display: "flex",
1763
+ alignItems: "center",
1764
+ justifyContent: "space-between",
1765
+ padding: "14px 16px",
1766
+ borderBottom: "1px solid #eaecf0",
1767
+ position: "sticky",
1768
+ top: 0,
1769
+ background: "#fff",
1770
+ zIndex: 1
1771
+ },
1772
+ dialogTitle: { margin: 0, fontSize: 16, fontWeight: 600 },
1773
+ iconBtn: {
1774
+ border: "none",
1775
+ background: "transparent",
1776
+ fontSize: 22,
1777
+ lineHeight: 1,
1778
+ cursor: "pointer",
1779
+ color: "#667085"
1780
+ },
1781
+ form: { display: "flex", flexDirection: "column", gap: 12, padding: 16 },
1782
+ confirmBody: { display: "flex", flexDirection: "column", gap: 16, padding: 16 },
1783
+ confirmText: { margin: 0, fontSize: 14, color: "#344054", lineHeight: 1.6 },
975
1784
  field: { display: "flex", flexDirection: "column", gap: 6 },
1785
+ fieldset: {
1786
+ margin: 0,
1787
+ padding: 0,
1788
+ border: "none",
1789
+ display: "flex",
1790
+ flexDirection: "column",
1791
+ gap: 8
1792
+ },
976
1793
  label: { fontSize: 13, color: "#344054", fontWeight: 500 },
977
1794
  input: {
978
1795
  border: "1px solid #d0d5dd",
979
1796
  borderRadius: 8,
980
1797
  padding: "8px 10px",
981
1798
  fontSize: 14,
982
- outline: "none"
1799
+ outline: "none",
1800
+ backgroundColor: "#ffffff",
1801
+ color: "#101828",
1802
+ boxSizing: "border-box",
1803
+ width: "100%"
1804
+ },
1805
+ radioGroup: { display: "flex", flexWrap: "wrap", gap: 16 },
1806
+ radioItem: {
1807
+ display: "flex",
1808
+ alignItems: "center",
1809
+ gap: 6,
1810
+ fontSize: 14,
1811
+ color: "#344054",
1812
+ cursor: "pointer"
1813
+ },
1814
+ multiSelect: {
1815
+ maxHeight: 160,
1816
+ overflow: "auto",
1817
+ border: "1px solid #eaecf0",
1818
+ borderRadius: 8,
1819
+ padding: 8,
1820
+ background: "#f9fafb"
1821
+ },
1822
+ checkItem: {
1823
+ display: "flex",
1824
+ alignItems: "center",
1825
+ gap: 8,
1826
+ padding: "6px 4px",
1827
+ fontSize: 13,
1828
+ color: "#344054",
1829
+ cursor: "pointer"
983
1830
  },
1831
+ hint: { fontSize: 13, color: "#98a2b3", padding: 8 },
984
1832
  dialogFooter: {
985
1833
  display: "flex",
986
1834
  justifyContent: "flex-end",
@@ -991,6 +1839,14 @@ var styles = {
991
1839
  // Annotate the CommonJS export names for ESM import in node:
992
1840
  0 && (module.exports = {
993
1841
  Can,
1842
+ MENU_LIST_TYPE_PARAM,
1843
+ MENU_TYPE_BUTTON,
1844
+ MENU_TYPE_LABEL,
1845
+ MENU_TYPE_MENU,
1846
+ MENU_TYPE_OPTIONS,
1847
+ MENU_TYPE_PAGE,
1848
+ MENU_VISIBILITY_OPTIONS,
1849
+ MenuManager,
994
1850
  PermissionProvider,
995
1851
  PermissionStore,
996
1852
  RESOURCE_PRIVATE_OPTIONS,
@@ -998,18 +1854,23 @@ var styles = {
998
1854
  RESOURCE_STATUS_ENABLED,
999
1855
  RESOURCE_STATUS_OPTIONS,
1000
1856
  RESOURCE_TYPE_API,
1857
+ ROOT_PARENT_ID,
1001
1858
  ResourceManager,
1002
1859
  appendQueryParam,
1003
1860
  buildCreateBody,
1861
+ buildCreateMenuBody,
1004
1862
  buildUpdateBody,
1863
+ buildUpdateMenuBody,
1005
1864
  createAuthorizationResourceApi,
1006
1865
  createDefaultResourceRequest,
1866
+ createMenuResourceApi,
1007
1867
  createPermissionStore,
1008
1868
  extractPagination,
1009
1869
  extractRecords,
1010
1870
  getAppClientId,
1011
1871
  getDeviceWorkerId,
1012
1872
  mapAuthorizationResource,
1873
+ mapMenuResource,
1013
1874
  snowyflake,
1014
1875
  useHasPermission,
1015
1876
  useHasRole,