com-angel-authorization 1.0.9 → 1.0.10
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 +4 -1
- package/dist/index.cjs +26 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +24 -2
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +154 -32
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +16 -1
- package/dist/react/index.d.ts +16 -1
- package/dist/react/index.js +151 -32
- package/dist/react/index.js.map +1 -1
- package/dist/vue/index.cjs +141 -10
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.d.cts +16 -1
- package/dist/vue/index.d.ts +16 -1
- package/dist/vue/index.js +138 -10
- package/dist/vue/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -174,6 +174,10 @@ type MenuResource = {
|
|
|
174
174
|
* 菜单层级:无上级(根)为 1,其余为上级 depth + 1
|
|
175
175
|
*/
|
|
176
176
|
depth: number;
|
|
177
|
+
/**
|
|
178
|
+
* 是否叶子节点:`1` 表示无下级菜单,不可再展开
|
|
179
|
+
*/
|
|
180
|
+
leaf: number;
|
|
177
181
|
type: MenuResourceType;
|
|
178
182
|
name: string;
|
|
179
183
|
identification: string;
|
|
@@ -198,6 +202,8 @@ type CreateMenuResourceBody = MenuResourceFormValues & {
|
|
|
198
202
|
};
|
|
199
203
|
type UpdateMenuResourceBody = Partial<MenuResourceFormValues>;
|
|
200
204
|
type FetchMenuResourcesParams = {
|
|
205
|
+
/** 列表默认传 1,只拉根层 */
|
|
206
|
+
depth?: number;
|
|
201
207
|
pagination?: ListPaginationParams;
|
|
202
208
|
};
|
|
203
209
|
type MenuResourceListResult = {
|
|
@@ -206,6 +212,9 @@ type MenuResourceListResult = {
|
|
|
206
212
|
hasPreviousPage: boolean;
|
|
207
213
|
hasNextPage: boolean;
|
|
208
214
|
};
|
|
215
|
+
/** leaf === 1 表示无下级 */
|
|
216
|
+
declare const MENU_LEAF_YES = 1;
|
|
217
|
+
declare const MENU_LEAF_NO = 0;
|
|
209
218
|
declare const RESOURCE_TYPE_API: ApiResourceType;
|
|
210
219
|
declare const MENU_TYPE_PAGE: MenuResourceType;
|
|
211
220
|
declare const MENU_TYPE_MENU: MenuResourceType;
|
|
@@ -259,6 +268,8 @@ type AuthorizationResourceApi = {
|
|
|
259
268
|
};
|
|
260
269
|
type MenuResourceApi = {
|
|
261
270
|
list: (params?: FetchMenuResourcesParams, signal?: AbortSignal) => Promise<MenuResourceListResult>;
|
|
271
|
+
/** 展开下级:GET /authorization-resources/{resource-id}/sub-resources */
|
|
272
|
+
listSubResources: (resourceId: string, signal?: AbortSignal) => Promise<MenuResource[]>;
|
|
262
273
|
/** 拉取权限点(type=api),供菜单表单多选 */
|
|
263
274
|
listPermissionPoints: (params?: FetchAuthorizationResourcesParams, signal?: AbortSignal) => Promise<AuthorizationResourceListResult>;
|
|
264
275
|
create: (values: MenuResourceFormValues, signal?: AbortSignal) => Promise<unknown>;
|
|
@@ -267,6 +278,10 @@ type MenuResourceApi = {
|
|
|
267
278
|
};
|
|
268
279
|
declare function mapAuthorizationResource(item: unknown): AuthorizationResource | null;
|
|
269
280
|
declare function mapMenuResource(item: unknown): MenuResource | null;
|
|
281
|
+
/**
|
|
282
|
+
* leaf === 1 表示无下级菜单。
|
|
283
|
+
*/
|
|
284
|
+
declare function isMenuLeaf(row: Pick<MenuResource, 'leaf'>): boolean;
|
|
270
285
|
/**
|
|
271
286
|
* 根据上级菜单计算 depth:无上级为 1,否则为上级 depth + 1。
|
|
272
287
|
*/
|
|
@@ -371,4 +386,4 @@ declare const snowyflake: ConfigurableSnowflake;
|
|
|
371
386
|
declare function getAppClientId(): string;
|
|
372
387
|
declare function getDeviceWorkerId(): string;
|
|
373
388
|
|
|
374
|
-
export { type ApiResourceType, type AuthorizationResource, type AuthorizationResourceApi, type AuthorizationResourceFormValues, type AuthorizationResourceListResult, Can, type CanProps, type CheckOptions, type CreateAuthorizationResourceBody, type CreateDefaultResourceRequestOptions, type CreateMenuResourceBody, type FetchAuthorizationResourcesParams, type FetchMenuResourcesParams, type HttpMethod, type ListPaginationParams, type ListPaginationResult, MENU_LIST_TYPE_PARAM, MENU_TYPE_BUTTON, MENU_TYPE_LABEL, MENU_TYPE_MENU, MENU_TYPE_OPTIONS, MENU_TYPE_PAGE, MENU_VISIBILITY_OPTIONS, type MatchMode, MenuManager, type MenuManagerProps, type MenuResource, type MenuResourceApi, type MenuResourceFormValues, type MenuResourceListResult, type MenuResourceType, type PageDirection, type PermissionChecker, type PermissionCode, type PermissionListener, PermissionProvider, type PermissionProviderProps, type PermissionState, PermissionStore, RESOURCE_PRIVATE_OPTIONS, RESOURCE_STATUS_DISABLED, RESOURCE_STATUS_ENABLED, RESOURCE_STATUS_OPTIONS, RESOURCE_TYPE_API, ROOT_MENU_DEPTH, ROOT_PARENT_ID, type ResourceHttpRequest, ResourceManager, type ResourceManagerProps, type ResourceRequestOptions, type ResourceStatus, type ResourceType, type RoleCode, SYSTEM_ADMIN_DEFAULT_KEY, SYSTEM_ADMIN_MENU, SystemAdmin, type SystemAdminMenuGroup, type SystemAdminMenuKey, type SystemAdminProps, type SystemAdminSubMenu, type UpdateAuthorizationResourceBody, type UpdateMenuResourceBody, type UsePermissionResult, appendQueryParam, buildCreateBody, buildCreateMenuBody, buildUpdateBody, buildUpdateMenuBody, createAuthorizationResourceApi, createDefaultResourceRequest, createMenuResourceApi, createPermissionStore, extractPagination, extractRecords, getAppClientId, getDeviceWorkerId, mapAuthorizationResource, mapMenuResource, resolveMenuDepth, snowyflake, useHasPermission, useHasRole, usePermission };
|
|
389
|
+
export { type ApiResourceType, type AuthorizationResource, type AuthorizationResourceApi, type AuthorizationResourceFormValues, type AuthorizationResourceListResult, Can, type CanProps, type CheckOptions, type CreateAuthorizationResourceBody, type CreateDefaultResourceRequestOptions, type CreateMenuResourceBody, type FetchAuthorizationResourcesParams, type FetchMenuResourcesParams, type HttpMethod, type ListPaginationParams, type ListPaginationResult, MENU_LEAF_NO, MENU_LEAF_YES, MENU_LIST_TYPE_PARAM, MENU_TYPE_BUTTON, MENU_TYPE_LABEL, MENU_TYPE_MENU, MENU_TYPE_OPTIONS, MENU_TYPE_PAGE, MENU_VISIBILITY_OPTIONS, type MatchMode, MenuManager, type MenuManagerProps, type MenuResource, type MenuResourceApi, type MenuResourceFormValues, type MenuResourceListResult, type MenuResourceType, type PageDirection, type PermissionChecker, type PermissionCode, type PermissionListener, PermissionProvider, type PermissionProviderProps, type PermissionState, PermissionStore, RESOURCE_PRIVATE_OPTIONS, RESOURCE_STATUS_DISABLED, RESOURCE_STATUS_ENABLED, RESOURCE_STATUS_OPTIONS, RESOURCE_TYPE_API, ROOT_MENU_DEPTH, ROOT_PARENT_ID, type ResourceHttpRequest, ResourceManager, type ResourceManagerProps, type ResourceRequestOptions, type ResourceStatus, type ResourceType, type RoleCode, SYSTEM_ADMIN_DEFAULT_KEY, SYSTEM_ADMIN_MENU, SystemAdmin, type SystemAdminMenuGroup, type SystemAdminMenuKey, type SystemAdminProps, type SystemAdminSubMenu, type UpdateAuthorizationResourceBody, type UpdateMenuResourceBody, type UsePermissionResult, appendQueryParam, buildCreateBody, buildCreateMenuBody, buildUpdateBody, buildUpdateMenuBody, createAuthorizationResourceApi, createDefaultResourceRequest, createMenuResourceApi, createPermissionStore, extractPagination, extractRecords, getAppClientId, getDeviceWorkerId, isMenuLeaf, mapAuthorizationResource, mapMenuResource, resolveMenuDepth, snowyflake, useHasPermission, useHasRole, usePermission };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -174,6 +174,10 @@ type MenuResource = {
|
|
|
174
174
|
* 菜单层级:无上级(根)为 1,其余为上级 depth + 1
|
|
175
175
|
*/
|
|
176
176
|
depth: number;
|
|
177
|
+
/**
|
|
178
|
+
* 是否叶子节点:`1` 表示无下级菜单,不可再展开
|
|
179
|
+
*/
|
|
180
|
+
leaf: number;
|
|
177
181
|
type: MenuResourceType;
|
|
178
182
|
name: string;
|
|
179
183
|
identification: string;
|
|
@@ -198,6 +202,8 @@ type CreateMenuResourceBody = MenuResourceFormValues & {
|
|
|
198
202
|
};
|
|
199
203
|
type UpdateMenuResourceBody = Partial<MenuResourceFormValues>;
|
|
200
204
|
type FetchMenuResourcesParams = {
|
|
205
|
+
/** 列表默认传 1,只拉根层 */
|
|
206
|
+
depth?: number;
|
|
201
207
|
pagination?: ListPaginationParams;
|
|
202
208
|
};
|
|
203
209
|
type MenuResourceListResult = {
|
|
@@ -206,6 +212,9 @@ type MenuResourceListResult = {
|
|
|
206
212
|
hasPreviousPage: boolean;
|
|
207
213
|
hasNextPage: boolean;
|
|
208
214
|
};
|
|
215
|
+
/** leaf === 1 表示无下级 */
|
|
216
|
+
declare const MENU_LEAF_YES = 1;
|
|
217
|
+
declare const MENU_LEAF_NO = 0;
|
|
209
218
|
declare const RESOURCE_TYPE_API: ApiResourceType;
|
|
210
219
|
declare const MENU_TYPE_PAGE: MenuResourceType;
|
|
211
220
|
declare const MENU_TYPE_MENU: MenuResourceType;
|
|
@@ -259,6 +268,8 @@ type AuthorizationResourceApi = {
|
|
|
259
268
|
};
|
|
260
269
|
type MenuResourceApi = {
|
|
261
270
|
list: (params?: FetchMenuResourcesParams, signal?: AbortSignal) => Promise<MenuResourceListResult>;
|
|
271
|
+
/** 展开下级:GET /authorization-resources/{resource-id}/sub-resources */
|
|
272
|
+
listSubResources: (resourceId: string, signal?: AbortSignal) => Promise<MenuResource[]>;
|
|
262
273
|
/** 拉取权限点(type=api),供菜单表单多选 */
|
|
263
274
|
listPermissionPoints: (params?: FetchAuthorizationResourcesParams, signal?: AbortSignal) => Promise<AuthorizationResourceListResult>;
|
|
264
275
|
create: (values: MenuResourceFormValues, signal?: AbortSignal) => Promise<unknown>;
|
|
@@ -267,6 +278,10 @@ type MenuResourceApi = {
|
|
|
267
278
|
};
|
|
268
279
|
declare function mapAuthorizationResource(item: unknown): AuthorizationResource | null;
|
|
269
280
|
declare function mapMenuResource(item: unknown): MenuResource | null;
|
|
281
|
+
/**
|
|
282
|
+
* leaf === 1 表示无下级菜单。
|
|
283
|
+
*/
|
|
284
|
+
declare function isMenuLeaf(row: Pick<MenuResource, 'leaf'>): boolean;
|
|
270
285
|
/**
|
|
271
286
|
* 根据上级菜单计算 depth:无上级为 1,否则为上级 depth + 1。
|
|
272
287
|
*/
|
|
@@ -371,4 +386,4 @@ declare const snowyflake: ConfigurableSnowflake;
|
|
|
371
386
|
declare function getAppClientId(): string;
|
|
372
387
|
declare function getDeviceWorkerId(): string;
|
|
373
388
|
|
|
374
|
-
export { type ApiResourceType, type AuthorizationResource, type AuthorizationResourceApi, type AuthorizationResourceFormValues, type AuthorizationResourceListResult, Can, type CanProps, type CheckOptions, type CreateAuthorizationResourceBody, type CreateDefaultResourceRequestOptions, type CreateMenuResourceBody, type FetchAuthorizationResourcesParams, type FetchMenuResourcesParams, type HttpMethod, type ListPaginationParams, type ListPaginationResult, MENU_LIST_TYPE_PARAM, MENU_TYPE_BUTTON, MENU_TYPE_LABEL, MENU_TYPE_MENU, MENU_TYPE_OPTIONS, MENU_TYPE_PAGE, MENU_VISIBILITY_OPTIONS, type MatchMode, MenuManager, type MenuManagerProps, type MenuResource, type MenuResourceApi, type MenuResourceFormValues, type MenuResourceListResult, type MenuResourceType, type PageDirection, type PermissionChecker, type PermissionCode, type PermissionListener, PermissionProvider, type PermissionProviderProps, type PermissionState, PermissionStore, RESOURCE_PRIVATE_OPTIONS, RESOURCE_STATUS_DISABLED, RESOURCE_STATUS_ENABLED, RESOURCE_STATUS_OPTIONS, RESOURCE_TYPE_API, ROOT_MENU_DEPTH, ROOT_PARENT_ID, type ResourceHttpRequest, ResourceManager, type ResourceManagerProps, type ResourceRequestOptions, type ResourceStatus, type ResourceType, type RoleCode, SYSTEM_ADMIN_DEFAULT_KEY, SYSTEM_ADMIN_MENU, SystemAdmin, type SystemAdminMenuGroup, type SystemAdminMenuKey, type SystemAdminProps, type SystemAdminSubMenu, type UpdateAuthorizationResourceBody, type UpdateMenuResourceBody, type UsePermissionResult, appendQueryParam, buildCreateBody, buildCreateMenuBody, buildUpdateBody, buildUpdateMenuBody, createAuthorizationResourceApi, createDefaultResourceRequest, createMenuResourceApi, createPermissionStore, extractPagination, extractRecords, getAppClientId, getDeviceWorkerId, mapAuthorizationResource, mapMenuResource, resolveMenuDepth, snowyflake, useHasPermission, useHasRole, usePermission };
|
|
389
|
+
export { type ApiResourceType, type AuthorizationResource, type AuthorizationResourceApi, type AuthorizationResourceFormValues, type AuthorizationResourceListResult, Can, type CanProps, type CheckOptions, type CreateAuthorizationResourceBody, type CreateDefaultResourceRequestOptions, type CreateMenuResourceBody, type FetchAuthorizationResourcesParams, type FetchMenuResourcesParams, type HttpMethod, type ListPaginationParams, type ListPaginationResult, MENU_LEAF_NO, MENU_LEAF_YES, MENU_LIST_TYPE_PARAM, MENU_TYPE_BUTTON, MENU_TYPE_LABEL, MENU_TYPE_MENU, MENU_TYPE_OPTIONS, MENU_TYPE_PAGE, MENU_VISIBILITY_OPTIONS, type MatchMode, MenuManager, type MenuManagerProps, type MenuResource, type MenuResourceApi, type MenuResourceFormValues, type MenuResourceListResult, type MenuResourceType, type PageDirection, type PermissionChecker, type PermissionCode, type PermissionListener, PermissionProvider, type PermissionProviderProps, type PermissionState, PermissionStore, RESOURCE_PRIVATE_OPTIONS, RESOURCE_STATUS_DISABLED, RESOURCE_STATUS_ENABLED, RESOURCE_STATUS_OPTIONS, RESOURCE_TYPE_API, ROOT_MENU_DEPTH, ROOT_PARENT_ID, type ResourceHttpRequest, ResourceManager, type ResourceManagerProps, type ResourceRequestOptions, type ResourceStatus, type ResourceType, type RoleCode, SYSTEM_ADMIN_DEFAULT_KEY, SYSTEM_ADMIN_MENU, SystemAdmin, type SystemAdminMenuGroup, type SystemAdminMenuKey, type SystemAdminProps, type SystemAdminSubMenu, type UpdateAuthorizationResourceBody, type UpdateMenuResourceBody, type UsePermissionResult, appendQueryParam, buildCreateBody, buildCreateMenuBody, buildUpdateBody, buildUpdateMenuBody, createAuthorizationResourceApi, createDefaultResourceRequest, createMenuResourceApi, createPermissionStore, extractPagination, extractRecords, getAppClientId, getDeviceWorkerId, isMenuLeaf, mapAuthorizationResource, mapMenuResource, resolveMenuDepth, snowyflake, useHasPermission, useHasRole, usePermission };
|
package/dist/react/index.js
CHANGED
|
@@ -232,6 +232,8 @@ import {
|
|
|
232
232
|
} from "react";
|
|
233
233
|
|
|
234
234
|
// src/resources/types.ts
|
|
235
|
+
var MENU_LEAF_YES = 1;
|
|
236
|
+
var MENU_LEAF_NO = 0;
|
|
235
237
|
var RESOURCE_TYPE_API = "api";
|
|
236
238
|
var MENU_TYPE_PAGE = "page";
|
|
237
239
|
var MENU_TYPE_MENU = "menu";
|
|
@@ -460,10 +462,13 @@ function mapMenuResource(item) {
|
|
|
460
462
|
const rawDepth = row.depth;
|
|
461
463
|
const parsedDepth = Number(rawDepth);
|
|
462
464
|
const depth = Number.isFinite(parsedDepth) && parsedDepth > 0 ? Math.floor(parsedDepth) : parentId ? ROOT_MENU_DEPTH + 1 : ROOT_MENU_DEPTH;
|
|
465
|
+
const rawLeaf = row.leaf;
|
|
466
|
+
const leaf = rawLeaf === true || rawLeaf === 1 || rawLeaf === "1" || String(rawLeaf).toLowerCase() === "true" ? MENU_LEAF_YES : Number(rawLeaf) === MENU_LEAF_YES ? MENU_LEAF_YES : 0;
|
|
463
467
|
return {
|
|
464
468
|
resourceId: String(resourceId),
|
|
465
469
|
parentId,
|
|
466
470
|
depth,
|
|
471
|
+
leaf,
|
|
467
472
|
type: toMenuType(row.type),
|
|
468
473
|
name: String(row.name ?? ""),
|
|
469
474
|
identification: String(row.identification ?? row.identity ?? row.path ?? ""),
|
|
@@ -472,6 +477,9 @@ function mapMenuResource(item) {
|
|
|
472
477
|
status: toResourceStatus(row.status)
|
|
473
478
|
};
|
|
474
479
|
}
|
|
480
|
+
function isMenuLeaf(row) {
|
|
481
|
+
return Number(row.leaf) === MENU_LEAF_YES;
|
|
482
|
+
}
|
|
475
483
|
function resolveMenuDepth(parentId, menus) {
|
|
476
484
|
if (!parentId) return ROOT_MENU_DEPTH;
|
|
477
485
|
const parent = menus.find((item) => item.resourceId === parentId);
|
|
@@ -481,6 +489,9 @@ function resolveMenuDepth(parentId, menus) {
|
|
|
481
489
|
function buildListUrl(type, params) {
|
|
482
490
|
const parts = [];
|
|
483
491
|
appendQueryParam(parts, "type", type);
|
|
492
|
+
if (params?.depth !== void 0 && params?.depth !== null && String(params.depth) !== "") {
|
|
493
|
+
appendQueryParam(parts, "depth", String(params.depth));
|
|
494
|
+
}
|
|
484
495
|
appendQueryParam(parts, "page-token", params?.pagination?.pageToken ?? "");
|
|
485
496
|
appendQueryParam(parts, "page-size", params?.pagination?.pageSize ?? "20");
|
|
486
497
|
appendQueryParam(parts, "page-direction", params?.pagination?.pageDirection ?? "current");
|
|
@@ -578,7 +589,10 @@ function createMenuResourceApi(request) {
|
|
|
578
589
|
async list(params, signal) {
|
|
579
590
|
const json = await request({
|
|
580
591
|
method: "GET",
|
|
581
|
-
url: buildListUrl(MENU_LIST_TYPE_PARAM,
|
|
592
|
+
url: buildListUrl(MENU_LIST_TYPE_PARAM, {
|
|
593
|
+
pagination: params?.pagination,
|
|
594
|
+
depth: params?.depth ?? ROOT_MENU_DEPTH
|
|
595
|
+
}),
|
|
582
596
|
signal
|
|
583
597
|
});
|
|
584
598
|
const records = extractRecords(json).map(mapMenuResource).filter((item) => item !== null);
|
|
@@ -588,6 +602,14 @@ function createMenuResourceApi(request) {
|
|
|
588
602
|
...pagination
|
|
589
603
|
};
|
|
590
604
|
},
|
|
605
|
+
async listSubResources(resourceId, signal) {
|
|
606
|
+
const json = await request({
|
|
607
|
+
method: "GET",
|
|
608
|
+
url: `/authorization-resources/${encodeURIComponent(resourceId)}/sub-resources`,
|
|
609
|
+
signal
|
|
610
|
+
});
|
|
611
|
+
return extractRecords(json).map(mapMenuResource).filter((item) => item !== null);
|
|
612
|
+
},
|
|
591
613
|
listPermissionPoints(params, signal) {
|
|
592
614
|
return permissionApi.list(params, signal);
|
|
593
615
|
},
|
|
@@ -1208,6 +1230,9 @@ function MenuManager({
|
|
|
1208
1230
|
toolbarExtra
|
|
1209
1231
|
}) {
|
|
1210
1232
|
const [records, setRecords] = useState3([]);
|
|
1233
|
+
const [childrenMap, setChildrenMap] = useState3({});
|
|
1234
|
+
const [expandedIds, setExpandedIds] = useState3({});
|
|
1235
|
+
const [expandingIds, setExpandingIds] = useState3({});
|
|
1211
1236
|
const [permissionPoints, setPermissionPoints] = useState3([]);
|
|
1212
1237
|
const [loading, setLoading] = useState3(false);
|
|
1213
1238
|
const [error, setError] = useState3("");
|
|
@@ -1226,18 +1251,40 @@ function MenuManager({
|
|
|
1226
1251
|
permissionPoints.forEach((p) => map.set(p.resourceId, p.name || p.identification));
|
|
1227
1252
|
return map;
|
|
1228
1253
|
}, [permissionPoints]);
|
|
1254
|
+
const allKnownMenus = useMemo3(() => {
|
|
1255
|
+
const map = /* @__PURE__ */ new Map();
|
|
1256
|
+
records.forEach((row) => map.set(row.resourceId, row));
|
|
1257
|
+
Object.values(childrenMap).forEach((list) => {
|
|
1258
|
+
list.forEach((row) => map.set(row.resourceId, row));
|
|
1259
|
+
});
|
|
1260
|
+
return Array.from(map.values());
|
|
1261
|
+
}, [records, childrenMap]);
|
|
1229
1262
|
const parentOptions = useMemo3(() => {
|
|
1230
|
-
return
|
|
1263
|
+
return allKnownMenus.filter((row) => !editing || row.resourceId !== editing.resourceId).map((row) => ({
|
|
1231
1264
|
value: row.resourceId,
|
|
1232
1265
|
label: `${row.name}\uFF08${MENU_TYPE_LABEL[row.type]}\uFF09`
|
|
1233
1266
|
}));
|
|
1234
|
-
}, [
|
|
1267
|
+
}, [allKnownMenus, editing]);
|
|
1268
|
+
const flatRows = useMemo3(() => {
|
|
1269
|
+
const rows = [];
|
|
1270
|
+
const walk = (list) => {
|
|
1271
|
+
list.forEach((row) => {
|
|
1272
|
+
rows.push(row);
|
|
1273
|
+
if (expandedIds[row.resourceId] && childrenMap[row.resourceId]?.length) {
|
|
1274
|
+
walk(childrenMap[row.resourceId]);
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
};
|
|
1278
|
+
walk(records);
|
|
1279
|
+
return rows;
|
|
1280
|
+
}, [records, childrenMap, expandedIds]);
|
|
1235
1281
|
const loadList = useCallback3(
|
|
1236
1282
|
async (direction = "current", token = pageToken) => {
|
|
1237
1283
|
setLoading(true);
|
|
1238
1284
|
setError("");
|
|
1239
1285
|
try {
|
|
1240
1286
|
const result = await api.list({
|
|
1287
|
+
depth: ROOT_MENU_DEPTH,
|
|
1241
1288
|
pagination: {
|
|
1242
1289
|
pageToken: token,
|
|
1243
1290
|
pageSize,
|
|
@@ -1245,6 +1292,9 @@ function MenuManager({
|
|
|
1245
1292
|
}
|
|
1246
1293
|
});
|
|
1247
1294
|
setRecords(result.records);
|
|
1295
|
+
setChildrenMap({});
|
|
1296
|
+
setExpandedIds({});
|
|
1297
|
+
setExpandingIds({});
|
|
1248
1298
|
setPageToken(result.pageToken);
|
|
1249
1299
|
setHasPreviousPage(result.hasPreviousPage);
|
|
1250
1300
|
setHasNextPage(result.hasNextPage);
|
|
@@ -1265,6 +1315,29 @@ function MenuManager({
|
|
|
1265
1315
|
} catch {
|
|
1266
1316
|
}
|
|
1267
1317
|
}, [api]);
|
|
1318
|
+
const toggleExpand = async (row) => {
|
|
1319
|
+
if (isMenuLeaf(row)) return;
|
|
1320
|
+
const id = row.resourceId;
|
|
1321
|
+
if (expandedIds[id]) {
|
|
1322
|
+
setExpandedIds((prev) => ({ ...prev, [id]: false }));
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
if (!childrenMap[id]) {
|
|
1326
|
+
setExpandingIds((prev) => ({ ...prev, [id]: true }));
|
|
1327
|
+
setError("");
|
|
1328
|
+
try {
|
|
1329
|
+
const children = await api.listSubResources(id);
|
|
1330
|
+
setChildrenMap((prev) => ({ ...prev, [id]: children }));
|
|
1331
|
+
setExpandedIds((prev) => ({ ...prev, [id]: true }));
|
|
1332
|
+
} catch (err) {
|
|
1333
|
+
setError(err instanceof Error ? err.message : "\u52A0\u8F7D\u4E0B\u7EA7\u83DC\u5355\u5931\u8D25");
|
|
1334
|
+
} finally {
|
|
1335
|
+
setExpandingIds((prev) => ({ ...prev, [id]: false }));
|
|
1336
|
+
}
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
setExpandedIds((prev) => ({ ...prev, [id]: true }));
|
|
1340
|
+
};
|
|
1268
1341
|
useEffect3(() => {
|
|
1269
1342
|
void loadList("current", "");
|
|
1270
1343
|
void loadPermissionPoints();
|
|
@@ -1279,7 +1352,7 @@ function MenuManager({
|
|
|
1279
1352
|
setEditing(row);
|
|
1280
1353
|
setForm({
|
|
1281
1354
|
parentId: row.parentId ?? null,
|
|
1282
|
-
depth: resolveMenuDepth(row.parentId ?? null,
|
|
1355
|
+
depth: resolveMenuDepth(row.parentId ?? null, allKnownMenus),
|
|
1283
1356
|
type: row.type,
|
|
1284
1357
|
name: row.name,
|
|
1285
1358
|
identification: row.identification,
|
|
@@ -1367,35 +1440,54 @@ function MenuManager({
|
|
|
1367
1440
|
/* @__PURE__ */ jsx3("th", { style: styles2.th, children: "\u6743\u9650\u6807\u8BC6" }),
|
|
1368
1441
|
/* @__PURE__ */ jsx3("th", { style: { ...styles2.th, width: 140 }, children: "\u64CD\u4F5C" })
|
|
1369
1442
|
] }) }),
|
|
1370
|
-
/* @__PURE__ */ jsx3("tbody", { children: loading ? /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsx3("td", { colSpan: 6, style: styles2.empty, children: "\u52A0\u8F7D\u4E2D\u2026" }) }) :
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
{
|
|
1377
|
-
style:
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1443
|
+
/* @__PURE__ */ jsx3("tbody", { children: loading ? /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsx3("td", { colSpan: 6, style: styles2.empty, children: "\u52A0\u8F7D\u4E2D\u2026" }) }) : flatRows.length === 0 ? /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsx3("td", { colSpan: 6, style: styles2.empty, children: "\u6682\u65E0\u6570\u636E" }) }) : flatRows.map((row) => {
|
|
1444
|
+
const leaf = isMenuLeaf(row);
|
|
1445
|
+
const expanded = Boolean(expandedIds[row.resourceId]);
|
|
1446
|
+
const expanding = Boolean(expandingIds[row.resourceId]);
|
|
1447
|
+
const indent = Math.max(0, (row.depth || 1) - 1) * 18;
|
|
1448
|
+
return /* @__PURE__ */ jsxs2("tr", { children: [
|
|
1449
|
+
/* @__PURE__ */ jsx3("td", { style: styles2.td, children: /* @__PURE__ */ jsxs2("div", { style: { ...styles2.treeCell, paddingLeft: indent }, children: [
|
|
1450
|
+
leaf ? /* @__PURE__ */ jsx3("span", { style: styles2.treeSpacer }) : /* @__PURE__ */ jsx3(
|
|
1451
|
+
"button",
|
|
1452
|
+
{
|
|
1453
|
+
type: "button",
|
|
1454
|
+
style: styles2.treeToggle,
|
|
1455
|
+
onClick: () => void toggleExpand(row),
|
|
1456
|
+
disabled: expanding,
|
|
1457
|
+
"aria-label": expanded ? "\u6536\u8D77" : "\u5C55\u5F00",
|
|
1458
|
+
children: expanding ? "\u2026" : expanded ? "\u25BC" : "\u25B6"
|
|
1459
|
+
}
|
|
1460
|
+
),
|
|
1461
|
+
/* @__PURE__ */ jsx3("span", { children: row.name })
|
|
1462
|
+
] }) }),
|
|
1463
|
+
/* @__PURE__ */ jsx3("td", { style: styles2.td, children: /* @__PURE__ */ jsx3("code", { style: styles2.code, children: row.identification || "\u2014" }) }),
|
|
1464
|
+
/* @__PURE__ */ jsx3("td", { style: styles2.td, children: MENU_TYPE_LABEL[row.type] }),
|
|
1465
|
+
/* @__PURE__ */ jsx3("td", { style: styles2.td, children: /* @__PURE__ */ jsx3(
|
|
1466
|
+
"span",
|
|
1390
1467
|
{
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1468
|
+
style: {
|
|
1469
|
+
...styles2.badge,
|
|
1470
|
+
background: row.status === RESOURCE_STATUS_ENABLED ? "#e8f7ef" : "#f4f4f5",
|
|
1471
|
+
color: row.status === RESOURCE_STATUS_ENABLED ? "#067647" : "#667085"
|
|
1472
|
+
},
|
|
1473
|
+
children: row.status === RESOURCE_STATUS_ENABLED ? "\u663E\u793A" : "\u9690\u85CF"
|
|
1395
1474
|
}
|
|
1396
|
-
)
|
|
1397
|
-
|
|
1398
|
-
|
|
1475
|
+
) }),
|
|
1476
|
+
/* @__PURE__ */ jsx3("td", { style: styles2.td, children: renderPermissionLabels(row) }),
|
|
1477
|
+
/* @__PURE__ */ jsxs2("td", { style: styles2.td, children: [
|
|
1478
|
+
/* @__PURE__ */ jsx3("button", { type: "button", style: styles2.linkBtn, onClick: () => openEdit(row), children: "\u7F16\u8F91" }),
|
|
1479
|
+
/* @__PURE__ */ jsx3(
|
|
1480
|
+
"button",
|
|
1481
|
+
{
|
|
1482
|
+
type: "button",
|
|
1483
|
+
style: { ...styles2.linkBtn, color: "#d92d20" },
|
|
1484
|
+
onClick: () => askDelete(row),
|
|
1485
|
+
children: "\u5220\u9664"
|
|
1486
|
+
}
|
|
1487
|
+
)
|
|
1488
|
+
] })
|
|
1489
|
+
] }, row.resourceId);
|
|
1490
|
+
}) })
|
|
1399
1491
|
] }) }),
|
|
1400
1492
|
/* @__PURE__ */ jsxs2("div", { style: styles2.pagination, children: [
|
|
1401
1493
|
/* @__PURE__ */ jsxs2("label", { style: styles2.pageSize, children: [
|
|
@@ -1461,7 +1553,7 @@ function MenuManager({
|
|
|
1461
1553
|
setForm((prev) => ({
|
|
1462
1554
|
...prev,
|
|
1463
1555
|
parentId,
|
|
1464
|
-
depth: resolveMenuDepth(parentId,
|
|
1556
|
+
depth: resolveMenuDepth(parentId, allKnownMenus)
|
|
1465
1557
|
}));
|
|
1466
1558
|
},
|
|
1467
1559
|
children: [
|
|
@@ -1659,6 +1751,30 @@ var styles2 = {
|
|
|
1659
1751
|
borderBottom: "1px solid #f2f4f7",
|
|
1660
1752
|
verticalAlign: "middle"
|
|
1661
1753
|
},
|
|
1754
|
+
treeCell: {
|
|
1755
|
+
display: "flex",
|
|
1756
|
+
alignItems: "center",
|
|
1757
|
+
gap: 6
|
|
1758
|
+
},
|
|
1759
|
+
treeToggle: {
|
|
1760
|
+
width: 22,
|
|
1761
|
+
height: 22,
|
|
1762
|
+
border: "1px solid #d0d5dd",
|
|
1763
|
+
borderRadius: 4,
|
|
1764
|
+
background: "#fff",
|
|
1765
|
+
color: "#475467",
|
|
1766
|
+
cursor: "pointer",
|
|
1767
|
+
fontSize: 10,
|
|
1768
|
+
lineHeight: "20px",
|
|
1769
|
+
padding: 0,
|
|
1770
|
+
flexShrink: 0
|
|
1771
|
+
},
|
|
1772
|
+
treeSpacer: {
|
|
1773
|
+
width: 22,
|
|
1774
|
+
height: 22,
|
|
1775
|
+
flexShrink: 0,
|
|
1776
|
+
display: "inline-block"
|
|
1777
|
+
},
|
|
1662
1778
|
empty: { padding: 28, textAlign: "center", color: "#98a2b3", fontSize: 14 },
|
|
1663
1779
|
code: {
|
|
1664
1780
|
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
@@ -1967,6 +2083,8 @@ var styles3 = {
|
|
|
1967
2083
|
};
|
|
1968
2084
|
export {
|
|
1969
2085
|
Can,
|
|
2086
|
+
MENU_LEAF_NO,
|
|
2087
|
+
MENU_LEAF_YES,
|
|
1970
2088
|
MENU_LIST_TYPE_PARAM,
|
|
1971
2089
|
MENU_TYPE_BUTTON,
|
|
1972
2090
|
MENU_TYPE_LABEL,
|
|
@@ -2001,6 +2119,7 @@ export {
|
|
|
2001
2119
|
extractRecords,
|
|
2002
2120
|
getAppClientId,
|
|
2003
2121
|
getDeviceWorkerId,
|
|
2122
|
+
isMenuLeaf,
|
|
2004
2123
|
mapAuthorizationResource,
|
|
2005
2124
|
mapMenuResource,
|
|
2006
2125
|
resolveMenuDepth,
|