@fe-free/core 1.3.1 → 1.3.3
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 +14 -0
- package/package.json +2 -2
- package/src/crud/crud.stories.tsx +73 -3
- package/src/crud/crud.tsx +19 -14
- package/src/crud/crud_of_simple.stories.tsx +109 -0
- package/src/crud/crud_of_simple.tsx +118 -0
- package/src/crud/demo/data.tsx +14 -2
- package/src/crud/index.tsx +2 -0
- package/src/crud/types.tsx +43 -31
- package/src/crud/use_row_selection.tsx +12 -5
- package/src/crud/use_tips.tsx +34 -0
- package/src/index.ts +2 -2
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"author": "",
|
|
@@ -29,7 +29,7 @@
|
|
|
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.3.
|
|
32
|
+
"@fe-free/tool": "1.3.3"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@ant-design/pro-components": "^2.8.7",
|
|
@@ -109,8 +109,78 @@ export const ReadDetail: Story = {
|
|
|
109
109
|
},
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
+
export const MoreCustom: Story = {
|
|
113
|
+
render: () => {
|
|
114
|
+
const columns = [
|
|
115
|
+
{
|
|
116
|
+
title: 'id',
|
|
117
|
+
dataIndex: 'id',
|
|
118
|
+
search: true,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
title: '名字(省略)',
|
|
122
|
+
dataIndex: 'name',
|
|
123
|
+
search: true,
|
|
124
|
+
ellipsis: true,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
title: 'city',
|
|
128
|
+
dataIndex: 'city',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
title: 'area',
|
|
132
|
+
dataIndex: 'area',
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<CRUD
|
|
138
|
+
actions={['create', 'read', 'delete', 'update']}
|
|
139
|
+
tableProps={{
|
|
140
|
+
columns,
|
|
141
|
+
request: fakeRequest,
|
|
142
|
+
toolBarRender: () => {
|
|
143
|
+
return [<div key="custom1">自定义1</div>, <div key="custom2">自定义2</div>];
|
|
144
|
+
},
|
|
145
|
+
}}
|
|
146
|
+
operateColumnProps={{
|
|
147
|
+
// 自定义宽度
|
|
148
|
+
width: 300,
|
|
149
|
+
// 自定义操作列
|
|
150
|
+
moreOperator: () => {
|
|
151
|
+
return <div>自定义</div>;
|
|
152
|
+
},
|
|
153
|
+
// 自定义操作列之后
|
|
154
|
+
moreOperatorAfter: () => {
|
|
155
|
+
return <div>自定义</div>;
|
|
156
|
+
},
|
|
157
|
+
}}
|
|
158
|
+
requestDeleteByRecord={fakeDeleteByRecord}
|
|
159
|
+
deleteProps={{
|
|
160
|
+
nameIndex: 'name',
|
|
161
|
+
}}
|
|
162
|
+
detailForm={(formProps) => (
|
|
163
|
+
<>
|
|
164
|
+
<ProFormText
|
|
165
|
+
{...formProps}
|
|
166
|
+
name="name"
|
|
167
|
+
label="名字"
|
|
168
|
+
required
|
|
169
|
+
rules={[{ required: true }]}
|
|
170
|
+
extra="extra extra extra extra"
|
|
171
|
+
/>
|
|
172
|
+
</>
|
|
173
|
+
)}
|
|
174
|
+
requestGetByRecord={fakeGetByRecord}
|
|
175
|
+
requestCreateByValues={fakeCreate}
|
|
176
|
+
requestUpdateById={fakeUpdateById}
|
|
177
|
+
/>
|
|
178
|
+
);
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
|
|
112
182
|
// 表格表单和详情表单 ref
|
|
113
|
-
const
|
|
183
|
+
const FormRefComponent = () => {
|
|
114
184
|
const formRef = useRef<any>();
|
|
115
185
|
const [detailFormInstance] = ProForm.useForm();
|
|
116
186
|
|
|
@@ -156,8 +226,8 @@ const RefComponent = () => {
|
|
|
156
226
|
);
|
|
157
227
|
};
|
|
158
228
|
|
|
159
|
-
export const
|
|
160
|
-
render: () => <
|
|
229
|
+
export const FormRef: Story = {
|
|
230
|
+
render: () => <FormRefComponent />,
|
|
161
231
|
};
|
|
162
232
|
|
|
163
233
|
// 通过 ref 获取 actionRef
|
package/src/crud/crud.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import { CRUDDetail } from './crud_detail';
|
|
|
8
8
|
import './style.scss';
|
|
9
9
|
import type { CRUDMethods, CRUDProps } from './types';
|
|
10
10
|
import { useRowSelection } from './use_row_selection';
|
|
11
|
+
import { useTips } from './use_tips';
|
|
11
12
|
|
|
12
13
|
function CRUDComponent<
|
|
13
14
|
DataSource extends Record<string, any> = any,
|
|
@@ -33,9 +34,11 @@ function CRUDComponent<
|
|
|
33
34
|
batchActions,
|
|
34
35
|
} = props;
|
|
35
36
|
|
|
37
|
+
useTips(props);
|
|
38
|
+
|
|
36
39
|
const requestUpdateById = originalRequestUpdateByValues || originalRequestUpdateById;
|
|
37
40
|
|
|
38
|
-
const actionRef = useRef<ActionType>();
|
|
41
|
+
const actionRef = useRef<ActionType | undefined>(undefined);
|
|
39
42
|
|
|
40
43
|
useImperativeHandle(ref, () => {
|
|
41
44
|
return {
|
|
@@ -161,18 +164,19 @@ function CRUDComponent<
|
|
|
161
164
|
]);
|
|
162
165
|
|
|
163
166
|
const toolBarRender = useCallback(
|
|
164
|
-
(...args) =>
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
167
|
+
(...args) =>
|
|
168
|
+
[
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
...(tableProps.toolBarRender ? tableProps.toolBarRender(...args) : []),
|
|
171
|
+
actions.includes('create') && (
|
|
172
|
+
<CRUDDetail
|
|
173
|
+
onSuccess={handleReload}
|
|
174
|
+
trigger={createButton || <Button type="primary">新建</Button>}
|
|
175
|
+
action="create"
|
|
176
|
+
{...detailProps}
|
|
177
|
+
/>
|
|
178
|
+
),
|
|
179
|
+
].filter(Boolean),
|
|
176
180
|
[actions, createButton, detailProps, handleReload, tableProps],
|
|
177
181
|
);
|
|
178
182
|
|
|
@@ -181,11 +185,12 @@ function CRUDComponent<
|
|
|
181
185
|
Key
|
|
182
186
|
>({
|
|
183
187
|
batchActions,
|
|
188
|
+
actionRef,
|
|
184
189
|
});
|
|
185
190
|
|
|
186
191
|
return (
|
|
187
192
|
<div className="crud-table">
|
|
188
|
-
<Table
|
|
193
|
+
<Table<DataSource>
|
|
189
194
|
rowKey="id"
|
|
190
195
|
{...tableProps}
|
|
191
196
|
actionRef={actionRef}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { ProFormText } from '@ant-design/pro-components';
|
|
2
|
+
import { CRUDOfSimple } from '@fe-free/core';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
import { fakeCreate, fakeDeleteByRecord, fakeRequest } from './demo/data';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof CRUDOfSimple> = {
|
|
7
|
+
title: '@fe-free/core/CRUDOfSimple',
|
|
8
|
+
component: CRUDOfSimple,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
type Story = StoryObj<typeof CRUDOfSimple>;
|
|
14
|
+
|
|
15
|
+
// 基础用法
|
|
16
|
+
export const Normal: Story = {
|
|
17
|
+
render: () => {
|
|
18
|
+
const columns = [
|
|
19
|
+
{
|
|
20
|
+
title: 'id',
|
|
21
|
+
dataIndex: 'id',
|
|
22
|
+
search: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: '名字(省略)',
|
|
26
|
+
dataIndex: 'name',
|
|
27
|
+
search: true,
|
|
28
|
+
ellipsis: true,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<CRUDOfSimple
|
|
34
|
+
actions={['create', 'delete']}
|
|
35
|
+
tableProps={{
|
|
36
|
+
columns,
|
|
37
|
+
request: fakeRequest,
|
|
38
|
+
pagination: false,
|
|
39
|
+
}}
|
|
40
|
+
requestDeleteByRecord={fakeDeleteByRecord}
|
|
41
|
+
deleteProps={{
|
|
42
|
+
nameIndex: 'name',
|
|
43
|
+
}}
|
|
44
|
+
detailForm={(formProps) => (
|
|
45
|
+
<>
|
|
46
|
+
<ProFormText
|
|
47
|
+
{...formProps}
|
|
48
|
+
name="name"
|
|
49
|
+
label="名字"
|
|
50
|
+
required
|
|
51
|
+
rules={[{ required: true }]}
|
|
52
|
+
extra="extra extra extra extra"
|
|
53
|
+
/>
|
|
54
|
+
</>
|
|
55
|
+
)}
|
|
56
|
+
requestCreateByValues={fakeCreate}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const WithSearch: Story = {
|
|
63
|
+
render: () => {
|
|
64
|
+
const columns = [
|
|
65
|
+
{
|
|
66
|
+
title: 'id',
|
|
67
|
+
dataIndex: 'id',
|
|
68
|
+
search: true,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
title: '名字(省略)',
|
|
72
|
+
dataIndex: 'name',
|
|
73
|
+
search: true,
|
|
74
|
+
ellipsis: true,
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<CRUDOfSimple
|
|
80
|
+
actions={['create', 'delete']}
|
|
81
|
+
tableProps={{
|
|
82
|
+
columns,
|
|
83
|
+
request: fakeRequest,
|
|
84
|
+
pagination: false,
|
|
85
|
+
}}
|
|
86
|
+
requestDeleteByRecord={fakeDeleteByRecord}
|
|
87
|
+
deleteProps={{
|
|
88
|
+
nameIndex: 'name',
|
|
89
|
+
}}
|
|
90
|
+
detailForm={(formProps) => (
|
|
91
|
+
<>
|
|
92
|
+
<ProFormText
|
|
93
|
+
{...formProps}
|
|
94
|
+
name="name"
|
|
95
|
+
label="名字"
|
|
96
|
+
required
|
|
97
|
+
rules={[{ required: true }]}
|
|
98
|
+
extra="extra extra extra extra"
|
|
99
|
+
/>
|
|
100
|
+
</>
|
|
101
|
+
)}
|
|
102
|
+
requestCreateByValues={fakeCreate}
|
|
103
|
+
simpleSearchProps={{
|
|
104
|
+
name: 'id',
|
|
105
|
+
}}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { useDebounce } from 'ahooks';
|
|
2
|
+
import { Input } from 'antd';
|
|
3
|
+
import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { CRUD } from './crud';
|
|
5
|
+
import type { CRUDMethods, CRUDProps } from './types';
|
|
6
|
+
|
|
7
|
+
interface CRUDOfSimpleProps<
|
|
8
|
+
DataSource extends Record<string, any> = any,
|
|
9
|
+
Key extends string | number = string,
|
|
10
|
+
> extends CRUDProps<DataSource, Key> {
|
|
11
|
+
// 传才开启搜索
|
|
12
|
+
simpleSearchProps?: {
|
|
13
|
+
/** 搜索项的名称,默认 keywords */
|
|
14
|
+
name: string;
|
|
15
|
+
/** 搜索项的 placeholder,默认 请输入 */
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function useTips(props) {
|
|
21
|
+
const { columns } = props;
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const hasSearchColumn = columns?.find((column) => column.search);
|
|
25
|
+
if (hasSearchColumn) {
|
|
26
|
+
console.warn('CRUDOfSimple 的 columns 中不能有 search 为 true 的列');
|
|
27
|
+
}
|
|
28
|
+
}, []);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function SearchRender(props: {
|
|
32
|
+
placeholder?: string;
|
|
33
|
+
value?: string;
|
|
34
|
+
onChange: (value: string) => void;
|
|
35
|
+
}) {
|
|
36
|
+
return (
|
|
37
|
+
<Input
|
|
38
|
+
placeholder={props.placeholder ?? '输入搜索'}
|
|
39
|
+
allowClear
|
|
40
|
+
value={props.value}
|
|
41
|
+
onChange={(e) => props.onChange(e.target.value)}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function CRUDOfSimpleComponent(props: CRUDOfSimpleProps, ref: React.ForwardedRef<CRUDMethods>) {
|
|
47
|
+
const { simpleSearchProps, tableProps, ...rest } = props;
|
|
48
|
+
|
|
49
|
+
useTips(props);
|
|
50
|
+
const [searchValue, setSearchValue] = useState<string>('');
|
|
51
|
+
|
|
52
|
+
const debouncedSearchValue = useDebounce(searchValue, { wait: 300 });
|
|
53
|
+
|
|
54
|
+
const newColumns = useMemo(() => {
|
|
55
|
+
return (tableProps.columns || []).map((column) => ({
|
|
56
|
+
...column,
|
|
57
|
+
search: false,
|
|
58
|
+
}));
|
|
59
|
+
}, [tableProps.columns]);
|
|
60
|
+
|
|
61
|
+
const toolBarRender = useCallback(
|
|
62
|
+
(...args) => {
|
|
63
|
+
return [
|
|
64
|
+
<div key="search">
|
|
65
|
+
{simpleSearchProps && (
|
|
66
|
+
<SearchRender
|
|
67
|
+
placeholder={simpleSearchProps.placeholder}
|
|
68
|
+
value={searchValue}
|
|
69
|
+
onChange={(value) => setSearchValue(value)}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
72
|
+
</div>,
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
...(tableProps.toolBarRender ? tableProps.toolBarRender(...args) : []),
|
|
75
|
+
];
|
|
76
|
+
},
|
|
77
|
+
[searchValue, simpleSearchProps, tableProps],
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const newParams = useMemo(() => {
|
|
81
|
+
if (!simpleSearchProps) {
|
|
82
|
+
return tableProps.params;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
...tableProps.params,
|
|
87
|
+
[simpleSearchProps.name]: debouncedSearchValue,
|
|
88
|
+
};
|
|
89
|
+
}, [debouncedSearchValue, simpleSearchProps, tableProps.params]);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div className="crud-of-simple">
|
|
93
|
+
<CRUD
|
|
94
|
+
ref={ref}
|
|
95
|
+
{...rest}
|
|
96
|
+
tableProps={{
|
|
97
|
+
...tableProps,
|
|
98
|
+
params: newParams,
|
|
99
|
+
cardBordered: false,
|
|
100
|
+
showHeader: false,
|
|
101
|
+
ghost: true,
|
|
102
|
+
columns: newColumns,
|
|
103
|
+
toolBarRender,
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const CRUDOfSimple = forwardRef(CRUDOfSimpleComponent) as <
|
|
111
|
+
DataSource extends Record<string, any> = any,
|
|
112
|
+
Key extends string | number = string,
|
|
113
|
+
>(
|
|
114
|
+
props: CRUDOfSimpleProps<DataSource, Key> & { ref?: React.ForwardedRef<CRUDMethods> },
|
|
115
|
+
) => JSX.Element;
|
|
116
|
+
|
|
117
|
+
export { CRUDOfSimple };
|
|
118
|
+
export type { CRUDOfSimpleProps };
|
package/src/crud/demo/data.tsx
CHANGED
|
@@ -58,12 +58,24 @@ let fakeData = makeData(21);
|
|
|
58
58
|
async function fakeRequest(params) {
|
|
59
59
|
console.log('fakeRequest', params);
|
|
60
60
|
|
|
61
|
+
let data = fakeData;
|
|
62
|
+
Object.keys(params).forEach((field) => {
|
|
63
|
+
if (params[field] !== undefined && params[field] !== '') {
|
|
64
|
+
data = data.filter((item) => {
|
|
65
|
+
if (typeof item[field] === 'string') {
|
|
66
|
+
return item[field].includes(params[field]);
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
61
73
|
return new Promise((resolve) => {
|
|
62
74
|
setTimeout(() => {
|
|
63
75
|
resolve({
|
|
64
|
-
data
|
|
76
|
+
data,
|
|
65
77
|
success: true,
|
|
66
|
-
total:
|
|
78
|
+
total: data.length,
|
|
67
79
|
});
|
|
68
80
|
}, 1000);
|
|
69
81
|
}) as Promise<any>;
|
package/src/crud/index.tsx
CHANGED
|
@@ -2,4 +2,6 @@ export { CRUD } from './crud';
|
|
|
2
2
|
export { OperateDelete, useDelete } from './crud_delete';
|
|
3
3
|
export { CRUDDetail } from './crud_detail';
|
|
4
4
|
export type { CRUDDetailProps } from './crud_detail';
|
|
5
|
+
export { CRUDOfSimple } from './crud_of_simple';
|
|
6
|
+
export type { CRUDOfSimpleProps } from './crud_of_simple';
|
|
5
7
|
export type { CRUDMethods, CRUDProps } from './types';
|
package/src/crud/types.tsx
CHANGED
|
@@ -11,17 +11,33 @@ import type { TableProps } from '../table';
|
|
|
11
11
|
*/
|
|
12
12
|
type CrudAction = 'create' | 'read' | 'read_detail' | 'update' | 'delete';
|
|
13
13
|
|
|
14
|
-
interface CRUDProps<
|
|
15
|
-
DataSource extends Record<string, any> = any,
|
|
16
|
-
Key extends string | number = string,
|
|
17
|
-
> {
|
|
14
|
+
interface CRUDProps<DataSource = any, Key = string> {
|
|
18
15
|
actions: CrudAction[];
|
|
19
16
|
|
|
17
|
+
// *** 表单 ***
|
|
18
|
+
|
|
19
|
+
/** 弹窗表单 */
|
|
20
|
+
detailForm?: (formProps: { readonly: boolean }, info: { action: CrudAction }) => ReactNode;
|
|
21
|
+
/** detailForm 的 formRef */
|
|
22
|
+
detailFormInstance?: ProFormInstance;
|
|
23
|
+
|
|
24
|
+
// *** Create 新建 ***
|
|
25
|
+
|
|
26
|
+
/** 新增接口 */
|
|
27
|
+
requestCreateByValues?: (values: Partial<DataSource>) => Promise<any>;
|
|
20
28
|
/** 新建按钮,默认新建 */
|
|
21
29
|
createButton?: ReactNode;
|
|
30
|
+
/** create 更多设置 */
|
|
31
|
+
createProps?: {
|
|
32
|
+
/** 成功文案 */
|
|
33
|
+
successText?: string | (() => string);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// *** Read 表格 ***
|
|
22
37
|
|
|
23
38
|
/** 表格相关 */
|
|
24
39
|
tableProps: TableProps<DataSource>;
|
|
40
|
+
/** 表格操作列相关 */
|
|
25
41
|
operateColumnProps?: {
|
|
26
42
|
width?: number;
|
|
27
43
|
/** 扩展操作区域,再其他操作之前 */
|
|
@@ -29,6 +45,14 @@ interface CRUDProps<
|
|
|
29
45
|
/** 扩展操作区域,在其他操作之后 */
|
|
30
46
|
moreOperatorAfter?: (record: DataSource) => ReactNode;
|
|
31
47
|
};
|
|
48
|
+
|
|
49
|
+
// *** Read 详情 ***
|
|
50
|
+
|
|
51
|
+
/** 获取详情接口 */
|
|
52
|
+
requestGetByRecord?: (record: DataSource) => Promise<any>;
|
|
53
|
+
/** 跳转到详情的索引 ,默认 id */
|
|
54
|
+
detailIdIndex?: string;
|
|
55
|
+
/** read 更多设置 */
|
|
32
56
|
readProps?: {
|
|
33
57
|
/** 文本 */
|
|
34
58
|
operateText?: string;
|
|
@@ -36,29 +60,7 @@ interface CRUDProps<
|
|
|
36
60
|
target?: '_blank';
|
|
37
61
|
};
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
requestDeleteByRecord?: (record: DataSource) => Promise<any>;
|
|
41
|
-
/** 删除相关 */
|
|
42
|
-
deleteProps?: {
|
|
43
|
-
/** 显示名称索引 */
|
|
44
|
-
nameIndex: keyof DataSource;
|
|
45
|
-
/** 删除确认描述 */
|
|
46
|
-
desc?: string;
|
|
47
|
-
/** 文本 */
|
|
48
|
-
operateText?: string;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
/** 弹窗表单 */
|
|
52
|
-
detailForm?: (formProps: { readonly: boolean }, info: { action: CrudAction }) => ReactNode;
|
|
53
|
-
/** detailForm 的 formRef */
|
|
54
|
-
detailFormInstance?: ProFormInstance;
|
|
55
|
-
|
|
56
|
-
/** 新增接口 */
|
|
57
|
-
requestCreateByValues?: (values: Partial<DataSource>) => Promise<any>;
|
|
58
|
-
createProps?: {
|
|
59
|
-
/** 成功文案 */
|
|
60
|
-
successText?: string | (() => string);
|
|
61
|
-
};
|
|
63
|
+
// *** Update 更新 ***
|
|
62
64
|
|
|
63
65
|
/** 更新接口 */
|
|
64
66
|
requestUpdateByValues?: (values: Partial<DataSource>) => Promise<any>;
|
|
@@ -71,11 +73,21 @@ interface CRUDProps<
|
|
|
71
73
|
successText?: string | (() => string);
|
|
72
74
|
};
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
requestGetByRecord?: (record: DataSource) => Promise<any>;
|
|
76
|
+
// *** Delete 删除 ***
|
|
76
77
|
|
|
77
|
-
/**
|
|
78
|
-
|
|
78
|
+
/** 删除接口 */
|
|
79
|
+
requestDeleteByRecord?: (record: DataSource) => Promise<any>;
|
|
80
|
+
/** 删除相关 */
|
|
81
|
+
deleteProps?: {
|
|
82
|
+
/** 显示名称索引 */
|
|
83
|
+
nameIndex: keyof DataSource;
|
|
84
|
+
/** 删除确认描述 */
|
|
85
|
+
desc?: string;
|
|
86
|
+
/** 文本 */
|
|
87
|
+
operateText?: string;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// *** 批量操作 ***
|
|
79
91
|
|
|
80
92
|
/** 批量操作 */
|
|
81
93
|
batchActions?: {
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import type { ActionType } from '@ant-design/pro-components';
|
|
1
2
|
import { Modal } from 'antd';
|
|
3
|
+
import type { MutableRefObject } from 'react';
|
|
2
4
|
import { useCallback, useMemo } from 'react';
|
|
3
5
|
import { LoadingButton } from '../button';
|
|
4
6
|
import type { CRUDProps } from './types';
|
|
5
7
|
|
|
6
|
-
function useRowSelection<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
function useRowSelection<DataSource, Key>({
|
|
9
|
+
batchActions,
|
|
10
|
+
actionRef,
|
|
11
|
+
}: {
|
|
12
|
+
batchActions?: CRUDProps<DataSource, Key>['batchActions'];
|
|
13
|
+
actionRef?: MutableRefObject<ActionType | undefined>;
|
|
14
|
+
}) {
|
|
10
15
|
const rowSelection = useMemo(() => ({}), []);
|
|
11
16
|
|
|
12
17
|
const tableAlertRender = useCallback(({ selectedRowKeys, onCleanSelected }) => {
|
|
@@ -55,6 +60,8 @@ function useRowSelection<
|
|
|
55
60
|
selectedRows,
|
|
56
61
|
});
|
|
57
62
|
}
|
|
63
|
+
|
|
64
|
+
actionRef?.current?.reload();
|
|
58
65
|
}}
|
|
59
66
|
>
|
|
60
67
|
{action.btnText}
|
|
@@ -63,7 +70,7 @@ function useRowSelection<
|
|
|
63
70
|
</div>
|
|
64
71
|
);
|
|
65
72
|
},
|
|
66
|
-
[batchActions],
|
|
73
|
+
[actionRef, batchActions],
|
|
67
74
|
);
|
|
68
75
|
|
|
69
76
|
if (!batchActions || batchActions.length === 0) {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import type { CRUDProps } from './types';
|
|
3
|
+
|
|
4
|
+
function useTips<DataSource, Key>(props: CRUDProps<DataSource, Key>) {
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (props.actions.includes('create')) {
|
|
7
|
+
if (!props.requestCreateByValues) {
|
|
8
|
+
console.warn('actions 包含 create 时,需要传递 requestCreateByValues');
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (props.actions.includes('read')) {
|
|
13
|
+
if (!props.requestGetByRecord) {
|
|
14
|
+
console.warn('actions 包含 read 时,需要传递 requestGetByRecord');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (props.actions.includes('update')) {
|
|
19
|
+
if (!props.requestGetByRecord || !props.requestUpdateByValues) {
|
|
20
|
+
console.warn(
|
|
21
|
+
'actions 包含 update 时,需要传递 requestGetByRecord 和 requestUpdateByValues',
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (props.actions.includes('delete')) {
|
|
27
|
+
if (!props.deleteProps?.nameIndex || !props.requestDeleteByRecord) {
|
|
28
|
+
console.warn('actions 包含 delete 时,需要传递 deleteProps 和 requestDeleteByRecord');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}, []);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { useTips };
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { LoadingButton } from './button';
|
|
2
2
|
|
|
3
|
-
export { CRUD, CRUDDetail, OperateDelete, useDelete } from './crud';
|
|
4
|
-
export type { CRUDDetailProps, CRUDMethods, CRUDProps } from './crud';
|
|
3
|
+
export { CRUD, CRUDDetail, CRUDOfSimple, OperateDelete, useDelete } from './crud';
|
|
4
|
+
export type { CRUDDetailProps, CRUDMethods, CRUDOfSimpleProps, CRUDProps } from './crud';
|
|
5
5
|
|
|
6
6
|
export { EditorJavascript } from './editor_javascript';
|
|
7
7
|
export type { EditorJavascriptProps } from './editor_javascript';
|