@gadmin2n/schematics 0.0.149 → 0.0.151
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/dist/lib/application/files/gadmin2-game-angle-demo/CODEBUDDY.md +125 -36
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +42 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/gitignore +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.seed-timestamp +0 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +3 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/check-dev-env.js +218 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/page-manage.ts +78 -12
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +37 -67
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/config/index.ts +0 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.controller.ts +46 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.controller.ts +60 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/external-callback.controller.ts +3 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/externalInteraction/workflow-callback-url.controller.ts +9 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.controller.ts +55 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.module.ts +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/page-transfer.service.ts +491 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/perm-transfer.dto.ts +213 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/perm-transfer.module.ts +28 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/resource-transfer.service.ts +137 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/role-transfer.service.ts +248 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/transfer-token.service.ts +65 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/permTransfer/user-transfer.service.ts +146 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.ts +55 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.module.ts +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.controller.ts +55 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.module.ts +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/subjectProvider/providers/user-group.provider.spec.ts +46 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/subjectProvider/providers/user-group.provider.ts +3 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.ts +55 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.module.ts +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-cancellation.spec.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.spec.ts +96 -14
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-compiler.service.ts +41 -41
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-database-function.spec.ts +36 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-database-function.ts +90 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-event-catalog.spec.ts +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-event-trigger.pg.spec.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution-idempotency.spec.ts +115 -63
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-outbox.service.spec.ts +166 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-outbox.service.ts +217 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.spec.ts +33 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle-runtime.controller.ts +57 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle.service.spec.ts +196 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-lifecycle.service.ts +125 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.controller.ts +9 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +148 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +12 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +14 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +75 -45
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowConfig/node-config-validator.service.spec.ts +25 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/TransferExportModal.tsx +115 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/TransferImportModal.tsx +257 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +0 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +40 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/workflow.json +15 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +40 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/workflow.json +15 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +89 -65
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +51 -127
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/permissionReadme/index.tsx +53 -109
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +45 -41
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +51 -72
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/list.tsx +49 -40
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.test.tsx +16 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ReadonlyNodePanel.test.tsx +28 -10
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.test.tsx +60 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +94 -12
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/node-instance-show.css +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/schema-form/default-widgets.tsx +3 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +8 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/DbExecuteConfigEditor.tsx +167 -94
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerConfigEditor.tsx +95 -95
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerLifecycleConfigEditor.test.tsx +81 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/EventTriggerLifecycleConfigEditor.tsx +126 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/widgets/SimplifiedNodeEditors.test.tsx +48 -52
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/forEachConnection.ts +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/utils/newNodeConfig.ts +1 -3
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/config/ac.config.ts +0 -24
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/SqlModal.tsx +0 -495
package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/permissionReadme/index.tsx
CHANGED
|
@@ -173,6 +173,14 @@ const faqItems = [
|
|
|
173
173
|
label: 'iframe 页面加载失败?',
|
|
174
174
|
children: (
|
|
175
175
|
<ol>
|
|
176
|
+
<li>
|
|
177
|
+
<Text strong>先确认本项目是否已实现 iframe 能力</Text>:若{' '}
|
|
178
|
+
<Text code>App.tsx</Text> 的兜底路由仍是{' '}
|
|
179
|
+
<Text code>ErrorComponent</Text>(未接入{' '}
|
|
180
|
+
<Text code>WildcardPage</Text>),则 <Text code>iframeUrl</Text>{' '}
|
|
181
|
+
不会生效,点菜单必然 404 —— 这与目标网站的设置无关。详见「iframe
|
|
182
|
+
嵌入」标签页顶部的说明。
|
|
183
|
+
</li>
|
|
176
184
|
<li>
|
|
177
185
|
检查目标网站是否允许被 iframe 嵌入(X-Frame-Options /
|
|
178
186
|
Content-Security-Policy 头)
|
|
@@ -269,17 +277,22 @@ const comparisonColumns = [
|
|
|
269
277
|
{ title: '原生页面', dataIndex: 'native', key: 'native' },
|
|
270
278
|
{ title: '外部链接', dataIndex: 'external', key: 'external' },
|
|
271
279
|
{ title: 'iframe 嵌入', dataIndex: 'iframe', key: 'iframe' },
|
|
272
|
-
{ title: '动态菜单', dataIndex: 'dynamic', key: 'dynamic' },
|
|
273
280
|
];
|
|
274
281
|
|
|
275
282
|
const comparisonData = [
|
|
283
|
+
{
|
|
284
|
+
key: 'support',
|
|
285
|
+
item: '本项目是否可用',
|
|
286
|
+
native: '是',
|
|
287
|
+
external: '否(未实现 WildcardPage)',
|
|
288
|
+
iframe: '否(未实现 WildcardPage)',
|
|
289
|
+
},
|
|
276
290
|
{
|
|
277
291
|
key: 'scene',
|
|
278
292
|
item: '适用场景',
|
|
279
293
|
native: '内部开发的完整功能页面',
|
|
280
294
|
external: '跳转到外部系统(Wiki、文档等)',
|
|
281
295
|
iframe: '在应用内嵌入外部页面(报表等)',
|
|
282
|
-
dynamic: '同一组件多实例(如工作室列表)',
|
|
283
296
|
},
|
|
284
297
|
{
|
|
285
298
|
key: 'registry',
|
|
@@ -287,7 +300,6 @@ const comparisonData = [
|
|
|
287
300
|
native: '是(config/routeRegistry.tsx)',
|
|
288
301
|
external: '否',
|
|
289
302
|
iframe: '否',
|
|
290
|
-
dynamic: '是(config/dynamicMenus.ts 配置)',
|
|
291
303
|
},
|
|
292
304
|
{
|
|
293
305
|
key: 'component',
|
|
@@ -295,7 +307,6 @@ const comparisonData = [
|
|
|
295
307
|
native: '是',
|
|
296
308
|
external: '否',
|
|
297
309
|
iframe: '否',
|
|
298
|
-
dynamic: '是(共享组件)',
|
|
299
310
|
},
|
|
300
311
|
{
|
|
301
312
|
key: 'tpage',
|
|
@@ -303,7 +314,6 @@ const comparisonData = [
|
|
|
303
314
|
native: '是(code = routeRegistry key)',
|
|
304
315
|
external: '是(填 externalRedirectUrl)',
|
|
305
316
|
iframe: '是(填 iframeUrl)',
|
|
306
|
-
dynamic: '是(父级目录)',
|
|
307
317
|
},
|
|
308
318
|
{
|
|
309
319
|
key: 'url',
|
|
@@ -311,7 +321,6 @@ const comparisonData = [
|
|
|
311
321
|
native: 'code, path, parentId',
|
|
312
322
|
external: 'externalRedirectUrl',
|
|
313
323
|
iframe: 'iframeUrl',
|
|
314
|
-
dynamic: 'code(如 invested / native)',
|
|
315
324
|
},
|
|
316
325
|
{
|
|
317
326
|
key: 'behavior',
|
|
@@ -319,7 +328,6 @@ const comparisonData = [
|
|
|
319
328
|
native: '应用内完整渲染',
|
|
320
329
|
external: '新窗口打开 + 自动返回',
|
|
321
330
|
iframe: '应用框架内嵌入',
|
|
322
|
-
dynamic: '应用内完整渲染',
|
|
323
331
|
},
|
|
324
332
|
{
|
|
325
333
|
key: 'template',
|
|
@@ -327,7 +335,6 @@ const comparisonData = [
|
|
|
327
335
|
native: '—',
|
|
328
336
|
external: '是',
|
|
329
337
|
iframe: '是',
|
|
330
|
-
dynamic: '—',
|
|
331
338
|
},
|
|
332
339
|
];
|
|
333
340
|
|
|
@@ -654,6 +661,26 @@ staff: {
|
|
|
654
661
|
label: '外部链接',
|
|
655
662
|
children: (
|
|
656
663
|
<>
|
|
664
|
+
<Alert
|
|
665
|
+
type="warning"
|
|
666
|
+
showIcon
|
|
667
|
+
message="本项目暂不支持外部链接菜单"
|
|
668
|
+
description={
|
|
669
|
+
<>
|
|
670
|
+
<Text code>externalRedirectUrl</Text>{' '}
|
|
671
|
+
字段在数据库和本页表单里都存在,但本项目未实现渲染它的{' '}
|
|
672
|
+
<Text code>WildcardPage</Text> 通配组件(
|
|
673
|
+
<Text code>App.tsx</Text> 的兜底路由目前直接返回
|
|
674
|
+
404)。填了该字段能保存成功,
|
|
675
|
+
<Text strong>但点击菜单会 404</Text>。
|
|
676
|
+
<br />
|
|
677
|
+
以下内容描述的是上游 ERP
|
|
678
|
+
项目的机制,供将来移植参考。当前若需要外部系统入口,
|
|
679
|
+
请做一个极薄的自定义页面(页面内放跳转按钮)。
|
|
680
|
+
</>
|
|
681
|
+
}
|
|
682
|
+
style={{ marginBottom: 16 }}
|
|
683
|
+
/>
|
|
657
684
|
<Paragraph>
|
|
658
685
|
外部链接方式<Text strong>无需编写任何前端代码</Text>
|
|
659
686
|
,只需在 Page Management 中创建一条 t_page 记录,并填写{' '}
|
|
@@ -718,6 +745,24 @@ staff: {
|
|
|
718
745
|
label: 'iframe 嵌入',
|
|
719
746
|
children: (
|
|
720
747
|
<>
|
|
748
|
+
<Alert
|
|
749
|
+
type="warning"
|
|
750
|
+
showIcon
|
|
751
|
+
message="本项目暂不支持 iframe 菜单"
|
|
752
|
+
description={
|
|
753
|
+
<>
|
|
754
|
+
<Text code>iframeUrl</Text>{' '}
|
|
755
|
+
字段在数据库和本页表单里都存在,但本项目未实现渲染它的{' '}
|
|
756
|
+
<Text code>WildcardPage</Text> 通配组件(
|
|
757
|
+
<Text code>App.tsx</Text> 的兜底路由目前直接返回
|
|
758
|
+
404)。填了该字段能保存成功,
|
|
759
|
+
<Text strong>但点击菜单会 404</Text>。
|
|
760
|
+
<br />
|
|
761
|
+
以下内容描述的是上游 ERP 项目的机制,供将来移植参考。
|
|
762
|
+
</>
|
|
763
|
+
}
|
|
764
|
+
style={{ marginBottom: 16 }}
|
|
765
|
+
/>
|
|
721
766
|
<Paragraph>
|
|
722
767
|
iframe 方式同样<Text strong>无需编写前端代码</Text>
|
|
723
768
|
,在 Page Management 中填写 <Text code>iframeUrl</Text>{' '}
|
|
@@ -771,107 +816,6 @@ staff: {
|
|
|
771
816
|
</>
|
|
772
817
|
),
|
|
773
818
|
},
|
|
774
|
-
{
|
|
775
|
-
key: 'dynamic',
|
|
776
|
-
label: '动态菜单',
|
|
777
|
-
children: (
|
|
778
|
-
<>
|
|
779
|
-
<Paragraph>
|
|
780
|
-
动态菜单适用于
|
|
781
|
-
<Text strong>同一个页面组件需要生成多个菜单项</Text>
|
|
782
|
-
的场景。通过 <Text code>
|
|
783
|
-
src/config/dynamicMenus.ts
|
|
784
|
-
</Text>{' '}
|
|
785
|
-
的配置驱动方案,开发者只需添加一条配置即可新增动态菜单组。
|
|
786
|
-
</Paragraph>
|
|
787
|
-
|
|
788
|
-
<Title level={5}>配置方式</Title>
|
|
789
|
-
<Paragraph>
|
|
790
|
-
在 <Text code>src/config/dynamicMenus.ts</Text> 中的{' '}
|
|
791
|
-
<Text code>dynamicMenuGroups</Text> 数组中添加一条配置:
|
|
792
|
-
</Paragraph>
|
|
793
|
-
<pre
|
|
794
|
-
style={{
|
|
795
|
-
background: 'var(--ant-color-fill-quaternary)',
|
|
796
|
-
padding: 16,
|
|
797
|
-
borderRadius: 6,
|
|
798
|
-
overflow: 'auto',
|
|
799
|
-
fontSize: 13,
|
|
800
|
-
lineHeight: 1.6,
|
|
801
|
-
}}
|
|
802
|
-
>{`// src/config/dynamicMenus.ts
|
|
803
|
-
interface DynamicMenuGroup {
|
|
804
|
-
parentCode: string; // 父级 page code(需在 t_page 注册)
|
|
805
|
-
routePrefix: string; // 路由前缀,如 "/rd/invested"
|
|
806
|
-
items: string[]; // 子项列表,每项生成一个菜单项和路由
|
|
807
|
-
component: LazyExoticComponent<ComponentType<any>>; // 共享组件
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
// 示例:RD 工作室
|
|
811
|
-
{
|
|
812
|
-
parentCode: "invested",
|
|
813
|
-
routePrefix: "/rd/invested",
|
|
814
|
-
items: studioMap.investedStudios,
|
|
815
|
-
component: lazy(() => import("@/routes/rd/rdec")),
|
|
816
|
-
}`}</pre>
|
|
817
|
-
|
|
818
|
-
<Alert
|
|
819
|
-
type="info"
|
|
820
|
-
showIcon
|
|
821
|
-
message="权限控制"
|
|
822
|
-
description={
|
|
823
|
-
<>
|
|
824
|
-
动态菜单的权限以 <Text code>parentCode</Text>{' '}
|
|
825
|
-
为单位控制。例如为角色分配 <Text code>invested</Text>{' '}
|
|
826
|
-
页面后,该角色可以看到该组下所有子菜单项。无需为每个子项单独配置权限。
|
|
827
|
-
</>
|
|
828
|
-
}
|
|
829
|
-
style={{ marginTop: 16 }}
|
|
830
|
-
/>
|
|
831
|
-
|
|
832
|
-
<Divider />
|
|
833
|
-
<Title level={5}>添加新动态菜单组的步骤</Title>
|
|
834
|
-
<ol>
|
|
835
|
-
<li>
|
|
836
|
-
在 <Text code>t_page</Text> 中注册父级页面(设置{' '}
|
|
837
|
-
<Text code>code</Text>、<Text code>parentId</Text>)
|
|
838
|
-
</li>
|
|
839
|
-
<li>
|
|
840
|
-
在 <Text code>src/config/dynamicMenus.ts</Text> 的{' '}
|
|
841
|
-
<Text code>dynamicMenuGroups</Text> 数组中添加一条配置
|
|
842
|
-
</li>
|
|
843
|
-
<li>
|
|
844
|
-
路由和菜单项会自动生成,无需修改{' '}
|
|
845
|
-
<Text code>routeRegistry.tsx</Text>、
|
|
846
|
-
<Text code>App.tsx</Text> 或{' '}
|
|
847
|
-
<Text code>useDynamicResources.tsx</Text>
|
|
848
|
-
</li>
|
|
849
|
-
</ol>
|
|
850
|
-
|
|
851
|
-
<Divider />
|
|
852
|
-
<Title level={5}>现有示例:RD 工作室</Title>
|
|
853
|
-
<Paragraph>
|
|
854
|
-
当前系统中 RD 模块的 invested(投资工作室)和
|
|
855
|
-
native(自研工作室)使用动态菜单:
|
|
856
|
-
</Paragraph>
|
|
857
|
-
<ul>
|
|
858
|
-
<li>
|
|
859
|
-
工作室列表定义在 <Text code>src/config/studio.ts</Text> 的{' '}
|
|
860
|
-
<Text code>studioMap</Text> 中
|
|
861
|
-
</li>
|
|
862
|
-
<li>
|
|
863
|
-
所有工作室路由共享同一个 <Text code>RDEC</Text>{' '}
|
|
864
|
-
组件,组件内从 URL 提取工作室名称
|
|
865
|
-
</li>
|
|
866
|
-
<li>
|
|
867
|
-
添加新工作室只需在 <Text code>studio.ts</Text> 的{' '}
|
|
868
|
-
<Text code>StudioEnum</Text> 和{' '}
|
|
869
|
-
<Text code>studioMap</Text> 中添加条目即可
|
|
870
|
-
</li>
|
|
871
|
-
</ul>
|
|
872
|
-
</>
|
|
873
|
-
),
|
|
874
|
-
},
|
|
875
819
|
]}
|
|
876
820
|
/>
|
|
877
821
|
</Card>
|
|
@@ -5,18 +5,16 @@ import {
|
|
|
5
5
|
EditOutlined,
|
|
6
6
|
EyeOutlined,
|
|
7
7
|
SearchOutlined,
|
|
8
|
-
|
|
8
|
+
ExportOutlined,
|
|
9
|
+
ImportOutlined,
|
|
9
10
|
} from '@ant-design/icons';
|
|
10
|
-
import {
|
|
11
|
-
getDefaultFilter,
|
|
12
|
-
type HttpError,
|
|
13
|
-
useGetIdentity,
|
|
14
|
-
} from '@refinedev/core';
|
|
11
|
+
import { getDefaultFilter, type HttpError } from '@refinedev/core';
|
|
15
12
|
import type { Resource } from './types';
|
|
16
13
|
import { EditModal } from './components/EditModal';
|
|
17
14
|
import { CreateModal } from './components/CreateModal';
|
|
18
15
|
import { ResourceDetailDrawer } from './components/ResourceDetailDrawer';
|
|
19
|
-
import {
|
|
16
|
+
import { TransferExportModal } from 'components/TransferExportModal';
|
|
17
|
+
import { TransferImportModal } from 'components/TransferImportModal';
|
|
20
18
|
import { PageHeader } from 'components';
|
|
21
19
|
import { PAGE_WRAPPER_STYLE } from 'constants/layout';
|
|
22
20
|
|
|
@@ -32,7 +30,6 @@ export const PROTECTED_RESOURCES = [
|
|
|
32
30
|
];
|
|
33
31
|
|
|
34
32
|
export const ResourceManagementListPage: React.FC = () => {
|
|
35
|
-
const { data: identity } = useGetIdentity<any>();
|
|
36
33
|
const {
|
|
37
34
|
tableProps,
|
|
38
35
|
filters,
|
|
@@ -72,20 +69,8 @@ export const ResourceManagementListPage: React.FC = () => {
|
|
|
72
69
|
|
|
73
70
|
const [drawerResource, setDrawerResource] = useState<Resource | null>(null);
|
|
74
71
|
|
|
75
|
-
const [
|
|
76
|
-
|
|
77
|
-
title: string;
|
|
78
|
-
sql: string;
|
|
79
|
-
}>({ open: false, title: '', sql: '' });
|
|
80
|
-
|
|
81
|
-
const handleShowSql = (record: Resource) => {
|
|
82
|
-
const operator = {
|
|
83
|
-
authorId: identity?.userid,
|
|
84
|
-
authorName: identity?.username,
|
|
85
|
-
};
|
|
86
|
-
const sql = generateResourceSql(record, operator);
|
|
87
|
-
setSqlModal({ open: true, title: `SQL — Resource: ${record.code}`, sql });
|
|
88
|
-
};
|
|
72
|
+
const [exportEndpoint, setExportEndpoint] = useState<string | null>(null);
|
|
73
|
+
const [importOpen, setImportOpen] = useState(false);
|
|
89
74
|
|
|
90
75
|
// fix for ant design filter dropdown contains operator
|
|
91
76
|
filters.map((filter) => {
|
|
@@ -122,17 +107,25 @@ export const ResourceManagementListPage: React.FC = () => {
|
|
|
122
107
|
<PageHeader
|
|
123
108
|
title="Resource mgnts"
|
|
124
109
|
extra={
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
110
|
+
<Space>
|
|
111
|
+
<Button
|
|
112
|
+
icon={<ImportOutlined />}
|
|
113
|
+
onClick={() => setImportOpen(true)}
|
|
114
|
+
>
|
|
115
|
+
Import
|
|
116
|
+
</Button>
|
|
117
|
+
<Button
|
|
118
|
+
type="primary"
|
|
119
|
+
onClick={() =>
|
|
120
|
+
setShowModal({
|
|
121
|
+
type: 'create',
|
|
122
|
+
id: null,
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
>
|
|
126
|
+
Create Resource
|
|
127
|
+
</Button>
|
|
128
|
+
</Space>
|
|
136
129
|
}
|
|
137
130
|
/>
|
|
138
131
|
<Card className="card-table">
|
|
@@ -212,12 +205,16 @@ export const ResourceManagementListPage: React.FC = () => {
|
|
|
212
205
|
}
|
|
213
206
|
/>
|
|
214
207
|
</Tooltip>
|
|
215
|
-
<Tooltip title="
|
|
208
|
+
<Tooltip title="Export">
|
|
216
209
|
<Button
|
|
217
210
|
type="default"
|
|
218
211
|
size="small"
|
|
219
|
-
icon={<
|
|
220
|
-
onClick={() =>
|
|
212
|
+
icon={<ExportOutlined />}
|
|
213
|
+
onClick={() =>
|
|
214
|
+
setExportEndpoint(
|
|
215
|
+
`resource/${encodeURIComponent(record.code)}/export-token`,
|
|
216
|
+
)
|
|
217
|
+
}
|
|
221
218
|
/>
|
|
222
219
|
</Tooltip>
|
|
223
220
|
</Space>
|
|
@@ -246,11 +243,18 @@ export const ResourceManagementListPage: React.FC = () => {
|
|
|
246
243
|
onClose={() => setDrawerResource(null)}
|
|
247
244
|
/>
|
|
248
245
|
)}
|
|
249
|
-
<
|
|
250
|
-
open={
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
246
|
+
<TransferExportModal
|
|
247
|
+
open={!!exportEndpoint}
|
|
248
|
+
exportTokenEndpoint={exportEndpoint}
|
|
249
|
+
entity="resource"
|
|
250
|
+
onClose={() => setExportEndpoint(null)}
|
|
251
|
+
/>
|
|
252
|
+
<TransferImportModal
|
|
253
|
+
open={importOpen}
|
|
254
|
+
onClose={() => setImportOpen(false)}
|
|
255
|
+
onSuccess={() => tableQueryResult?.refetch()}
|
|
256
|
+
previewEndpoint="resource/import-preview"
|
|
257
|
+
confirmEndpoint="resource/import-confirm"
|
|
254
258
|
/>
|
|
255
259
|
</div>
|
|
256
260
|
);
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import React, { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import { useTable } from '@refinedev/antd';
|
|
3
|
-
import { useGetLocale
|
|
4
|
-
import { Table, Button, Card, Space, Tooltip
|
|
3
|
+
import { useGetLocale } from '@refinedev/core';
|
|
4
|
+
import { Table, Button, Card, Space, Tooltip } from 'antd';
|
|
5
5
|
|
|
6
6
|
import { EditModal } from './components/EditModal';
|
|
7
7
|
import { CreateModal } from './components/CreateModal';
|
|
8
8
|
import type { RolePageTreeNode } from './types';
|
|
9
9
|
import { useRolePage } from './hooks/useRolePage';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
EditOutlined,
|
|
12
|
+
EyeOutlined,
|
|
13
|
+
ExportOutlined,
|
|
14
|
+
ImportOutlined,
|
|
15
|
+
} from '@ant-design/icons';
|
|
11
16
|
import { RoleDetailDrawer } from './components/RoleDetailDrawer';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
17
|
+
import { TransferExportModal } from '@/components/TransferExportModal';
|
|
18
|
+
import { TransferImportModal } from '@/components/TransferImportModal';
|
|
14
19
|
import { buildPageTree } from '@/helpers/page-tree';
|
|
15
20
|
import { PageHeader } from 'components';
|
|
16
21
|
import { PAGE_WRAPPER_STYLE } from 'constants/layout';
|
|
@@ -85,9 +90,8 @@ const extractActionsFromRelation = (
|
|
|
85
90
|
export const RoleManagementListPage: React.FC = () => {
|
|
86
91
|
const getLocale = useGetLocale();
|
|
87
92
|
const currentLocale = getLocale();
|
|
88
|
-
const { data: identity } = useGetIdentity<any>();
|
|
89
93
|
|
|
90
|
-
const { tableProps } = useTable({
|
|
94
|
+
const { tableProps, tableQuery: tableQueryResult } = useTable({
|
|
91
95
|
resource: 'role',
|
|
92
96
|
pagination: {
|
|
93
97
|
pageSize: 20,
|
|
@@ -258,52 +262,8 @@ export const RoleManagementListPage: React.FC = () => {
|
|
|
258
262
|
id: null,
|
|
259
263
|
});
|
|
260
264
|
|
|
261
|
-
const [
|
|
262
|
-
|
|
263
|
-
title: string;
|
|
264
|
-
sql: string;
|
|
265
|
-
}>({ open: false, title: '', sql: '' });
|
|
266
|
-
|
|
267
|
-
const handleShowSql = useCallback(
|
|
268
|
-
async (record: any) => {
|
|
269
|
-
const summary = rolePermissionSummary[record.id];
|
|
270
|
-
const rolePages =
|
|
271
|
-
summary?.pageInfos?.map((p) => ({
|
|
272
|
-
pageId: p.id,
|
|
273
|
-
pageCode: p.code,
|
|
274
|
-
pageName: p.name,
|
|
275
|
-
})) ?? [];
|
|
276
|
-
|
|
277
|
-
let roleResources: Array<{
|
|
278
|
-
resourceCode: string;
|
|
279
|
-
resourceName: string;
|
|
280
|
-
actions: string[];
|
|
281
|
-
}> = [];
|
|
282
|
-
try {
|
|
283
|
-
const resp: any = await customRequest('roleResource/findMany', 'post', {
|
|
284
|
-
where: { roleId: record.id },
|
|
285
|
-
include: { resource: true },
|
|
286
|
-
});
|
|
287
|
-
const items: any[] = Array.isArray(resp?.data) ? resp.data : [];
|
|
288
|
-
roleResources = items.map((item) => ({
|
|
289
|
-
resourceCode: item.resource?.code ?? String(item.resourceId),
|
|
290
|
-
resourceName: item.resource?.name ?? String(item.resourceId),
|
|
291
|
-
actions: Array.isArray(item.actions) ? item.actions : [],
|
|
292
|
-
}));
|
|
293
|
-
} catch {
|
|
294
|
-
message.warning(
|
|
295
|
-
'Could not fetch role resource details; SQL will omit permissions.',
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const sql = generateRoleSql(record, rolePages, roleResources, {
|
|
300
|
-
authorId: identity?.userid,
|
|
301
|
-
authorName: identity?.username,
|
|
302
|
-
});
|
|
303
|
-
setSqlModal({ open: true, title: `SQL — Role: ${record.name}`, sql });
|
|
304
|
-
},
|
|
305
|
-
[rolePermissionSummary, identity],
|
|
306
|
-
);
|
|
265
|
+
const [exportEndpoint, setExportEndpoint] = useState<string | null>(null);
|
|
266
|
+
const [importOpen, setImportOpen] = useState(false);
|
|
307
267
|
|
|
308
268
|
const refreshRoleRelatedData = useCallback(() => {
|
|
309
269
|
refetchRolePages(rolePagesQuery ?? {});
|
|
@@ -324,17 +284,25 @@ export const RoleManagementListPage: React.FC = () => {
|
|
|
324
284
|
<PageHeader
|
|
325
285
|
title="Role mgnts"
|
|
326
286
|
extra={
|
|
327
|
-
<
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
287
|
+
<Space>
|
|
288
|
+
<Button
|
|
289
|
+
icon={<ImportOutlined />}
|
|
290
|
+
onClick={() => setImportOpen(true)}
|
|
291
|
+
>
|
|
292
|
+
Import
|
|
293
|
+
</Button>
|
|
294
|
+
<Button
|
|
295
|
+
type="primary"
|
|
296
|
+
onClick={() =>
|
|
297
|
+
setShowModal({
|
|
298
|
+
type: 'create',
|
|
299
|
+
id: null,
|
|
300
|
+
})
|
|
301
|
+
}
|
|
302
|
+
>
|
|
303
|
+
Create Role
|
|
304
|
+
</Button>
|
|
305
|
+
</Space>
|
|
338
306
|
}
|
|
339
307
|
/>
|
|
340
308
|
<Card className="card-table">
|
|
@@ -364,12 +332,16 @@ export const RoleManagementListPage: React.FC = () => {
|
|
|
364
332
|
}
|
|
365
333
|
/>
|
|
366
334
|
</Tooltip>
|
|
367
|
-
<Tooltip title="
|
|
335
|
+
<Tooltip title="Export">
|
|
368
336
|
<Button
|
|
369
337
|
type="default"
|
|
370
338
|
size="small"
|
|
371
|
-
icon={<
|
|
372
|
-
onClick={() =>
|
|
339
|
+
icon={<ExportOutlined />}
|
|
340
|
+
onClick={() =>
|
|
341
|
+
setExportEndpoint(
|
|
342
|
+
`role/${encodeURIComponent(record.name)}/export-token`,
|
|
343
|
+
)
|
|
344
|
+
}
|
|
373
345
|
/>
|
|
374
346
|
</Tooltip>
|
|
375
347
|
</Space>
|
|
@@ -401,11 +373,18 @@ export const RoleManagementListPage: React.FC = () => {
|
|
|
401
373
|
pageTreeData={pageTreeData}
|
|
402
374
|
/>
|
|
403
375
|
)}
|
|
404
|
-
<
|
|
405
|
-
open={
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
376
|
+
<TransferExportModal
|
|
377
|
+
open={!!exportEndpoint}
|
|
378
|
+
exportTokenEndpoint={exportEndpoint}
|
|
379
|
+
entity="role"
|
|
380
|
+
onClose={() => setExportEndpoint(null)}
|
|
381
|
+
/>
|
|
382
|
+
<TransferImportModal
|
|
383
|
+
open={importOpen}
|
|
384
|
+
onClose={() => setImportOpen(false)}
|
|
385
|
+
onSuccess={() => tableQueryResult?.refetch()}
|
|
386
|
+
previewEndpoint="role/import-preview"
|
|
387
|
+
confirmEndpoint="role/import-confirm"
|
|
409
388
|
/>
|
|
410
389
|
</div>
|
|
411
390
|
);
|