@fe-free/core 2.5.4 → 2.5.5
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 +7 -0
- package/package.json +2 -2
- package/src/crud/index.tsx +0 -2
- package/src/crud/style.scss +0 -36
- package/src/{crud/crud_of_simple.stories.tsx → crud_of_list/crud_of_list.stories.tsx} +34 -61
- package/src/{crud/crud_of_simple.tsx → crud_of_list/index.tsx} +42 -51
- package/src/crud_of_list/style.scss +37 -0
- package/src/index.ts +4 -2
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/core",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"author": "",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"remark-gfm": "^4.0.1",
|
|
42
42
|
"vanilla-jsoneditor": "^0.23.1",
|
|
43
43
|
"zustand": "^4.5.4",
|
|
44
|
-
"@fe-free/tool": "2.5.
|
|
44
|
+
"@fe-free/tool": "2.5.5"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@ant-design/pro-components": "2.8.9",
|
package/src/crud/index.tsx
CHANGED
|
@@ -2,6 +2,4 @@ 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';
|
|
7
5
|
export type { CRUDMethods, CRUDProps } from './types';
|
package/src/crud/style.scss
CHANGED
|
@@ -8,39 +8,3 @@
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
.fec-crud-of-simple {
|
|
13
|
-
.ant-pro-table-list-toolbar {
|
|
14
|
-
border-bottom: 1px solid #f0f0f0;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
&.fec-crud-of-simple-hover-show {
|
|
18
|
-
.ant-table-cell-fix-right {
|
|
19
|
-
position: absolute !important;
|
|
20
|
-
display: none;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.ant-table-row {
|
|
24
|
-
&:hover {
|
|
25
|
-
.ant-table-cell-fix-right {
|
|
26
|
-
display: block;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
&.fec-crud-of-simple-search-width-full {
|
|
33
|
-
.ant-pro-table-list-toolbar-container {
|
|
34
|
-
justify-content: unset;
|
|
35
|
-
|
|
36
|
-
.ant-pro-table-list-toolbar-right {
|
|
37
|
-
justify-content: unset;
|
|
38
|
-
|
|
39
|
-
& > div {
|
|
40
|
-
flex: 1;
|
|
41
|
-
margin-right: 8px;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
import { ProFormText } from '@ant-design/pro-components';
|
|
2
|
-
import {
|
|
2
|
+
import { CRUDOfList } from '@fe-free/core';
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
-
import { fakeCreate, fakeDeleteByRecord, fakeRequest } from '
|
|
4
|
+
import { fakeCreate, fakeDeleteByRecord, fakeRequest } from '../crud/demo/data';
|
|
5
5
|
|
|
6
|
-
const meta: Meta<typeof
|
|
7
|
-
title: '@fe-free/core/
|
|
8
|
-
component:
|
|
6
|
+
const meta: Meta<typeof CRUDOfList> = {
|
|
7
|
+
title: '@fe-free/core/CRUDOfList',
|
|
8
|
+
component: CRUDOfList,
|
|
9
9
|
tags: ['autodocs'],
|
|
10
|
+
parameters: {
|
|
11
|
+
docs: {
|
|
12
|
+
description: {
|
|
13
|
+
component: `
|
|
14
|
+
CRUDOfList 组件。(简洁的列表形态的 CRUD 组件)
|
|
15
|
+
- 隐藏 label
|
|
16
|
+
- 搜索表单按钮一行
|
|
17
|
+
- 移除卡片布局
|
|
18
|
+
`,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
10
22
|
decorators: [
|
|
11
23
|
(Story) => {
|
|
12
24
|
return (
|
|
13
|
-
<div className="c-border h-[500px] w-[300px] overflow-
|
|
25
|
+
<div className="c-border h-[500px] w-[300px] overflow-y-auto">
|
|
14
26
|
<Story />
|
|
15
27
|
</div>
|
|
16
28
|
);
|
|
@@ -19,27 +31,25 @@ const meta: Meta<typeof CRUDOfSimple> = {
|
|
|
19
31
|
};
|
|
20
32
|
|
|
21
33
|
export default meta;
|
|
22
|
-
type Story = StoryObj<typeof
|
|
34
|
+
type Story = StoryObj<typeof CRUDOfList>;
|
|
23
35
|
|
|
24
|
-
|
|
25
|
-
export const Normal: Story = {
|
|
36
|
+
export const Basic: Story = {
|
|
26
37
|
render: () => {
|
|
27
38
|
const columns = [
|
|
28
39
|
{
|
|
29
40
|
title: '名字(省略)',
|
|
30
41
|
dataIndex: 'name',
|
|
31
|
-
search: true,
|
|
42
|
+
// search: true,
|
|
32
43
|
ellipsis: true,
|
|
33
44
|
},
|
|
34
45
|
];
|
|
35
46
|
|
|
36
47
|
return (
|
|
37
|
-
<
|
|
38
|
-
actions={[
|
|
48
|
+
<CRUDOfList
|
|
49
|
+
actions={[]}
|
|
39
50
|
tableProps={{
|
|
40
51
|
columns,
|
|
41
52
|
request: fakeRequest,
|
|
42
|
-
pagination: false,
|
|
43
53
|
}}
|
|
44
54
|
requestDeleteByRecord={fakeDeleteByRecord}
|
|
45
55
|
deleteProps={{
|
|
@@ -47,13 +57,7 @@ export const Normal: Story = {
|
|
|
47
57
|
}}
|
|
48
58
|
detailForm={() => (
|
|
49
59
|
<>
|
|
50
|
-
<ProFormText
|
|
51
|
-
name="name"
|
|
52
|
-
label="名字"
|
|
53
|
-
required
|
|
54
|
-
rules={[{ required: true }]}
|
|
55
|
-
extra="extra extra extra extra"
|
|
56
|
-
/>
|
|
60
|
+
<ProFormText name="name" label="名字" required rules={[{ required: true }]} />
|
|
57
61
|
</>
|
|
58
62
|
)}
|
|
59
63
|
requestCreateByValues={fakeCreate}
|
|
@@ -74,12 +78,11 @@ export const WithSearch: Story = {
|
|
|
74
78
|
];
|
|
75
79
|
|
|
76
80
|
return (
|
|
77
|
-
<
|
|
78
|
-
actions={['
|
|
81
|
+
<CRUDOfList
|
|
82
|
+
actions={['delete']}
|
|
79
83
|
tableProps={{
|
|
80
84
|
columns,
|
|
81
85
|
request: fakeRequest,
|
|
82
|
-
pagination: false,
|
|
83
86
|
}}
|
|
84
87
|
requestDeleteByRecord={fakeDeleteByRecord}
|
|
85
88
|
deleteProps={{
|
|
@@ -87,26 +90,16 @@ export const WithSearch: Story = {
|
|
|
87
90
|
}}
|
|
88
91
|
detailForm={() => (
|
|
89
92
|
<>
|
|
90
|
-
<ProFormText
|
|
91
|
-
name="name"
|
|
92
|
-
label="名字"
|
|
93
|
-
required
|
|
94
|
-
rules={[{ required: true }]}
|
|
95
|
-
extra="extra extra extra extra"
|
|
96
|
-
/>
|
|
93
|
+
<ProFormText name="name" label="名字" required rules={[{ required: true }]} />
|
|
97
94
|
</>
|
|
98
95
|
)}
|
|
99
96
|
requestCreateByValues={fakeCreate}
|
|
100
|
-
simpleSearchProps={{
|
|
101
|
-
name: 'name',
|
|
102
|
-
widthFull: true,
|
|
103
|
-
}}
|
|
104
97
|
/>
|
|
105
98
|
);
|
|
106
99
|
},
|
|
107
100
|
};
|
|
108
101
|
|
|
109
|
-
export const
|
|
102
|
+
export const WithCreateDelete: Story = {
|
|
110
103
|
render: () => {
|
|
111
104
|
const columns = [
|
|
112
105
|
{
|
|
@@ -118,12 +111,11 @@ export const HoverShow: Story = {
|
|
|
118
111
|
];
|
|
119
112
|
|
|
120
113
|
return (
|
|
121
|
-
<
|
|
114
|
+
<CRUDOfList
|
|
122
115
|
actions={['create', 'delete']}
|
|
123
116
|
tableProps={{
|
|
124
117
|
columns,
|
|
125
118
|
request: fakeRequest,
|
|
126
|
-
pagination: false,
|
|
127
119
|
}}
|
|
128
120
|
requestDeleteByRecord={fakeDeleteByRecord}
|
|
129
121
|
deleteProps={{
|
|
@@ -131,40 +123,31 @@ export const HoverShow: Story = {
|
|
|
131
123
|
}}
|
|
132
124
|
detailForm={() => (
|
|
133
125
|
<>
|
|
134
|
-
<ProFormText
|
|
135
|
-
name="name"
|
|
136
|
-
label="名字"
|
|
137
|
-
required
|
|
138
|
-
rules={[{ required: true }]}
|
|
139
|
-
extra="extra extra extra extra"
|
|
140
|
-
/>
|
|
126
|
+
<ProFormText name="name" label="名字" required rules={[{ required: true }]} />
|
|
141
127
|
</>
|
|
142
128
|
)}
|
|
143
129
|
requestCreateByValues={fakeCreate}
|
|
144
|
-
simpleOperateHoverShow
|
|
145
130
|
/>
|
|
146
131
|
);
|
|
147
132
|
},
|
|
148
133
|
};
|
|
149
134
|
|
|
150
|
-
export const
|
|
135
|
+
export const NoSearch: Story = {
|
|
151
136
|
render: () => {
|
|
152
137
|
const columns = [
|
|
153
138
|
{
|
|
154
139
|
title: '名字(省略)',
|
|
155
140
|
dataIndex: 'name',
|
|
156
|
-
search: true,
|
|
157
141
|
ellipsis: true,
|
|
158
142
|
},
|
|
159
143
|
];
|
|
160
144
|
|
|
161
145
|
return (
|
|
162
|
-
<
|
|
163
|
-
actions={['delete']}
|
|
146
|
+
<CRUDOfList
|
|
147
|
+
actions={['create', 'delete']}
|
|
164
148
|
tableProps={{
|
|
165
149
|
columns,
|
|
166
150
|
request: fakeRequest,
|
|
167
|
-
pagination: false,
|
|
168
151
|
}}
|
|
169
152
|
requestDeleteByRecord={fakeDeleteByRecord}
|
|
170
153
|
deleteProps={{
|
|
@@ -172,20 +155,10 @@ export const JustSearch: Story = {
|
|
|
172
155
|
}}
|
|
173
156
|
detailForm={() => (
|
|
174
157
|
<>
|
|
175
|
-
<ProFormText
|
|
176
|
-
name="name"
|
|
177
|
-
label="名字"
|
|
178
|
-
required
|
|
179
|
-
rules={[{ required: true }]}
|
|
180
|
-
extra="extra extra extra extra"
|
|
181
|
-
/>
|
|
158
|
+
<ProFormText name="name" label="名字" required rules={[{ required: true }]} />
|
|
182
159
|
</>
|
|
183
160
|
)}
|
|
184
161
|
requestCreateByValues={fakeCreate}
|
|
185
|
-
simpleSearchProps={{
|
|
186
|
-
name: 'name',
|
|
187
|
-
widthFull: true,
|
|
188
|
-
}}
|
|
189
162
|
/>
|
|
190
163
|
);
|
|
191
164
|
},
|
|
@@ -2,32 +2,26 @@ import { useDebounce } from 'ahooks';
|
|
|
2
2
|
import { Input } from 'antd';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import { forwardRef, useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
5
|
+
import type { CRUDMethods, CRUDProps } from '../crud';
|
|
6
|
+
import { CRUD } from '../crud';
|
|
7
|
+
import './style.scss';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
10
|
+
interface CRUDOfListProps<
|
|
9
11
|
DataSource extends Record<string, any> = any,
|
|
10
12
|
Key extends string | number = string,
|
|
11
13
|
> extends CRUDProps<DataSource, Key> {
|
|
12
|
-
|
|
13
|
-
// 传才开启搜索
|
|
14
|
-
simpleSearchProps?: {
|
|
15
|
-
/** 搜索项的名称,默认 keywords */
|
|
16
|
-
name: string;
|
|
17
|
-
/** 搜索项的 placeholder,默认 请输入 */
|
|
18
|
-
placeholder?: string;
|
|
19
|
-
/** 占满宽度 */
|
|
20
|
-
widthFull?: boolean;
|
|
21
|
-
};
|
|
14
|
+
// nothing
|
|
22
15
|
}
|
|
23
16
|
|
|
24
17
|
function useTips(props) {
|
|
25
|
-
const { columns } = props;
|
|
26
|
-
|
|
27
18
|
useEffect(() => {
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
console.warn('
|
|
19
|
+
const count = props.tableProps.columns?.filter((column) => column.search).length;
|
|
20
|
+
if (!count) {
|
|
21
|
+
console.warn('CRUDOfList 的 columns 中至少有一个 search 为 true 的列');
|
|
22
|
+
}
|
|
23
|
+
if (count > 1) {
|
|
24
|
+
console.warn('CRUDOfList 的 columns 中只能有一个 search 为 true 的列');
|
|
31
25
|
}
|
|
32
26
|
}, []);
|
|
33
27
|
}
|
|
@@ -48,14 +42,18 @@ function SearchRender(props: {
|
|
|
48
42
|
);
|
|
49
43
|
}
|
|
50
44
|
|
|
51
|
-
function
|
|
52
|
-
const { simpleSearchProps, tableProps, simpleOperateHoverShow, ...rest } = props;
|
|
53
|
-
|
|
45
|
+
function CRUDOfListComponent(props: CRUDOfListProps, ref: React.ForwardedRef<CRUDMethods>) {
|
|
54
46
|
useTips(props);
|
|
55
|
-
const [searchValue, setSearchValue] = useState<string>('');
|
|
56
47
|
|
|
48
|
+
const { tableProps, ...rest } = props;
|
|
49
|
+
|
|
50
|
+
const [searchValue, setSearchValue] = useState<string>('');
|
|
57
51
|
const debouncedSearchValue = useDebounce(searchValue, { wait: 300 });
|
|
58
52
|
|
|
53
|
+
const searchDataIndex = useMemo(() => {
|
|
54
|
+
return tableProps.columns?.find((column) => column.search)?.dataIndex;
|
|
55
|
+
}, [tableProps.columns]);
|
|
56
|
+
|
|
59
57
|
const newColumns = useMemo(() => {
|
|
60
58
|
return (tableProps.columns || []).map((column) => ({
|
|
61
59
|
...column,
|
|
@@ -66,56 +64,49 @@ function CRUDOfSimpleComponent(props: CRUDOfSimpleProps, ref: React.ForwardedRef
|
|
|
66
64
|
const toolBarRender = useCallback(
|
|
67
65
|
(...args) => {
|
|
68
66
|
return [
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
onChange={(value) => setSearchValue(value)}
|
|
75
|
-
/>
|
|
76
|
-
),
|
|
67
|
+
<div key="search-input-container" className="w-full">
|
|
68
|
+
{searchDataIndex && (
|
|
69
|
+
<SearchRender value={searchValue} onChange={(value) => setSearchValue(value)} />
|
|
70
|
+
)}
|
|
71
|
+
</div>,
|
|
77
72
|
// @ts-ignore
|
|
78
73
|
...(tableProps.toolBarRender ? tableProps.toolBarRender(...args) : []),
|
|
79
74
|
];
|
|
80
75
|
},
|
|
81
|
-
[searchValue,
|
|
76
|
+
[searchValue, searchDataIndex, tableProps],
|
|
82
77
|
);
|
|
83
78
|
|
|
84
79
|
const newParams = useMemo(() => {
|
|
85
|
-
if (!simpleSearchProps) {
|
|
86
|
-
return tableProps.params;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
80
|
return {
|
|
90
|
-
...tableProps.params,
|
|
91
|
-
[
|
|
81
|
+
...(tableProps.params || {}),
|
|
82
|
+
[searchDataIndex]: debouncedSearchValue,
|
|
92
83
|
};
|
|
93
|
-
}, [debouncedSearchValue,
|
|
84
|
+
}, [debouncedSearchValue, searchDataIndex, tableProps.params]);
|
|
94
85
|
|
|
95
86
|
return (
|
|
96
87
|
<div
|
|
97
|
-
className={classNames('fec-crud-of-
|
|
98
|
-
|
|
99
|
-
'fec-crud-of-
|
|
88
|
+
className={classNames('fec-crud-of-list', {
|
|
89
|
+
// 先这样实现
|
|
90
|
+
'fec-crud-of-list-no-toolbar': !searchDataIndex && !props.actions.includes('create'),
|
|
100
91
|
})}
|
|
101
92
|
>
|
|
102
93
|
<CRUD
|
|
103
94
|
ref={ref}
|
|
104
95
|
{...rest}
|
|
105
96
|
tableProps={{
|
|
106
|
-
...tableProps,
|
|
107
|
-
params: newParams,
|
|
108
97
|
cardBordered: false,
|
|
109
98
|
showHeader: false,
|
|
110
99
|
ghost: true,
|
|
111
|
-
columns: newColumns,
|
|
112
|
-
toolBarRender,
|
|
113
100
|
// 简单的隐藏搜索栏
|
|
114
101
|
search: false,
|
|
102
|
+
pagination: false,
|
|
103
|
+
...tableProps,
|
|
104
|
+
params: newParams,
|
|
105
|
+
columns: newColumns,
|
|
106
|
+
toolBarRender,
|
|
115
107
|
}}
|
|
116
108
|
operateColumnProps={{
|
|
117
|
-
|
|
118
|
-
width: simpleOperateHoverShow ? 1 : undefined,
|
|
109
|
+
width: 1,
|
|
119
110
|
...props.operateColumnProps,
|
|
120
111
|
}}
|
|
121
112
|
/>
|
|
@@ -123,12 +114,12 @@ function CRUDOfSimpleComponent(props: CRUDOfSimpleProps, ref: React.ForwardedRef
|
|
|
123
114
|
);
|
|
124
115
|
}
|
|
125
116
|
|
|
126
|
-
const
|
|
117
|
+
const CRUDOfList = forwardRef(CRUDOfListComponent) as <
|
|
127
118
|
DataSource extends Record<string, any> = any,
|
|
128
119
|
Key extends string | number = string,
|
|
129
120
|
>(
|
|
130
|
-
props:
|
|
121
|
+
props: CRUDOfListProps<DataSource, Key> & { ref?: React.ForwardedRef<CRUDMethods> },
|
|
131
122
|
) => JSX.Element;
|
|
132
123
|
|
|
133
|
-
export {
|
|
134
|
-
export type {
|
|
124
|
+
export { CRUDOfList };
|
|
125
|
+
export type { CRUDOfListProps };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
.fec-crud-of-list {
|
|
2
|
+
.ant-pro-table-list-toolbar {
|
|
3
|
+
border-bottom: 1px solid #f0f0f0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.ant-table-cell-fix-right {
|
|
7
|
+
position: absolute !important;
|
|
8
|
+
display: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.ant-table-row {
|
|
12
|
+
&:hover {
|
|
13
|
+
.ant-table-cell-fix-right {
|
|
14
|
+
display: block;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.ant-pro-table-list-toolbar-container {
|
|
20
|
+
justify-content: unset;
|
|
21
|
+
|
|
22
|
+
.ant-pro-table-list-toolbar-right {
|
|
23
|
+
justify-content: unset;
|
|
24
|
+
|
|
25
|
+
& > div {
|
|
26
|
+
flex: 1;
|
|
27
|
+
margin-right: 8px;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.fec-crud-of-list-no-toolbar {
|
|
33
|
+
.ant-pro-table-list-toolbar-container {
|
|
34
|
+
padding-block: 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -6,8 +6,10 @@ export { LoadingButton } from './button';
|
|
|
6
6
|
export { Copy } from './copy';
|
|
7
7
|
export type { CopyProps } from './copy';
|
|
8
8
|
export { CoreApp } from './core_app';
|
|
9
|
-
export { CRUD, CRUDDetail,
|
|
10
|
-
export type { CRUDDetailProps, CRUDMethods,
|
|
9
|
+
export { CRUD, CRUDDetail, OperateDelete, useDelete } from './crud';
|
|
10
|
+
export type { CRUDDetailProps, CRUDMethods, CRUDProps } from './crud';
|
|
11
|
+
export { CRUDOfList } from './crud_of_list';
|
|
12
|
+
export type { CRUDOfListProps } from './crud_of_list';
|
|
11
13
|
export { CRUDOfPure } from './crud_of_pure';
|
|
12
14
|
export type { CRUDOfPureProps } from './crud_of_pure';
|
|
13
15
|
export { Editor } from './editor';
|