openxiangda-cli 2.0.0-alpha.67 → 2.0.0-alpha.68
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/package.json +1 -1
- package/template/apps/web/e2e/resources.spec.ts +11 -0
- package/template/apps/web/src/FilePreviewPage.tsx +3 -3
- package/template/apps/web/src/Shell.tsx +323 -33
- package/template/apps/web/src/appearance.tsx +147 -0
- package/template/apps/web/src/components/resource/GeneratedResourceCrud.tsx +410 -50
- package/template/apps/web/src/components/resource/StandardResourcePages.tsx +13 -52
- package/template/apps/web/src/components/resource/SurfaceFields.tsx +1 -1
- package/template/apps/web/src/main.tsx +22 -21
- package/template/apps/web/src/platform-client.ts +7 -0
- package/template/apps/web/src/styles.css +425 -219
- package/template/apps/web/test/contracts.test.ts +37 -0
- package/template/package.json +1 -1
|
@@ -4,12 +4,10 @@ import {
|
|
|
4
4
|
ExportOutlined,
|
|
5
5
|
EyeOutlined,
|
|
6
6
|
HistoryOutlined,
|
|
7
|
-
ImportOutlined,
|
|
8
7
|
PlusOutlined,
|
|
9
8
|
} from '@ant-design/icons';
|
|
10
9
|
import {
|
|
11
10
|
Alert,
|
|
12
|
-
App,
|
|
13
11
|
Button,
|
|
14
12
|
Card,
|
|
15
13
|
Result,
|
|
@@ -47,17 +45,10 @@ export function ResourceListPage({
|
|
|
47
45
|
resource,
|
|
48
46
|
surface,
|
|
49
47
|
title,
|
|
50
|
-
description,
|
|
51
48
|
readCapability,
|
|
52
|
-
createCapability,
|
|
53
|
-
createPath,
|
|
54
|
-
onExport,
|
|
55
|
-
importDisabledReason = '导入能力将在批量事务合同落地后启用',
|
|
56
49
|
children,
|
|
57
50
|
}: ResourceListPageProps) {
|
|
58
|
-
const navigate = useNavigate();
|
|
59
51
|
const { hasCapability } = useRuntime();
|
|
60
|
-
const { message } = App.useApp();
|
|
61
52
|
if (!hasCapability(readCapability)) {
|
|
62
53
|
return (
|
|
63
54
|
<Shell>
|
|
@@ -65,7 +56,6 @@ export function ResourceListPage({
|
|
|
65
56
|
</Shell>
|
|
66
57
|
);
|
|
67
58
|
}
|
|
68
|
-
const canCreate = createCapability ? hasCapability(createCapability) : false;
|
|
69
59
|
return (
|
|
70
60
|
<Shell>
|
|
71
61
|
<Card
|
|
@@ -73,42 +63,7 @@ export function ResourceListPage({
|
|
|
73
63
|
data-resource={resource}
|
|
74
64
|
data-surface-layout={surface?.list ? 'standard' : undefined}
|
|
75
65
|
>
|
|
76
|
-
<
|
|
77
|
-
<div className="oxa-page-heading">
|
|
78
|
-
<div>
|
|
79
|
-
<h2 className="oxa-title">{title}</h2>
|
|
80
|
-
{description && <div className="oxa-muted">{description}</div>}
|
|
81
|
-
</div>
|
|
82
|
-
<Space>
|
|
83
|
-
<Button
|
|
84
|
-
disabled
|
|
85
|
-
icon={<ImportOutlined />}
|
|
86
|
-
title={importDisabledReason}
|
|
87
|
-
>
|
|
88
|
-
导入
|
|
89
|
-
</Button>
|
|
90
|
-
<Button
|
|
91
|
-
icon={<ExportOutlined />}
|
|
92
|
-
onClick={() => {
|
|
93
|
-
if (onExport) onExport();
|
|
94
|
-
else message.info('导出将使用当前 Data API 查询条件');
|
|
95
|
-
}}
|
|
96
|
-
>
|
|
97
|
-
导出
|
|
98
|
-
</Button>
|
|
99
|
-
{canCreate && createPath && (
|
|
100
|
-
<Button
|
|
101
|
-
icon={<PlusOutlined />}
|
|
102
|
-
onClick={() => navigate(createPath)}
|
|
103
|
-
type="primary"
|
|
104
|
-
>
|
|
105
|
-
新增
|
|
106
|
-
</Button>
|
|
107
|
-
)}
|
|
108
|
-
</Space>
|
|
109
|
-
</div>
|
|
110
|
-
{children}
|
|
111
|
-
</Space>
|
|
66
|
+
<div className="oxa-list-surface">{children}</div>
|
|
112
67
|
</Card>
|
|
113
68
|
</Shell>
|
|
114
69
|
);
|
|
@@ -289,6 +244,7 @@ interface ResourceDetailPageProps extends StandardResourcePageProps {
|
|
|
289
244
|
editCapability?: string;
|
|
290
245
|
editPath?: string;
|
|
291
246
|
auditTargetId?: string;
|
|
247
|
+
onAuditOpen?: () => void;
|
|
292
248
|
hero: ReactNode;
|
|
293
249
|
meta?: ReactNode;
|
|
294
250
|
children: ReactNode;
|
|
@@ -307,6 +263,7 @@ export function ResourceDetailPage({
|
|
|
307
263
|
editCapability,
|
|
308
264
|
editPath,
|
|
309
265
|
auditTargetId,
|
|
266
|
+
onAuditOpen,
|
|
310
267
|
hero,
|
|
311
268
|
meta,
|
|
312
269
|
children,
|
|
@@ -356,11 +313,14 @@ export function ResourceDetailPage({
|
|
|
356
313
|
{auditTargetId && (
|
|
357
314
|
<Button
|
|
358
315
|
icon={<HistoryOutlined />}
|
|
359
|
-
onClick={() =>
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
316
|
+
onClick={() => {
|
|
317
|
+
onAuditOpen?.();
|
|
318
|
+
window.requestAnimationFrame(() =>
|
|
319
|
+
document
|
|
320
|
+
.getElementById(auditTargetId)
|
|
321
|
+
?.scrollIntoView({ behavior: 'smooth', block: 'center' }),
|
|
322
|
+
);
|
|
323
|
+
}}
|
|
364
324
|
>
|
|
365
325
|
操作记录
|
|
366
326
|
</Button>
|
|
@@ -399,6 +359,7 @@ export function MobileResourceDetailPage({
|
|
|
399
359
|
editCapability,
|
|
400
360
|
editPath,
|
|
401
361
|
auditTargetId,
|
|
362
|
+
onAuditOpen,
|
|
402
363
|
hero,
|
|
403
364
|
meta,
|
|
404
365
|
children,
|
|
@@ -417,7 +378,7 @@ export function MobileResourceDetailPage({
|
|
|
417
378
|
{backLabel}
|
|
418
379
|
</Button>
|
|
419
380
|
<Space>
|
|
420
|
-
{auditTargetId && <Button icon={<HistoryOutlined />} onClick={() => document.getElementById(auditTargetId)?.scrollIntoView({ behavior: 'smooth', block: 'center' })}>操作记录</Button>}
|
|
381
|
+
{auditTargetId && <Button icon={<HistoryOutlined />} onClick={() => { onAuditOpen?.(); window.requestAnimationFrame(() => document.getElementById(auditTargetId)?.scrollIntoView({ behavior: 'smooth', block: 'center' })); }}>操作记录</Button>}
|
|
421
382
|
{editCapability && editPath && hasCapability(editCapability) && <Button icon={<EditOutlined />} onClick={() => navigate(editPath)} type="primary">编辑</Button>}
|
|
422
383
|
</Space>
|
|
423
384
|
</header>
|
|
@@ -460,7 +460,7 @@ function ManagedFileField({
|
|
|
460
460
|
refsRef.current = refs;
|
|
461
461
|
}, [refs]);
|
|
462
462
|
if (!onUpload) {
|
|
463
|
-
return <Alert type="info" showIcon
|
|
463
|
+
return <Alert type="info" showIcon title="该文件字段尚未配置上传能力" />;
|
|
464
464
|
}
|
|
465
465
|
if (mobile) {
|
|
466
466
|
const acceptValue = Array.isArray(accept) ? accept.join(',') : accept;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Refine } from '@refinedev/core';
|
|
2
|
-
import { App as AntdApp, ConfigProvider, Spin } from 'antd';
|
|
3
|
-
import zhCN from 'antd/locale/zh_CN';
|
|
4
2
|
import React from 'react';
|
|
5
3
|
import ReactDOM from 'react-dom/client';
|
|
6
4
|
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
|
|
7
5
|
import { resourceDefinitions } from '../../../packages/contracts/src/generated.js';
|
|
8
6
|
import { applicationProvider } from './data-provider';
|
|
7
|
+
import { AppearanceProvider } from './appearance';
|
|
9
8
|
import { GeneratedResourcePage } from './components/resource/GeneratedResourceCrud';
|
|
10
9
|
import { FilePreviewPage } from './FilePreviewPage';
|
|
11
10
|
import { EmptyApplicationPage } from './Shell';
|
|
@@ -20,9 +19,13 @@ const firstPath = codes[0] ? `/${codes[0]}` : '/';
|
|
|
20
19
|
function GlobalRequestLoading() {
|
|
21
20
|
const loading = useGlobalRequestLoading();
|
|
22
21
|
return loading ? (
|
|
23
|
-
<div
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
<div
|
|
23
|
+
aria-label="页面请求进行中"
|
|
24
|
+
aria-valuetext="正在加载"
|
|
25
|
+
className="oxa-global-request-loading"
|
|
26
|
+
role="progressbar"
|
|
27
|
+
>
|
|
28
|
+
<span />
|
|
26
29
|
</div>
|
|
27
30
|
) : null;
|
|
28
31
|
}
|
|
@@ -40,21 +43,19 @@ const resourceRoutes = codes.flatMap(resourceCode => [
|
|
|
40
43
|
|
|
41
44
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
42
45
|
<React.StrictMode>
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
<
|
|
48
|
-
<
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
</AntdApp>
|
|
58
|
-
</ConfigProvider>
|
|
46
|
+
<AppearanceProvider>
|
|
47
|
+
<GlobalRequestLoading />
|
|
48
|
+
<RuntimeBoundary>
|
|
49
|
+
<BrowserRouter basename={applicationBasename()}>
|
|
50
|
+
<Refine dataProvider={applicationProvider} resources={codes.map(code => ({ name: code, list: `/${code}`, create: `/${code}/new`, edit: `/${code}/:id/edit`, show: `/${code}/:id` }))}>
|
|
51
|
+
<Routes>
|
|
52
|
+
<Route path="/" element={codes.length ? <Navigate replace to={firstPath} /> : <EmptyApplicationPage />} />
|
|
53
|
+
<Route path="/files/:resourceCode/:fileId/preview" element={<FilePreviewPage />} />
|
|
54
|
+
{resourceRoutes}
|
|
55
|
+
</Routes>
|
|
56
|
+
</Refine>
|
|
57
|
+
</BrowserRouter>
|
|
58
|
+
</RuntimeBoundary>
|
|
59
|
+
</AppearanceProvider>
|
|
59
60
|
</React.StrictMode>,
|
|
60
61
|
);
|
|
@@ -115,6 +115,13 @@ export async function loadCurrentIdentity(): Promise<RuntimeIdentity> {
|
|
|
115
115
|
return activeIdentity;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
export async function logoutCurrentUser() {
|
|
119
|
+
await request<null>('/api/auth/logout', {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
});
|
|
122
|
+
activeIdentity = undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
118
125
|
function currentEnvironmentKey() {
|
|
119
126
|
const key = activeIdentity?.environment.key || runtimeMount()?.environmentKey;
|
|
120
127
|
if (!key) throw new Error('OPENXIANGDA_CURRENT_ENVIRONMENT_REQUIRED');
|