@hkyhy/marsun-components-core 0.1.69 → 0.1.73

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.
Files changed (47) hide show
  1. package/dist/components/Form/kneFormInfo.js +6 -6
  2. package/dist/components/Iam/client.d.ts +42 -0
  3. package/dist/components/Iam/index.d.ts +10 -0
  4. package/dist/components/Iam/pages/IamOrgPage.d.ts +8 -0
  5. package/dist/components/Iam/pages/IamOrgPage.js +45 -0
  6. package/dist/components/Iam/pages/IamOrgPage.js.map +1 -0
  7. package/dist/components/Iam/pages/IamRolesPage.d.ts +24 -0
  8. package/dist/components/Iam/pages/IamRolesPage.js +222 -0
  9. package/dist/components/Iam/pages/IamRolesPage.js.map +1 -0
  10. package/dist/components/Iam/pages/IamSharedGroupsPage.d.ts +6 -0
  11. package/dist/components/Iam/pages/IamSharedGroupsPage.js +207 -0
  12. package/dist/components/Iam/pages/IamSharedGroupsPage.js.map +1 -0
  13. package/dist/components/Iam/pages/IamUsersPage.d.ts +10 -0
  14. package/dist/components/Iam/pages/IamUsersPage.js +314 -0
  15. package/dist/components/Iam/pages/IamUsersPage.js.map +1 -0
  16. package/dist/components/Iam/types.d.ts +85 -0
  17. package/dist/components/Iam/utils/catalogToItems.d.ts +3 -0
  18. package/dist/components/Iam/utils/catalogToItems.js +17 -0
  19. package/dist/components/Iam/utils/catalogToItems.js.map +1 -0
  20. package/dist/components/Iam/utils/draftEffectivePermissions.d.ts +48 -0
  21. package/dist/components/Iam/utils/draftEffectivePermissions.js +42 -0
  22. package/dist/components/Iam/utils/draftEffectivePermissions.js.map +1 -0
  23. package/dist/components/Iam/utils/multiTagSelect.d.ts +15 -0
  24. package/dist/components/Iam/utils/multiTagSelect.js +21 -0
  25. package/dist/components/Iam/utils/multiTagSelect.js.map +1 -0
  26. package/dist/components/Iam/utils/roleDisplay.d.ts +13 -0
  27. package/dist/components/Iam/utils/roleDisplay.js +17 -0
  28. package/dist/components/Iam/utils/roleDisplay.js.map +1 -0
  29. package/dist/components/Layout/AgentAppShell/style.module.scss.js +20 -20
  30. package/dist/components/Layout/ModulePageShell/index.d.ts +5 -0
  31. package/dist/components/Layout/ModulePageShell/index.js +52 -29
  32. package/dist/components/Layout/ModulePageShell/index.js.map +1 -1
  33. package/dist/components/Layout/ModulePageShell/style.module.scss.js +6 -4
  34. package/dist/components/Layout/ModulePageShell/style.module.scss.js.map +1 -1
  35. package/dist/components/Layout/PageSpin/index.d.ts +2 -0
  36. package/dist/components/Layout/PageSpin/index.js +24 -6
  37. package/dist/components/Layout/PageSpin/index.js.map +1 -1
  38. package/dist/components/Layout/PageSpin/style.module.scss.js +2 -1
  39. package/dist/components/Layout/PageSpin/style.module.scss.js.map +1 -1
  40. package/dist/components/PermissionBindPanel/PermissionBindPanel.js +110 -98
  41. package/dist/components/PermissionBindPanel/PermissionBindPanel.js.map +1 -1
  42. package/dist/iam.d.ts +14 -0
  43. package/dist/iam.js +23 -0
  44. package/dist/iam.js.map +1 -0
  45. package/dist/marsun-components-core.css +1 -1
  46. package/dist/styles/global.css +1 -1
  47. package/package.json +5 -1
@@ -1,22 +1,22 @@
1
1
  /* empty css */
2
- import s, { Form as e, FormModal as n, FormSteps as a, FormStepsModal as r, List as c, MultiField as i, TableList as m } from "@kne/form-info";
3
- import { CancelButton as u, ResetButton as l, SubmitButton as p, Input as S, InputNumber as d, RadioGroup as F, Select as $, Switch as b, TextArea as T, TreeSelect as B } from "@kne/react-form-antd";
2
+ import s, { FormModal as e, Form as n, FormSteps as a, FormStepsModal as r, List as c, MultiField as i, TableList as m } from "@kne/form-info";
3
+ import { CancelButton as u, ResetButton as l, SubmitButton as p, Select as S, Input as d, InputNumber as F, RadioGroup as $, Switch as b, TextArea as T, TreeSelect as B } from "@kne/react-form-antd";
4
4
  import { withNormalizedLabelTips as t } from "./normalizeLabelTips.js";
5
5
  import { normalizeLabelTips as H } from "./normalizeLabelTips.js";
