@fe-free/core 1.2.4 → 1.3.1
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/CHANGELOG.md +18 -0
- package/package.json +4 -4
- package/src/button/button.stories.ts +7 -2
- package/src/button/index.tsx +1 -1
- package/src/crud/crud.stories.tsx +384 -0
- package/src/crud/crud.tsx +42 -102
- package/src/crud/crud_delete.tsx +19 -23
- package/src/crud/crud_detail.tsx +6 -6
- package/src/crud/demo/data.tsx +6 -6
- package/src/crud/index.tsx +2 -2
- package/src/crud/types.tsx +98 -0
- package/src/crud/use_row_selection.tsx +84 -0
- package/src/editor_javascript/{index.md → editor_javascript.stories.tsx} +24 -38
- package/src/editor_javascript/index.tsx +2 -1
- package/src/editor_json/{index.md → editor_json.stories.tsx} +42 -67
- package/src/editor_json/index.tsx +1 -0
- package/src/editor_logs/editor_logs.stories.tsx +47 -0
- package/src/editor_logs/index.tsx +4 -3
- package/src/editor_markdown/editor_markdown.stories.tsx +32 -0
- package/src/editor_markdown/index.tsx +1 -0
- package/src/form/form.stories.tsx +65 -0
- package/src/index.ts +13 -9
- package/src/table/index.tsx +3 -3
- package/src/table/table.stories.tsx +80 -0
- package/src/tailwindcss.stories.tsx +1 -1
- package/src/value_type_map/{index.md → value_type_map.stories.tsx} +22 -52
- package/src/crud/demo/index.tsx +0 -342
- package/src/crud/index.md +0 -158
- package/src/editor_logs/index.md +0 -48
- package/src/editor_markdown/index.md +0 -40
- package/src/form/index.md +0 -96
- package/src/table/index.md +0 -89
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @fe-free/core
|
|
2
2
|
|
|
3
|
+
## 1.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat: crud
|
|
8
|
+
- @fe-free/tool@1.3.1
|
|
9
|
+
|
|
10
|
+
## 1.3.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- feat: some
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- @fe-free/tool@1.3.0
|
|
20
|
+
|
|
3
21
|
## 1.2.4
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"author": "",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"react-syntax-highlighter": "^15.5.0",
|
|
30
30
|
"vanilla-jsoneditor": "^0.23.1",
|
|
31
31
|
"zustand": "^4.5.4",
|
|
32
|
-
"@fe-free/tool": "1.
|
|
32
|
+
"@fe-free/tool": "1.3.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@ant-design/pro-components": "^2.7
|
|
36
|
-
"antd": "^5.
|
|
35
|
+
"@ant-design/pro-components": "^2.8.7",
|
|
36
|
+
"antd": "^5.25.1",
|
|
37
37
|
"react": "^18.2.0"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { LoadingButton } from '@fe-free/core';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
const meta: Meta<typeof LoadingButton> = {
|
|
4
5
|
title: '@fe-free/core/LoadingButton',
|
|
5
6
|
component: LoadingButton,
|
|
6
7
|
tags: ['autodocs'],
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
+
export default meta;
|
|
11
|
+
|
|
12
|
+
type Story = StoryObj<typeof LoadingButton>;
|
|
13
|
+
|
|
14
|
+
export const Resolve: Story = {
|
|
10
15
|
args: {
|
|
11
16
|
children: 'click and resolve',
|
|
12
17
|
onClick: () => {
|
package/src/button/index.tsx
CHANGED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import type { ProColumns } from '@ant-design/pro-components';
|
|
2
|
+
import { ProForm, ProFormSwitch, ProFormText } from '@ant-design/pro-components';
|
|
3
|
+
import { CRUD, proFormSelectSearchProps } from '@fe-free/core';
|
|
4
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
5
|
+
import { Button } from 'antd';
|
|
6
|
+
import { useRef } from 'react';
|
|
7
|
+
import {
|
|
8
|
+
fakeCreate,
|
|
9
|
+
fakeDeleteByRecord,
|
|
10
|
+
fakeGetByRecord,
|
|
11
|
+
fakeRequest,
|
|
12
|
+
fakeRequestArea,
|
|
13
|
+
fakeRequestCity,
|
|
14
|
+
fakeRequestSchool,
|
|
15
|
+
fakeUpdateById,
|
|
16
|
+
levels,
|
|
17
|
+
} from './demo/data';
|
|
18
|
+
|
|
19
|
+
const meta: Meta<typeof CRUD> = {
|
|
20
|
+
title: '@fe-free/core/CRUD',
|
|
21
|
+
component: CRUD,
|
|
22
|
+
tags: ['autodocs'],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default meta;
|
|
26
|
+
type Story = StoryObj<typeof CRUD>;
|
|
27
|
+
|
|
28
|
+
// 基础用法
|
|
29
|
+
export const Normal: Story = {
|
|
30
|
+
render: () => {
|
|
31
|
+
const columns = [
|
|
32
|
+
{
|
|
33
|
+
title: 'id',
|
|
34
|
+
dataIndex: 'id',
|
|
35
|
+
search: true,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
title: '名字(省略)',
|
|
39
|
+
dataIndex: 'name',
|
|
40
|
+
search: true,
|
|
41
|
+
ellipsis: true,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
title: 'city',
|
|
45
|
+
dataIndex: 'city',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
title: 'area',
|
|
49
|
+
dataIndex: 'area',
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<CRUD
|
|
55
|
+
actions={['create', 'read', 'delete', 'update']}
|
|
56
|
+
tableProps={{
|
|
57
|
+
columns,
|
|
58
|
+
request: fakeRequest,
|
|
59
|
+
}}
|
|
60
|
+
requestDeleteByRecord={fakeDeleteByRecord}
|
|
61
|
+
deleteProps={{
|
|
62
|
+
nameIndex: 'name',
|
|
63
|
+
}}
|
|
64
|
+
detailForm={(formProps) => (
|
|
65
|
+
<>
|
|
66
|
+
<ProFormText
|
|
67
|
+
{...formProps}
|
|
68
|
+
name="name"
|
|
69
|
+
label="名字"
|
|
70
|
+
required
|
|
71
|
+
rules={[{ required: true }]}
|
|
72
|
+
extra="extra extra extra extra"
|
|
73
|
+
/>
|
|
74
|
+
</>
|
|
75
|
+
)}
|
|
76
|
+
requestGetByRecord={fakeGetByRecord}
|
|
77
|
+
requestCreateByValues={fakeCreate}
|
|
78
|
+
requestUpdateById={fakeUpdateById}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// 详情页查看
|
|
85
|
+
export const ReadDetail: Story = {
|
|
86
|
+
render: () => {
|
|
87
|
+
const columns = [
|
|
88
|
+
{
|
|
89
|
+
title: 'id',
|
|
90
|
+
dataIndex: 'id',
|
|
91
|
+
search: true,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
title: '名字',
|
|
95
|
+
dataIndex: 'name',
|
|
96
|
+
search: true,
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<CRUD
|
|
102
|
+
actions={['read_detail']}
|
|
103
|
+
tableProps={{
|
|
104
|
+
columns,
|
|
105
|
+
request: fakeRequest,
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// 表格表单和详情表单 ref
|
|
113
|
+
const RefComponent = () => {
|
|
114
|
+
const formRef = useRef<any>();
|
|
115
|
+
const [detailFormInstance] = ProForm.useForm();
|
|
116
|
+
|
|
117
|
+
const columns = [
|
|
118
|
+
{
|
|
119
|
+
title: 'id',
|
|
120
|
+
dataIndex: 'id',
|
|
121
|
+
search: true,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
title: '名字',
|
|
125
|
+
dataIndex: 'name',
|
|
126
|
+
search: true,
|
|
127
|
+
},
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<CRUD
|
|
132
|
+
actions={['create', 'read', 'update']}
|
|
133
|
+
tableProps={{
|
|
134
|
+
formRef,
|
|
135
|
+
columns,
|
|
136
|
+
request: fakeRequest,
|
|
137
|
+
}}
|
|
138
|
+
detailFormInstance={detailFormInstance}
|
|
139
|
+
detailForm={(formProps) => (
|
|
140
|
+
<>
|
|
141
|
+
<ProFormText
|
|
142
|
+
{...formProps}
|
|
143
|
+
name="name"
|
|
144
|
+
label="名字"
|
|
145
|
+
required
|
|
146
|
+
rules={[{ required: true }]}
|
|
147
|
+
initialValue={'default'}
|
|
148
|
+
/>
|
|
149
|
+
<ProFormSwitch {...formProps} name="status" label="开启" initialValue={false} />
|
|
150
|
+
</>
|
|
151
|
+
)}
|
|
152
|
+
requestGetByRecord={fakeGetByRecord}
|
|
153
|
+
requestCreateByValues={fakeCreate}
|
|
154
|
+
requestUpdateByValues={fakeUpdateById}
|
|
155
|
+
/>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const Ref: Story = {
|
|
160
|
+
render: () => <RefComponent />,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// 通过 ref 获取 actionRef
|
|
164
|
+
const ActionRefComponent = () => {
|
|
165
|
+
const ref = useRef<any>();
|
|
166
|
+
|
|
167
|
+
const columns = [
|
|
168
|
+
{
|
|
169
|
+
title: 'id',
|
|
170
|
+
dataIndex: 'id',
|
|
171
|
+
search: true,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
title: '名字',
|
|
175
|
+
dataIndex: 'name',
|
|
176
|
+
search: true,
|
|
177
|
+
},
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<>
|
|
182
|
+
<Button onClick={() => ref.current.getActionRef().current?.reload()}>reload</Button>
|
|
183
|
+
<CRUD
|
|
184
|
+
ref={ref}
|
|
185
|
+
actions={[]}
|
|
186
|
+
tableProps={{
|
|
187
|
+
columns,
|
|
188
|
+
request: fakeRequest,
|
|
189
|
+
}}
|
|
190
|
+
/>
|
|
191
|
+
</>
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const ActionRef: Story = {
|
|
196
|
+
render: () => <ActionRefComponent />,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// 数据 本地&远程&依赖
|
|
200
|
+
export const RemoteData: Story = {
|
|
201
|
+
render: () => {
|
|
202
|
+
const columns: ProColumns<any>[] = [
|
|
203
|
+
{
|
|
204
|
+
title: 'id',
|
|
205
|
+
dataIndex: 'id',
|
|
206
|
+
search: true,
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
title: '名字',
|
|
210
|
+
dataIndex: 'name',
|
|
211
|
+
search: true,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
title: '等级(本地数据)',
|
|
215
|
+
dataIndex: 'level',
|
|
216
|
+
search: true,
|
|
217
|
+
valueEnum: levels,
|
|
218
|
+
...proFormSelectSearchProps,
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
title: 'city(远端数据)',
|
|
222
|
+
dataIndex: 'city',
|
|
223
|
+
search: true,
|
|
224
|
+
request: async () => {
|
|
225
|
+
const res = await fakeRequestCity();
|
|
226
|
+
return res.map((item) => ({
|
|
227
|
+
label: item,
|
|
228
|
+
value: item,
|
|
229
|
+
}));
|
|
230
|
+
},
|
|
231
|
+
...proFormSelectSearchProps,
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
title: 'area(联动 city)',
|
|
235
|
+
dataIndex: 'area',
|
|
236
|
+
search: true,
|
|
237
|
+
request: async (params) => {
|
|
238
|
+
const res = await fakeRequestArea(params);
|
|
239
|
+
return res.map((item) => ({
|
|
240
|
+
label: item,
|
|
241
|
+
value: item,
|
|
242
|
+
}));
|
|
243
|
+
},
|
|
244
|
+
dependencies: ['city'],
|
|
245
|
+
...proFormSelectSearchProps,
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
title: '学校(远端数据 label value)',
|
|
249
|
+
dataIndex: 'school',
|
|
250
|
+
search: true,
|
|
251
|
+
valueType: 'select' as const,
|
|
252
|
+
request: () => fakeRequestSchool(),
|
|
253
|
+
...proFormSelectSearchProps,
|
|
254
|
+
},
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<CRUD
|
|
259
|
+
actions={[]}
|
|
260
|
+
tableProps={{
|
|
261
|
+
columns,
|
|
262
|
+
request: fakeRequest,
|
|
263
|
+
}}
|
|
264
|
+
/>
|
|
265
|
+
);
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// 没有搜索
|
|
270
|
+
export const NoSearch: Story = {
|
|
271
|
+
render: () => {
|
|
272
|
+
const columns = [
|
|
273
|
+
{
|
|
274
|
+
title: 'id',
|
|
275
|
+
dataIndex: 'id',
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
title: '名字',
|
|
279
|
+
dataIndex: 'name',
|
|
280
|
+
},
|
|
281
|
+
];
|
|
282
|
+
|
|
283
|
+
return (
|
|
284
|
+
<CRUD
|
|
285
|
+
actions={[]}
|
|
286
|
+
tableProps={{
|
|
287
|
+
columns,
|
|
288
|
+
request: fakeRequest,
|
|
289
|
+
search: false,
|
|
290
|
+
}}
|
|
291
|
+
/>
|
|
292
|
+
);
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
// 自定义文案
|
|
297
|
+
export const CustomText: Story = {
|
|
298
|
+
render: () => {
|
|
299
|
+
const columns = [
|
|
300
|
+
{
|
|
301
|
+
title: 'id',
|
|
302
|
+
dataIndex: 'id',
|
|
303
|
+
search: true,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
title: '名字',
|
|
307
|
+
dataIndex: 'name',
|
|
308
|
+
search: true,
|
|
309
|
+
},
|
|
310
|
+
];
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<CRUD
|
|
314
|
+
actions={['create', 'read', 'delete', 'update']}
|
|
315
|
+
tableProps={{
|
|
316
|
+
columns,
|
|
317
|
+
request: fakeRequest,
|
|
318
|
+
}}
|
|
319
|
+
createButton={<Button type="primary">新建</Button>}
|
|
320
|
+
readProps={{
|
|
321
|
+
operateText: '查看',
|
|
322
|
+
}}
|
|
323
|
+
deleteProps={{
|
|
324
|
+
nameIndex: 'name',
|
|
325
|
+
operateText: '删除',
|
|
326
|
+
desc: '确定要删除吗?',
|
|
327
|
+
}}
|
|
328
|
+
updateProps={{
|
|
329
|
+
operateText: '编辑',
|
|
330
|
+
successText: '编辑成功',
|
|
331
|
+
}}
|
|
332
|
+
requestDeleteByRecord={fakeDeleteByRecord}
|
|
333
|
+
detailForm={(formProps) => (
|
|
334
|
+
<>
|
|
335
|
+
<ProFormText
|
|
336
|
+
{...formProps}
|
|
337
|
+
name="name"
|
|
338
|
+
label="名字"
|
|
339
|
+
required
|
|
340
|
+
rules={[{ required: true }]}
|
|
341
|
+
/>
|
|
342
|
+
</>
|
|
343
|
+
)}
|
|
344
|
+
requestGetByRecord={fakeGetByRecord}
|
|
345
|
+
requestCreateByValues={fakeCreate}
|
|
346
|
+
requestUpdateByValues={fakeUpdateById}
|
|
347
|
+
/>
|
|
348
|
+
);
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
export const RowSelection: Story = {
|
|
353
|
+
render: () => {
|
|
354
|
+
return (
|
|
355
|
+
<CRUD
|
|
356
|
+
actions={[]}
|
|
357
|
+
tableProps={{
|
|
358
|
+
columns: [
|
|
359
|
+
{
|
|
360
|
+
title: 'id',
|
|
361
|
+
dataIndex: 'id',
|
|
362
|
+
search: true,
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
title: '名字',
|
|
366
|
+
dataIndex: 'name',
|
|
367
|
+
search: true,
|
|
368
|
+
},
|
|
369
|
+
],
|
|
370
|
+
request: fakeRequest,
|
|
371
|
+
}}
|
|
372
|
+
batchActions={[
|
|
373
|
+
{
|
|
374
|
+
btnText: '批量删除',
|
|
375
|
+
danger: true,
|
|
376
|
+
onClick: async (_, { selectedRowKeys }) => {
|
|
377
|
+
console.log(selectedRowKeys);
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
]}
|
|
381
|
+
/>
|
|
382
|
+
);
|
|
383
|
+
},
|
|
384
|
+
};
|
package/src/crud/crud.tsx
CHANGED
|
@@ -1,90 +1,18 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import type { ReactNode } from 'react';
|
|
1
|
+
import type { ActionType } from '@ant-design/pro-components';
|
|
2
|
+
import { Button, Space } from 'antd';
|
|
4
3
|
import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef } from 'react';
|
|
5
|
-
import { Link, useLocation } from 'react-router-dom';
|
|
6
4
|
import type { TableProps } from '../table';
|
|
7
5
|
import { Table } from '../table';
|
|
8
6
|
import { OperateDelete } from './crud_delete';
|
|
9
7
|
import { CRUDDetail } from './crud_detail';
|
|
10
8
|
import './style.scss';
|
|
9
|
+
import type { CRUDMethods, CRUDProps } from './types';
|
|
10
|
+
import { useRowSelection } from './use_row_selection';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* update 编辑
|
|
17
|
-
* delete 删除
|
|
18
|
-
*/
|
|
19
|
-
type CrudAction = 'create' | 'read' | 'read_detail' | 'update' | 'delete';
|
|
20
|
-
|
|
21
|
-
interface CRUDProps {
|
|
22
|
-
actions: CrudAction[];
|
|
23
|
-
|
|
24
|
-
/** 新建按钮,默认新建 */
|
|
25
|
-
createButton?: ReactNode;
|
|
26
|
-
|
|
27
|
-
/** 表格相关 */
|
|
28
|
-
tableProps: TableProps;
|
|
29
|
-
operateColumnProps?: {
|
|
30
|
-
width?: number;
|
|
31
|
-
/** 扩展操作区域,再其他操作之前 */
|
|
32
|
-
moreOperator?: (record) => ReactNode;
|
|
33
|
-
/** 扩展操作区域,在其他操作之后 */
|
|
34
|
-
moreOperatorAfter?: (record) => ReactNode;
|
|
35
|
-
};
|
|
36
|
-
readProps?: {
|
|
37
|
-
/** 文本 */
|
|
38
|
-
operateText?: string;
|
|
39
|
-
/** 打开方式, action 为 read_detail 有效 */
|
|
40
|
-
target?: '_blank';
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/** 删除接口 */
|
|
44
|
-
requestDeleteByRecord?: (record) => Promise<any>;
|
|
45
|
-
/** 删除相关 */
|
|
46
|
-
deleteProps?: {
|
|
47
|
-
/** 显示名称索引 */
|
|
48
|
-
nameIndex: string;
|
|
49
|
-
/** 删除确认描述 */
|
|
50
|
-
desc?: string;
|
|
51
|
-
/** 文本 */
|
|
52
|
-
operateText?: string;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/** 弹窗表单 */
|
|
56
|
-
detailForm?: (formProps: { readonly: boolean }, info: { action: CrudAction }) => ReactNode;
|
|
57
|
-
/** detailForm 的 formRef */
|
|
58
|
-
detailFormInstance?: ProFormInstance;
|
|
59
|
-
|
|
60
|
-
/** 新增接口 */
|
|
61
|
-
requestCreateByValues?: (values) => Promise<any>;
|
|
62
|
-
createProps?: {
|
|
63
|
-
/** 成功文案 */
|
|
64
|
-
successText?: string | (() => string);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/** 更新接口 */
|
|
68
|
-
requestUpdateById?: (values) => Promise<any>;
|
|
69
|
-
updateProps?: {
|
|
70
|
-
/** 文本 */
|
|
71
|
-
operateText?: string;
|
|
72
|
-
/** 成功文案 */
|
|
73
|
-
successText?: string | (() => string);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/** 获取详情接口 */
|
|
77
|
-
requestGetByRecord?: (record) => Promise<any>;
|
|
78
|
-
|
|
79
|
-
/** 跳转到详情的索引 ,默认 id */
|
|
80
|
-
detailIdIndex?: string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
interface CRUDMethods {
|
|
84
|
-
getActionRef: () => React.MutableRefObject<ActionType | undefined>;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
12
|
+
function CRUDComponent<
|
|
13
|
+
DataSource extends Record<string, any> = any,
|
|
14
|
+
Key extends string | number = string,
|
|
15
|
+
>(props: CRUDProps<DataSource, Key>, ref: React.ForwardedRef<CRUDMethods>) {
|
|
88
16
|
const {
|
|
89
17
|
actions,
|
|
90
18
|
tableProps,
|
|
@@ -99,22 +27,21 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
99
27
|
createProps,
|
|
100
28
|
requestCreateByValues,
|
|
101
29
|
updateProps,
|
|
102
|
-
requestUpdateById,
|
|
30
|
+
requestUpdateById: originalRequestUpdateById,
|
|
31
|
+
requestUpdateByValues: originalRequestUpdateByValues,
|
|
103
32
|
detailFormInstance,
|
|
33
|
+
batchActions,
|
|
104
34
|
} = props;
|
|
105
35
|
|
|
36
|
+
const requestUpdateById = originalRequestUpdateByValues || originalRequestUpdateById;
|
|
37
|
+
|
|
106
38
|
const actionRef = useRef<ActionType>();
|
|
107
|
-
const location = useLocation();
|
|
108
39
|
|
|
109
|
-
useImperativeHandle(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
};
|
|
115
|
-
},
|
|
116
|
-
[actionRef]
|
|
117
|
-
);
|
|
40
|
+
useImperativeHandle(ref, () => {
|
|
41
|
+
return {
|
|
42
|
+
getActionRef: () => actionRef,
|
|
43
|
+
};
|
|
44
|
+
}, [actionRef]);
|
|
118
45
|
|
|
119
46
|
const detailProps = useMemo(
|
|
120
47
|
() => ({
|
|
@@ -134,7 +61,7 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
134
61
|
detailFormInstance,
|
|
135
62
|
createProps,
|
|
136
63
|
updateProps,
|
|
137
|
-
]
|
|
64
|
+
],
|
|
138
65
|
);
|
|
139
66
|
|
|
140
67
|
const getHandleDelete = useCallback(
|
|
@@ -149,7 +76,7 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
149
76
|
throw new Error('没有传 requestDeleteByRecord');
|
|
150
77
|
};
|
|
151
78
|
},
|
|
152
|
-
[requestDeleteByRecord]
|
|
79
|
+
[requestDeleteByRecord],
|
|
153
80
|
);
|
|
154
81
|
|
|
155
82
|
const handleReload = useCallback(() => {
|
|
@@ -176,12 +103,9 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
176
103
|
/>
|
|
177
104
|
)}
|
|
178
105
|
{actions.includes('read_detail') && (
|
|
179
|
-
<
|
|
180
|
-
to={`${location.pathname}/detail/${record[detailIdIndex || 'id']}`}
|
|
181
|
-
target={readProps?.target}
|
|
182
|
-
>
|
|
106
|
+
<a href={`./detail/${record[detailIdIndex || 'id']}`} target={readProps?.target}>
|
|
183
107
|
{readProps?.operateText || '查看'}
|
|
184
|
-
</
|
|
108
|
+
</a>
|
|
185
109
|
)}
|
|
186
110
|
{actions.includes('update') && (
|
|
187
111
|
<CRUDDetail
|
|
@@ -230,7 +154,6 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
230
154
|
readProps?.operateText,
|
|
231
155
|
readProps?.target,
|
|
232
156
|
detailProps,
|
|
233
|
-
location.pathname,
|
|
234
157
|
detailIdIndex,
|
|
235
158
|
updateProps?.operateText,
|
|
236
159
|
deleteProps,
|
|
@@ -239,6 +162,7 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
239
162
|
|
|
240
163
|
const toolBarRender = useCallback(
|
|
241
164
|
(...args) => [
|
|
165
|
+
// @ts-ignore
|
|
242
166
|
...(tableProps.toolBarRender ? tableProps.toolBarRender(...args) : []),
|
|
243
167
|
actions.includes('create') && (
|
|
244
168
|
<CRUDDetail
|
|
@@ -249,9 +173,16 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
249
173
|
/>
|
|
250
174
|
),
|
|
251
175
|
],
|
|
252
|
-
[actions, createButton, detailProps, handleReload, tableProps]
|
|
176
|
+
[actions, createButton, detailProps, handleReload, tableProps],
|
|
253
177
|
);
|
|
254
178
|
|
|
179
|
+
const { rowSelection, tableAlertRender, tableAlertOptionRender } = useRowSelection<
|
|
180
|
+
DataSource,
|
|
181
|
+
Key
|
|
182
|
+
>({
|
|
183
|
+
batchActions,
|
|
184
|
+
});
|
|
185
|
+
|
|
255
186
|
return (
|
|
256
187
|
<div className="crud-table">
|
|
257
188
|
<Table
|
|
@@ -260,10 +191,19 @@ const CRUD = forwardRef<CRUDMethods, CRUDProps>(function CRUD(props, ref) {
|
|
|
260
191
|
actionRef={actionRef}
|
|
261
192
|
toolBarRender={toolBarRender}
|
|
262
193
|
columns={newColumns}
|
|
194
|
+
rowSelection={rowSelection}
|
|
195
|
+
tableAlertRender={tableAlertRender}
|
|
196
|
+
tableAlertOptionRender={tableAlertOptionRender}
|
|
263
197
|
/>
|
|
264
198
|
</div>
|
|
265
199
|
);
|
|
266
|
-
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const CRUD = forwardRef(CRUDComponent) as <
|
|
203
|
+
DataSource extends Record<string, any> = any,
|
|
204
|
+
Key extends string | number = string,
|
|
205
|
+
>(
|
|
206
|
+
props: CRUDProps<DataSource, Key> & { ref?: React.ForwardedRef<CRUDMethods> },
|
|
207
|
+
) => JSX.Element;
|
|
267
208
|
|
|
268
209
|
export { CRUD };
|
|
269
|
-
export type { CRUDProps, CRUDMethods };
|