6
- const R = s, x = e, h = n, N = a, A = r, C = c, G = m, z = i, o = S, I = t(o), P = Object.assign(I, {
6
+ const R = s, x = n, h = e, N = a, A = r, C = c, G = m, z = i, o = d, I = t(o), P = Object.assign(I, {
7
7
  Password: t(o.Password)
8
8
  }), g = t(
9
9
  T
10
10
  ), j = t(
11
- $
11
+ S
12
12
  ), y = t(
13
13
  B
14
14
  ), K = t(
15
- d
15
+ F
16
16
  ), O = t(
17
17
  b
18
18
  ), W = t(
19
- F
19
+ $
20
20
  ), k = p, q = l, v = u;
21
21
  export {
22
22
  v as CancelButton,
@@ -0,0 +1,42 @@
1
+ import { IamOrgUnit, IamPermission, IamRole, IamSharedGroup, IamUser, IamUsersPageResult } from './types';
2
+ /**
3
+ * App 侧 `ssoIam.ts` 实现本接口;core 页面只依赖注入对象,不内置 fetch。
4
+ */
5
+ export type IamClient = {
6
+ listUsers: (params?: {
7
+ page?: number;
8
+ pageSize?: number;
9
+ keyword?: string;
10
+ }) => Promise<IamUsersPageResult>;
11
+ getUser: (id: string) => Promise<IamUser>;
12
+ listRoles: () => Promise<IamRole[]>;
13
+ createRole: (body: {
14
+ name: string;
15
+ description?: string;
16
+ }) => Promise<IamRole>;
17
+ updateRole: (id: string, body: {
18
+ name?: string;
19
+ description?: string;
20
+ }) => Promise<IamRole>;
21
+ deleteRole: (id: string) => Promise<void>;
22
+ setRolePermissions: (roleId: string, permissionIds: string[]) => Promise<void>;
23
+ listPermissions: () => Promise<IamPermission[]>;
24
+ listOrgUnits: () => Promise<IamOrgUnit[]>;
25
+ listSharedGroups: () => Promise<IamSharedGroup[]>;
26
+ createSharedGroup: (body: {
27
+ code: string;
28
+ name: string;
29
+ description?: string;
30
+ roleIds?: string[];
31
+ }) => Promise<IamSharedGroup>;
32
+ updateSharedGroup: (id: string, body: {
33
+ name?: string;
34
+ description?: string;
35
+ }) => Promise<IamSharedGroup>;
36
+ deleteSharedGroup: (id: string) => Promise<void>;
37
+ addSharedGroupMembers: (groupId: string, userIds: string[]) => Promise<void>;
38
+ removeSharedGroupMembers: (groupId: string, userIds: string[]) => Promise<void>;
39
+ listUserSharedGroups: (userId: string) => Promise<IamSharedGroup[]>;
40
+ setUserAppRoleCodes: (userId: string, roleCodes: string[]) => Promise<void>;
41
+ setUserSharedGroups: (userId: string, groupIds: string[]) => Promise<void>;
42
+ };
@@ -0,0 +1,10 @@
1
+ export type { IamClient } from './client';
2
+ export type { IamOrgUnit, IamPermission, IamRole, IamSharedGroup, IamUser, IamUsersPageResult, } from './types';
3
+ export { buildDraftEffectivePermissions, type DraftEpPerm, } from './utils/draftEffectivePermissions';
4
+ export { roleDisplayName, roleSelectOption } from './utils/roleDisplay';
5
+ export { MULTI_TAG_SHOW_LENGTH, multiTagSelectProps } from './utils/multiTagSelect';
6
+ export { catalogToItems } from './utils/catalogToItems';
7
+ export { default as IamUsersPage, type IamUsersPageProps } from './pages/IamUsersPage';
8
+ export { IamRolesPage, IamRolePermissionsPage, displayRoleDescription, type IamRolesPageProps, type IamRolePermissionsPageProps, } from './pages/IamRolesPage';
9
+ export { default as IamOrgPage, type IamOrgPageProps } from './pages/IamOrgPage';
10
+ export { default as IamSharedGroupsPage, type IamSharedGroupsPageProps, } from './pages/IamSharedGroupsPage';
@@ -0,0 +1,8 @@
1
+ import { IamClient } from '../client';
2
+ export type IamOrgPageProps = {
3
+ client: IamClient;
4
+ /** SSO Admin 组织维护页 URL(由 App 用 AUTH_LOGIN_URL 推导) */
5
+ ssoOrgAdminUrl: string;
6
+ title?: string;
7
+ };
8
+ export default function IamOrgPage({ client, ssoOrgAdminUrl, title, }: IamOrgPageProps): import("react").JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { jsxs as c, jsx as o } from "react/jsx-runtime";
2
+ import { message as g } from "antd";
3
+ import { useState as i, useEffect as u, useMemo as h } from "react";
4
+ import p from "../../Layout/ModulePageShell/index.js";
5
+ import S from "../../Alert/Alert.js";
6
+ import O from "../../OrgTree/OrgTree.js";
7
+ function l(r) {
8
+ return r.map((e) => {
9
+ var t;
10
+ return {
11
+ id: e.id,
12
+ name: e.name,
13
+ parentId: e.parentId ?? null,
14
+ children: (t = e.children) != null && t.length ? l(e.children) : void 0
15
+ };
16
+ });
17
+ }
18
+ function v({
19
+ client: r,
20
+ ssoOrgAdminUrl: e,
21
+ title: t = "组织架构管理"
22
+ }) {
23
+ const [m, s] = i(!1), [n, f] = i([]);
24
+ u(() => {
25
+ s(!0), r.listOrgUnits().then(f).catch((a) => g.error(a instanceof Error ? a.message : "加载失败")).finally(() => s(!1));
26
+ }, [r]);
27
+ const d = h(() => l(n), [n]);
28
+ return /* @__PURE__ */ c(p, { title: t, fillHeight: !1, children: [
29
+ /* @__PURE__ */ o(
30
+ S,
31
+ {
32
+ type: "info",
33
+ showIcon: !0,
34
+ style: { marginBottom: 16 },
35
+ message: "组织架构请在 SSO 维护",
36
+ description: /* @__PURE__ */ o("a", { href: e, target: "_blank", rel: "noreferrer", children: "打开 SSO 组织" })
37
+ }
38
+ ),
39
+ /* @__PURE__ */ o(O, { nodes: d, loading: m, editable: !1 })
40
+ ] });
41
+ }
42
+ export {
43
+ v as default
44
+ };
45
+ //# sourceMappingURL=IamOrgPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IamOrgPage.js","sources":["../../../../src/components/Iam/pages/IamOrgPage.tsx"],"sourcesContent":["import { Alert } from '@/components/Alert';\nimport { ModulePageShell } from '@/components/Layout';\nimport { OrgTree, type OrgTreeNode } from '@/components/OrgTree';\nimport { message } from 'antd';\nimport { useEffect, useMemo, useState } from 'react';\nimport type { IamClient } from '../client';\nimport type { IamOrgUnit } from '../types';\n\nfunction toNodes(nodes: IamOrgUnit[]): OrgTreeNode[] {\n return nodes.map((n) => ({\n id: n.id,\n name: n.name,\n parentId: n.parentId ?? null,\n children: n.children?.length ? toNodes(n.children) : undefined,\n }));\n}\n\nexport type IamOrgPageProps = {\n client: IamClient;\n /** SSO Admin 组织维护页 URL(由 App 用 AUTH_LOGIN_URL 推导) */\n ssoOrgAdminUrl: string;\n title?: string;\n};\n\nexport default function IamOrgPage({\n client,\n ssoOrgAdminUrl,\n title = '组织架构管理',\n}: IamOrgPageProps) {\n const [loading, setLoading] = useState(false);\n const [tree, setTree] = useState<IamOrgUnit[]>([]);\n\n useEffect(() => {\n setLoading(true);\n void client\n .listOrgUnits()\n .then(setTree)\n .catch((e) => message.error(e instanceof Error ? e.message : '加载失败'))\n .finally(() => setLoading(false));\n }, [client]);\n\n const nodes = useMemo(() => toNodes(tree), [tree]);\n\n return (\n <ModulePageShell title={title} fillHeight={false}>\n <Alert\n type=\"info\"\n showIcon\n style={{ marginBottom: 16 }}\n message=\"组织架构请在 SSO 维护\"\n description={\n <a href={ssoOrgAdminUrl} target=\"_blank\" rel=\"noreferrer\">\n 打开 SSO 组织\n </a>\n }\n />\n <OrgTree nodes={nodes} loading={loading} editable={false} />\n </ModulePageShell>\n );\n}\n"],"names":["toNodes","nodes","n","_a","IamOrgPage","client","ssoOrgAdminUrl","title","loading","setLoading","useState","tree","setTree","useEffect","e","message","useMemo","jsxs","ModulePageShell","jsx","Alert","OrgTree"],"mappings":";;;;;;AAQA,SAASA,EAAQC,GAAoC;AACnD,SAAOA,EAAM,IAAI,CAACC,MAAA;;AAAO;AAAA,MACvB,IAAIA,EAAE;AAAA,MACN,MAAMA,EAAE;AAAA,MACR,UAAUA,EAAE,YAAY;AAAA,MACxB,WAAUC,IAAAD,EAAE,aAAF,QAAAC,EAAY,SAASH,EAAQE,EAAE,QAAQ,IAAI;AAAA,IAAA;AAAA,GACrD;AACJ;AASA,SAAwBE,EAAW;AAAA,EACjC,QAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,OAAAC,IAAQ;AACV,GAAoB;AAClB,QAAM,CAACC,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtC,CAACC,GAAMC,CAAO,IAAIF,EAAuB,CAAA,CAAE;AAEjD,EAAAG,EAAU,MAAM;AACd,IAAAJ,EAAW,EAAI,GACVJ,EACF,eACA,KAAKO,CAAO,EACZ,MAAM,CAACE,MAAMC,EAAQ,MAAMD,aAAa,QAAQA,EAAE,UAAU,MAAM,CAAC,EACnE,QAAQ,MAAML,EAAW,EAAK,CAAC;AAAA,EACpC,GAAG,CAACJ,CAAM,CAAC;AAEX,QAAMJ,IAAQe,EAAQ,MAAMhB,EAAQW,CAAI,GAAG,CAACA,CAAI,CAAC;AAEjD,SACE,gBAAAM,EAACC,GAAA,EAAgB,OAAAX,GAAc,YAAY,IACzC,UAAA;AAAA,IAAA,gBAAAY;AAAA,MAACC;AAAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,UAAQ;AAAA,QACR,OAAO,EAAE,cAAc,GAAA;AAAA,QACvB,SAAQ;AAAA,QACR,+BACG,KAAA,EAAE,MAAMd,GAAgB,QAAO,UAAS,KAAI,cAAa,UAAA,YAAA,CAE1D;AAAA,MAAA;AAAA,IAAA;AAAA,IAGJ,gBAAAa,EAACE,GAAA,EAAQ,OAAApB,GAAc,SAAAO,GAAkB,UAAU,GAAA,CAAO;AAAA,EAAA,GAC5D;AAEJ;"}
@@ -0,0 +1,24 @@
1
+ import { PermissionBindCatalog } from '../../PermissionBindPanel';
2
+ import { IamClient } from '../client';
3
+ /** 隐藏矩阵 sync 运维 provenance,不当作用户可读描述 */
4
+ export declare function displayRoleDescription(v: string | null | undefined): string;
5
+ export type IamRolesPageProps = {
6
+ client: IamClient;
7
+ /** 角色列表路由,默认 `/config/iam/roles` */
8
+ rolesListPath?: string;
9
+ /** 绑权页路径工厂 */
10
+ rolePermissionsPath?: (roleId: string) => string;
11
+ title?: string;
12
+ };
13
+ export declare function IamRolesPage({ client, rolesListPath, rolePermissionsPath, title, }: IamRolesPageProps): import("react").JSX.Element;
14
+ export type IamRolePermissionsPageProps = {
15
+ client: IamClient;
16
+ catalog: PermissionBindCatalog;
17
+ systemEntryCodes: readonly string[];
18
+ systemAppCode: string;
19
+ rolesListPath?: string;
20
+ onAfterSave?: () => void | Promise<void>;
21
+ emptyCatalogHint?: string;
22
+ title?: string;
23
+ };
24
+ export declare function IamRolePermissionsPage({ client, catalog, systemEntryCodes, systemAppCode, rolesListPath, onAfterSave, emptyCatalogHint, title, }: IamRolePermissionsPageProps): import("react").JSX.Element;
@@ -0,0 +1,222 @@
1
+ import { jsxs as R, jsx as r } from "react/jsx-runtime";
2
+ import { message as d, Typography as T, Empty as N, Form as x, Table as V, Space as W, Button as B, Modal as Y, Input as M } from "antd";
3
+ import { useState as a, useRef as G, useEffect as _, useMemo as F, useCallback as j } from "react";
4
+ import { useParams as J, useNavigate as H } from "react-router-dom";
5
+ import U from "../../Layout/ModulePageShell/index.js";
6
+ import Q from "../../PermissionBindPanel/PermissionBindPanel.js";
7
+ function z(n) {
8
+ const m = (n || "").trim();
9
+ return !m || /^(Synced from .+ role matrix|S3 Wave2 pilot matrix)/i.test(m) ? "—" : m;
10
+ }
11
+ function ne({
12
+ client: n,
13
+ rolesListPath: m = "/config/iam/roles",
14
+ rolePermissionsPath: S,
15
+ title: k = "角色管理"
16
+ }) {
17
+ const P = H(), f = S ?? ((s) => `${m}/${s}/permissions`), [b, C] = a(!1), [o, E] = a([]), [y, h] = a(!1), [u, w] = a(null), [t] = x.useForm(), p = j(async () => {
18
+ C(!0);
19
+ try {
20
+ E(await n.listRoles());
21
+ } catch (s) {
22
+ d.error(s instanceof Error ? s.message : "加载失败");
23
+ } finally {
24
+ C(!1);
25
+ }
26
+ }, [n]);
27
+ _(() => {
28
+ p();
29
+ }, [p]);
30
+ const v = F(
31
+ () => [
32
+ {
33
+ children: "新增角色",
34
+ type: "primary",
35
+ onClick: () => {
36
+ w(null), t.resetFields(), h(!0);
37
+ }
38
+ }
39
+ ],
40
+ [t]
41
+ );
42
+ return /* @__PURE__ */ R(U, { title: k, actions: v, fillHeight: !1, children: [
43
+ /* @__PURE__ */ r(
44
+ V,
45
+ {
46
+ rowKey: "id",
47
+ loading: b,
48
+ dataSource: o,
49
+ columns: [
50
+ { title: "角色名称", dataIndex: "name" },
51
+ { title: "编码", dataIndex: "code" },
52
+ {
53
+ title: "描述",
54
+ dataIndex: "description",
55
+ render: (s) => z(s)
56
+ },
57
+ {
58
+ title: "用户数",
59
+ key: "uc",
60
+ render: (s, e) => {
61
+ var l;
62
+ return ((l = e._count) == null ? void 0 : l.userRoles) ?? "—";
63
+ }
64
+ },
65
+ {
66
+ title: "操作",
67
+ key: "ops",
68
+ render: (s, e) => /* @__PURE__ */ R(W, { children: [
69
+ /* @__PURE__ */ r(B, { type: "link", size: "small", onClick: () => P(f(e.id)), children: "权限管理" }),
70
+ /* @__PURE__ */ r(
71
+ B,
72
+ {
73
+ type: "link",
74
+ size: "small",
75
+ onClick: () => {
76
+ w(e), t.setFieldsValue({
77
+ name: e.name,
78
+ description: z(e.description) === "—" ? "" : e.description || ""
79
+ }), h(!0);
80
+ },
81
+ children: "编辑"
82
+ }
83
+ ),
84
+ /* @__PURE__ */ r(
85
+ B,
86
+ {
87
+ type: "link",
88
+ size: "small",
89
+ danger: !0,
90
+ disabled: !!e.isBuiltin,
91
+ onClick: async () => {
92
+ try {
93
+ await n.deleteRole(e.id), d.success("已删除"), p();
94
+ } catch (l) {
95
+ d.error(l instanceof Error ? l.message : "删除失败");
96
+ }
97
+ },
98
+ children: "删除"
99
+ }
100
+ )
101
+ ] })
102
+ }
103
+ ]
104
+ }
105
+ ),
106
+ /* @__PURE__ */ r(
107
+ Y,
108
+ {
109
+ open: y,
110
+ title: u ? "编辑角色" : "新增角色",
111
+ onCancel: () => h(!1),
112
+ onOk: async () => {
113
+ const s = await t.validateFields();
114
+ try {
115
+ u ? await n.updateRole(u.id, s) : await n.createRole(s), d.success("已保存"), h(!1), p();
116
+ } catch (e) {
117
+ d.error(e instanceof Error ? e.message : "失败");
118
+ }
119
+ },
120
+ children: /* @__PURE__ */ R(x, { form: t, layout: "vertical", children: [
121
+ /* @__PURE__ */ r(x.Item, { name: "name", label: "角色名称", rules: [{ required: !0 }], children: /* @__PURE__ */ r(M, { placeholder: "请输入角色名称" }) }),
122
+ /* @__PURE__ */ r(x.Item, { name: "description", label: "角色描述", children: /* @__PURE__ */ r(M.TextArea, { placeholder: "请输入角色描述", rows: 3 }) })
123
+ ] })
124
+ }
125
+ )
126
+ ] });
127
+ }
128
+ function re({
129
+ client: n,
130
+ catalog: m,
131
+ systemEntryCodes: S,
132
+ systemAppCode: k,
133
+ rolesListPath: P = "/config/iam/roles",
134
+ onAfterSave: f,
135
+ emptyCatalogHint: b = "暂无权限点;请先在 SSO 导入本应用目录。",
136
+ title: C = "权限管理"
137
+ }) {
138
+ const { id: o } = J(), E = H(), [y, h] = a(null), [u, w] = a([]), [t, p] = a([]), v = G(t);
139
+ v.current = t;
140
+ const [s, e] = a(!1), [l, O] = a(!1);
141
+ _(() => {
142
+ o && (e(!0), Promise.all([n.listRoles(), n.listPermissions()]).then(([i, K]) => {
143
+ const I = i.find((c) => c.id === o) || null;
144
+ h(I);
145
+ const L = K.filter(
146
+ (c) => {
147
+ var g;
148
+ return c.layer !== "RESOURCE" && (!c.systemAppId || ((g = c.systemApp) == null ? void 0 : g.code) === k);
149
+ }
150
+ );
151
+ w(L), p(
152
+ ((I == null ? void 0 : I.rolePermissions) || []).map((c) => {
153
+ var g;
154
+ return c.permissionId || ((g = c.permission) == null ? void 0 : g.id) || "";
155
+ }).filter(Boolean)
156
+ );
157
+ }).catch((i) => d.error(i instanceof Error ? i.message : "加载失败")).finally(() => e(!1)));
158
+ }, [o, n, k]);
159
+ const $ = F(
160
+ () => u.map((i) => ({
161
+ id: i.id,
162
+ code: i.code,
163
+ name: i.name,
164
+ layer: i.layer
165
+ })),
166
+ [u]
167
+ ), q = j((i) => {
168
+ p(i);
169
+ }, []), D = F(
170
+ () => [
171
+ {
172
+ children: "返回",
173
+ onClick: () => E(P)
174
+ },
175
+ {
176
+ children: "保存",
177
+ type: "primary",
178
+ loading: l,
179
+ onClick: async () => {
180
+ if (o) {
181
+ O(!0);
182
+ try {
183
+ await n.setRolePermissions(o, v.current.filter(Boolean)), d.success("已保存");
184
+ try {
185
+ await (f == null ? void 0 : f());
186
+ } catch {
187
+ }
188
+ } catch (i) {
189
+ d.error(i instanceof Error ? i.message : "保存失败");
190
+ } finally {
191
+ O(!1);
192
+ }
193
+ }
194
+ }
195
+ }
196
+ ],
197
+ [o, E, l, n, P, f]
198
+ );
199
+ return /* @__PURE__ */ R(U, { title: C, actions: D, spinning: s, fillHeight: !1, children: [
200
+ /* @__PURE__ */ R(T.Paragraph, { style: { marginTop: 0 }, children: [
201
+ "角色名称:",
202
+ (y == null ? void 0 : y.name) || "—"
203
+ ] }),
204
+ /* @__PURE__ */ r(T.Paragraph, { type: "secondary", children: "按页面模块 → 分类 → 功能点勾选(中文目录来自 bindCatalog)。须先勾选「进入应用」SYSTEM 入口。RESOURCE 不在此绑定。" }),
205
+ u.length === 0 && !s ? /* @__PURE__ */ r(N, { description: b }) : /* @__PURE__ */ r(
206
+ Q,
207
+ {
208
+ catalog: m,
209
+ permissions: $,
210
+ value: t,
211
+ onChange: q,
212
+ systemEntryCodes: [...S]
213
+ }
214
+ )
215
+ ] });
216
+ }
217
+ export {
218
+ re as IamRolePermissionsPage,
219
+ ne as IamRolesPage,
220
+ z as displayRoleDescription
221
+ };
222
+ //# sourceMappingURL=IamRolesPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IamRolesPage.js","sources":["../../../../src/components/Iam/pages/IamRolesPage.tsx"],"sourcesContent":["import { ModulePageShell } from '@/components/Layout';\nimport { PermissionBindPanel, type PermissionBindCatalog } from '@/components/PermissionBindPanel';\nimport { Button, Empty, Form, Input, Modal, Space, Table, Typography, message } from 'antd';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport type { IamClient } from '../client';\nimport type { IamPermission, IamRole } from '../types';\n\n/** 隐藏矩阵 sync 运维 provenance,不当作用户可读描述 */\nexport function displayRoleDescription(v: string | null | undefined): string {\n const t = (v || '').trim();\n if (!t) return '—';\n if (/^(Synced from .+ role matrix|S3 Wave2 pilot matrix)/i.test(t)) return '—';\n return t;\n}\n\nexport type IamRolesPageProps = {\n client: IamClient;\n /** 角色列表路由,默认 `/config/iam/roles` */\n rolesListPath?: string;\n /** 绑权页路径工厂 */\n rolePermissionsPath?: (roleId: string) => string;\n title?: string;\n};\n\nexport function IamRolesPage({\n client,\n rolesListPath = '/config/iam/roles',\n rolePermissionsPath,\n title = '角色管理',\n}: IamRolesPageProps) {\n const navigate = useNavigate();\n const resolvePermPath =\n rolePermissionsPath ?? ((id: string) => `${rolesListPath}/${id}/permissions`);\n const [loading, setLoading] = useState(false);\n const [rows, setRows] = useState<IamRole[]>([]);\n const [open, setOpen] = useState(false);\n const [editing, setEditing] = useState<IamRole | null>(null);\n const [form] = Form.useForm();\n\n const load = useCallback(async () => {\n setLoading(true);\n try {\n setRows(await client.listRoles());\n } catch (e) {\n message.error(e instanceof Error ? e.message : '加载失败');\n } finally {\n setLoading(false);\n }\n }, [client]);\n\n useEffect(() => {\n void load();\n }, [load]);\n\n const headerActions = useMemo(\n () => [\n {\n children: '新增角色',\n type: 'primary' as const,\n onClick: () => {\n setEditing(null);\n form.resetFields();\n setOpen(true);\n },\n },\n ],\n [form],\n );\n\n return (\n <ModulePageShell title={title} actions={headerActions} fillHeight={false}>\n <Table\n rowKey=\"id\"\n loading={loading}\n dataSource={rows}\n columns={[\n { title: '角色名称', dataIndex: 'name' },\n { title: '编码', dataIndex: 'code' },\n {\n title: '描述',\n dataIndex: 'description',\n render: (v: string | null) => displayRoleDescription(v),\n },\n {\n title: '用户数',\n key: 'uc',\n render: (_: unknown, r: IamRole) => r._count?.userRoles ?? '—',\n },\n {\n title: '操作',\n key: 'ops',\n render: (_: unknown, r: IamRole) => (\n <Space>\n <Button type=\"link\" size=\"small\" onClick={() => navigate(resolvePermPath(r.id))}>\n 权限管理\n </Button>\n <Button\n type=\"link\"\n size=\"small\"\n onClick={() => {\n setEditing(r);\n form.setFieldsValue({\n name: r.name,\n description:\n displayRoleDescription(r.description) === '—' ? '' : r.description || '',\n });\n setOpen(true);\n }}\n >\n 编辑\n </Button>\n <Button\n type=\"link\"\n size=\"small\"\n danger\n disabled={Boolean(r.isBuiltin)}\n onClick={async () => {\n try {\n await client.deleteRole(r.id);\n message.success('已删除');\n void load();\n } catch (e) {\n message.error(e instanceof Error ? e.message : '删除失败');\n }\n }}\n >\n 删除\n </Button>\n </Space>\n ),\n },\n ]}\n />\n <Modal\n open={open}\n title={editing ? '编辑角色' : '新增角色'}\n onCancel={() => setOpen(false)}\n onOk={async () => {\n const values = await form.validateFields();\n try {\n if (editing) {\n await client.updateRole(editing.id, values);\n } else {\n await client.createRole(values);\n }\n message.success('已保存');\n setOpen(false);\n void load();\n } catch (e) {\n message.error(e instanceof Error ? e.message : '失败');\n }\n }}\n >\n <Form form={form} layout=\"vertical\">\n <Form.Item name=\"name\" label=\"角色名称\" rules={[{ required: true }]}>\n <Input placeholder=\"请输入角色名称\" />\n </Form.Item>\n <Form.Item name=\"description\" label=\"角色描述\">\n <Input.TextArea placeholder=\"请输入角色描述\" rows={3} />\n </Form.Item>\n </Form>\n </Modal>\n </ModulePageShell>\n );\n}\n\nexport type IamRolePermissionsPageProps = {\n client: IamClient;\n catalog: PermissionBindCatalog;\n systemEntryCodes: readonly string[];\n systemAppCode: string;\n rolesListPath?: string;\n onAfterSave?: () => void | Promise<void>;\n emptyCatalogHint?: string;\n title?: string;\n};\n\nexport function IamRolePermissionsPage({\n client,\n catalog,\n systemEntryCodes,\n systemAppCode,\n rolesListPath = '/config/iam/roles',\n onAfterSave,\n emptyCatalogHint = '暂无权限点;请先在 SSO 导入本应用目录。',\n title = '权限管理',\n}: IamRolePermissionsPageProps) {\n const { id } = useParams();\n const navigate = useNavigate();\n const [role, setRole] = useState<IamRole | null>(null);\n const [perms, setPerms] = useState<IamPermission[]>([]);\n const [checked, setChecked] = useState<string[]>([]);\n const checkedRef = useRef(checked);\n checkedRef.current = checked;\n const [loading, setLoading] = useState(false);\n const [saving, setSaving] = useState(false);\n\n useEffect(() => {\n if (!id) return;\n setLoading(true);\n void Promise.all([client.listRoles(), client.listPermissions()])\n .then(([roles, allPerms]) => {\n const r = roles.find((x) => x.id === id) || null;\n setRole(r);\n const appPerms = allPerms.filter(\n (p) => p.layer !== 'RESOURCE' && (!p.systemAppId || p.systemApp?.code === systemAppCode),\n );\n setPerms(appPerms);\n setChecked(\n (r?.rolePermissions || [])\n .map((x) => x.permissionId || x.permission?.id || '')\n .filter(Boolean),\n );\n })\n .catch((e) => message.error(e instanceof Error ? e.message : '加载失败'))\n .finally(() => setLoading(false));\n }, [id, client, systemAppCode]);\n\n const panelPermissions = useMemo(\n () =>\n perms.map((p) => ({\n id: p.id,\n code: p.code,\n name: p.name,\n layer: p.layer,\n })),\n [perms],\n );\n\n const onCheckedChange = useCallback((next: string[]) => {\n setChecked(next);\n }, []);\n\n const headerActions = useMemo(\n () => [\n {\n children: '返回',\n onClick: () => navigate(rolesListPath),\n },\n {\n children: '保存',\n type: 'primary' as const,\n loading: saving,\n onClick: async () => {\n if (!id) return;\n setSaving(true);\n try {\n await client.setRolePermissions(id, checkedRef.current.filter(Boolean));\n message.success('已保存');\n try {\n await onAfterSave?.();\n } catch {\n /* ignore EP refresh */\n }\n } catch (e) {\n message.error(e instanceof Error ? e.message : '保存失败');\n } finally {\n setSaving(false);\n }\n },\n },\n ],\n [id, navigate, saving, client, rolesListPath, onAfterSave],\n );\n\n return (\n <ModulePageShell title={title} actions={headerActions} spinning={loading} fillHeight={false}>\n <Typography.Paragraph style={{ marginTop: 0 }}>\n 角色名称:{role?.name || '—'}\n </Typography.Paragraph>\n <Typography.Paragraph type=\"secondary\">\n 按页面模块 → 分类 → 功能点勾选(中文目录来自 bindCatalog)。须先勾选「进入应用」SYSTEM\n 入口。RESOURCE 不在此绑定。\n </Typography.Paragraph>\n {perms.length === 0 && !loading ? (\n <Empty description={emptyCatalogHint} />\n ) : (\n <PermissionBindPanel\n catalog={catalog}\n permissions={panelPermissions}\n value={checked}\n onChange={onCheckedChange}\n systemEntryCodes={[...systemEntryCodes]}\n />\n )}\n </ModulePageShell>\n );\n}\n"],"names":["displayRoleDescription","v","t","IamRolesPage","client","rolesListPath","rolePermissionsPath","title","navigate","useNavigate","resolvePermPath","id","loading","setLoading","useState","rows","setRows","open","setOpen","editing","setEditing","form","Form","load","useCallback","e","message","useEffect","headerActions","useMemo","ModulePageShell","jsx","Table","_","r","_a","Space","Button","Modal","values","jsxs","Input","IamRolePermissionsPage","catalog","systemEntryCodes","systemAppCode","onAfterSave","emptyCatalogHint","useParams","role","setRole","perms","setPerms","checked","setChecked","checkedRef","useRef","saving","setSaving","roles","allPerms","x","appPerms","p","panelPermissions","onCheckedChange","next","Typography","Empty","PermissionBindPanel"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { IamClient } from '../client';
2
+ export type IamSharedGroupsPageProps = {
3
+ client: IamClient;
4
+ title?: string;
5
+ };
6
+ export default function IamSharedGroupsPage({ client, title, }: IamSharedGroupsPageProps): import("react").JSX.Element;
@@ -0,0 +1,207 @@
1
+ import { jsxs as g, jsx as r, Fragment as j } from "react/jsx-runtime";
2
+ import { Form as c, message as o, Table as P, Space as q, Button as y, Modal as S, Input as b, Select as w } from "antd";
3
+ import { useState as l, useCallback as B, useEffect as T, useMemo as U } from "react";
4
+ import D from "../../Layout/ModulePageShell/index.js";
5
+ function V({
6
+ client: t,
7
+ title: C = "共享组"
8
+ }) {
9
+ const [G, I] = l(!1), [x, E] = l([]), [M, F] = l([]), [O, _] = l([]), [$, h] = l(!1), [m, k] = l(null), [z, f] = l(!1), [n, A] = l(null), [u, v] = l([]), [p] = c.useForm(), d = B(async () => {
10
+ I(!0);
11
+ try {
12
+ const [e, s, a] = await Promise.all([
13
+ t.listSharedGroups(),
14
+ t.listRoles(),
15
+ t.listUsers({ page: 1, pageSize: 100 })
16
+ ]);
17
+ E(e), F(s), _(a.pageData.filter((i) => i.isActive));
18
+ } catch (e) {
19
+ o.error(e instanceof Error ? e.message : "加载失败");
20
+ } finally {
21
+ I(!1);
22
+ }
23
+ }, [t]);
24
+ T(() => {
25
+ d();
26
+ }, [d]);
27
+ const R = U(
28
+ () => [
29
+ {
30
+ children: "新增共享组",
31
+ type: "primary",
32
+ onClick: () => {
33
+ k(null), p.resetFields(), h(!0);
34
+ }
35
+ }
36
+ ],
37
+ [p]
38
+ );
39
+ return /* @__PURE__ */ g(D, { title: C, actions: R, fillHeight: !1, children: [
40
+ /* @__PURE__ */ r(
41
+ P,
42
+ {
43
+ rowKey: "id",
44
+ loading: G,
45
+ dataSource: x,
46
+ columns: [
47
+ { title: "名称", dataIndex: "name" },
48
+ { title: "编码", dataIndex: "code" },
49
+ { title: "说明", dataIndex: "description", render: (e) => e || "—" },
50
+ {
51
+ title: "角色",
52
+ key: "roles",
53
+ render: (e, s) => (s.groupRoles || []).map((a) => {
54
+ var i;
55
+ return (i = a.role) == null ? void 0 : i.code;
56
+ }).filter(Boolean).join(", ") || "—"
57
+ },
58
+ {
59
+ title: "成员数",
60
+ key: "mc",
61
+ render: (e, s) => {
62
+ var a;
63
+ return ((a = s._count) == null ? void 0 : a.userGroups) ?? "—";
64
+ }
65
+ },
66
+ {
67
+ title: "操作",
68
+ key: "ops",
69
+ render: (e, s) => /* @__PURE__ */ g(q, { children: [
70
+ /* @__PURE__ */ r(
71
+ y,
72
+ {
73
+ type: "link",
74
+ size: "small",
75
+ onClick: () => {
76
+ k(s), p.setFieldsValue({
77
+ name: s.name,
78
+ description: s.description || ""
79
+ }), h(!0);
80
+ },
81
+ children: "编辑"
82
+ }
83
+ ),
84
+ /* @__PURE__ */ r(
85
+ y,
86
+ {
87
+ type: "link",
88
+ size: "small",
89
+ onClick: () => {
90
+ A(s), v([]), f(!0);
91
+ },
92
+ children: "成员"
93
+ }
94
+ ),
95
+ /* @__PURE__ */ r(
96
+ y,
97
+ {
98
+ type: "link",
99
+ size: "small",
100
+ danger: !0,
101
+ onClick: async () => {
102
+ try {
103
+ await t.deleteSharedGroup(s.id), o.success("已删除"), d();
104
+ } catch (a) {
105
+ o.error(a instanceof Error ? a.message : "删除失败(请先移除成员)");
106
+ }
107
+ },
108
+ children: "删除"
109
+ }
110
+ )
111
+ ] })
112
+ }
113
+ ]
114
+ }
115
+ ),
116
+ /* @__PURE__ */ r(
117
+ S,
118
+ {
119
+ open: $,
120
+ title: m ? "编辑共享组" : "新增共享组",
121
+ onCancel: () => h(!1),
122
+ onOk: async () => {
123
+ const e = await p.validateFields();
124
+ try {
125
+ m ? await t.updateSharedGroup(m.id, {
126
+ name: e.name,
127
+ description: e.description
128
+ }) : await t.createSharedGroup({
129
+ code: e.code,
130
+ name: e.name,
131
+ description: e.description,
132
+ roleIds: e.roleIds
133
+ }), o.success("已保存"), h(!1), d();
134
+ } catch (s) {
135
+ o.error(s instanceof Error ? s.message : "失败");
136
+ }
137
+ },
138
+ children: /* @__PURE__ */ g(c, { form: p, layout: "vertical", children: [
139
+ m ? null : /* @__PURE__ */ r(c.Item, { name: "code", label: "编码", rules: [{ required: !0 }], children: /* @__PURE__ */ r(b, {}) }),
140
+ /* @__PURE__ */ r(c.Item, { name: "name", label: "名称", rules: [{ required: !0 }], children: /* @__PURE__ */ r(b, {}) }),
141
+ /* @__PURE__ */ r(c.Item, { name: "description", label: "说明", children: /* @__PURE__ */ r(b.TextArea, { rows: 2 }) }),
142
+ m ? null : /* @__PURE__ */ r(c.Item, { name: "roleIds", label: "聚合角色", children: /* @__PURE__ */ r(
143
+ w,
144
+ {
145
+ mode: "multiple",
146
+ options: M.map((e) => ({ value: e.id, label: `${e.code} · ${e.name}` }))
147
+ }
148
+ ) })
149
+ ] })
150
+ }
151
+ ),
152
+ /* @__PURE__ */ r(
153
+ S,
154
+ {
155
+ open: z,
156
+ title: `成员 · ${(n == null ? void 0 : n.name) || ""}`,
157
+ onCancel: () => f(!1),
158
+ onOk: async () => {
159
+ if (!(!n || !u.length))
160
+ try {
161
+ await t.addSharedGroupMembers(n.id, u), o.success("已添加成员"), f(!1), d();
162
+ } catch (e) {
163
+ o.error(e instanceof Error ? e.message : "失败");
164
+ }
165
+ },
166
+ footer: (e, { OkBtn: s, CancelBtn: a }) => /* @__PURE__ */ g(j, { children: [
167
+ /* @__PURE__ */ r(
168
+ y,
169
+ {
170
+ danger: !0,
171
+ disabled: !u.length || !n,
172
+ onClick: async () => {
173
+ if (n)
174
+ try {
175
+ await t.removeSharedGroupMembers(n.id, u), o.success("已移除成员"), f(!1), d();
176
+ } catch (i) {
177
+ o.error(i instanceof Error ? i.message : "失败");
178
+ }
179
+ },
180
+ children: "移除所选"
181
+ }
182
+ ),
183
+ /* @__PURE__ */ r(a, {}),
184
+ /* @__PURE__ */ r(s, {})
185
+ ] }),
186
+ children: /* @__PURE__ */ r(
187
+ w,
188
+ {
189
+ mode: "multiple",
190
+ style: { width: "100%" },
191
+ value: u,
192
+ onChange: v,
193
+ options: O.map((e) => ({
194
+ value: e.id,
195
+ label: `${e.displayName} · ${e.employeeId}`
196
+ })),
197
+ placeholder: "选择用户后可添加或移除"
198
+ }
199
+ )
200
+ }
201
+ )
202
+ ] });
203
+ }
204
+ export {
205
+ V as default
206
+ };
207
+ //# sourceMappingURL=IamSharedGroupsPage.js.map