Skip to content

Commit fef061e

Browse files
authored
Merge pull request #2061 from LiarYe/master
[ADD] configure: Added addNewOptionPromptRender property.
2 parents 3551d75 + 056268f commit fef061e

10 files changed

Lines changed: 206 additions & 17 deletions

File tree

CHANGELOG.en-US.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ timeline: true
1515

1616
---
1717

18-
- 🌟 `configure`: Added `selectShowInputPrompt`, `tooltipAutoPlacement`, `inputDecimalSeparatorFollowLang` property.
18+
- 🌟 `configure`: Added `selectShowInputPrompt`, `tooltipAutoPlacement`, `inputDecimalSeparatorFollowLang`, `addNewOptionPromptRender` property.
1919
- 🌟 `<pro>Cascader`: Added `checkable` property.
2020
- 🌟 `<pro>Table`: Added `summaryBarConfigProps`, `customizedColumnProps` property.
2121
- 🌟 `<pro>Form.ItemGroup`: Added `groupItemStyle` property.

CHANGELOG.zh-CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ timeline: true
1515

1616
---
1717

18-
- 🌟 `configure`: 新增 selectShowInputPrompt, tooltipAutoPlacement, inputDecimalSeparatorFollowLang 属性。
18+
- 🌟 `configure`: 新增 selectShowInputPrompt, tooltipAutoPlacement, inputDecimalSeparatorFollowLang, addNewOptionPromptRender 属性。
1919
- 🌟 `<pro>Cascader`: 新增 checkable 属性。
2020
- 🌟 `<pro>Table`: 新增 summaryBarConfigProps, customizedColumnProps 属性。
2121
- 🌟 `<pro>Form.ItemGroup`: 新增 groupItemStyle 属性。

components-pro/lov/Lov.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,8 @@ export default class Lov extends Select<LovProps> {
652652
getSelectionProps: this.getSelectionProps,
653653
showDetailWhenReadonly,
654654
lang: this.lang,
655-
renderAddNewOptionPrompt: addNewOptionPrompt ? this.renderAddNewOptionPrompt : undefined,
655+
renderAddNewOptionPrompt: isFunction(addNewOptionPrompt) || (addNewOptionPrompt && addNewOptionPrompt.path)
656+
? this.renderAddNewOptionPrompt : undefined,
656657
}
657658
this.modal = Modal.open(mergeProps<ModalProps>({
658659
title: title || this.getLabel(),
@@ -695,7 +696,7 @@ export default class Lov extends Select<LovProps> {
695696
[`${this.prefixCls}-lov-modal`]: viewMode === TriggerViewMode.modal,
696697
[`${this.prefixCls}-lov-modal-drawer`]: viewMode === TriggerViewMode.drawer,
697698
[`${this.prefixCls}-lov-popup`]: viewMode === TriggerViewMode.popup,
698-
[`${this.prefixCls}-lov-modal-new-option-prompt`]: addNewOptionPrompt,
699+
[`${this.prefixCls}-lov-modal-new-option-prompt`]: isFunction(addNewOptionPrompt) || (addNewOptionPrompt && addNewOptionPrompt.path),
699700
});
700701
}
701702

components-pro/select/Select.tsx

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -270,16 +270,16 @@ export interface SelectProps extends TriggerFieldProps<SelectPopupContentProps>
270270
*/
271271
showInputPrompt?: boolean | ReactNode | (({ searchable, combo }) => boolean | ReactNode);
272272
/**
273-
* 自定义添加新选项提示
273+
* 自定义新增选项功能: 传入 path(根据addNewOptionPromptRender渲染) 或者 完全自定义渲染
274274
* type: prompt 有数据时底部提示, noDataPrompt 无数据时提示;
275275
*/
276-
addNewOptionPrompt?: (props: {
276+
addNewOptionPrompt?: { path: string; disabledTooltipTitle?: string; } | ((props: {
277277
type: 'prompt' | 'noDataPrompt';
278278
component: 'Select' | 'Lov';
279279
record?: Record;
280280
field?: Field;
281281
code?: string;
282-
}) => ReactNode;
282+
}) => ReactNode);
283283
}
284284

285285
export class Select<T extends SelectProps = SelectProps> extends TriggerField<T> {
@@ -707,7 +707,7 @@ export class Select<T extends SelectProps = SelectProps> extends TriggerField<T>
707707
if (notFoundContent !== undefined) {
708708
return notFoundContent;
709709
}
710-
if (addNewOptionPrompt) {
710+
if (isFunction(addNewOptionPrompt) || (addNewOptionPrompt && addNewOptionPrompt.path)) {
711711
return this.renderAddNewOptionPrompt('noDataPrompt');
712712
}
713713
return this.getContextConfig('renderEmpty')('Select');
@@ -1117,19 +1117,31 @@ export class Select<T extends SelectProps = SelectProps> extends TriggerField<T>
11171117
renderAddNewOptionPrompt(type: 'prompt' | 'noDataPrompt'): ReactNode | undefined {
11181118
const { record, field, props: { addNewOptionPrompt } } = this;
11191119
const { displayName } = this.constructor as any;
1120+
const addNewOptionPromptRender = this.getContextConfig('addNewOptionPromptRender');
1121+
const renderProps = {
1122+
type,
1123+
component: displayName,
1124+
record,
1125+
field,
1126+
code: field ? field.get(displayName === 'Select' ? 'lookupCode' : 'lovCode') : undefined,
1127+
};
11201128
if (isFunction(addNewOptionPrompt)) {
11211129
return (
11221130
<div
11231131
key={`new-option-notice-inner-${type}`}
11241132
className={`${this.prefixCls}-new-option-prompt ${this.prefixCls}-new-option-prompt-${type}`}
11251133
>
1126-
{addNewOptionPrompt({
1127-
type,
1128-
component: displayName,
1129-
record,
1130-
field,
1131-
code: field ? field.get(displayName === 'Select' ? 'lookupCode' : 'lovCode') : undefined,
1132-
})}
1134+
{addNewOptionPrompt(renderProps)}
1135+
</div>
1136+
);
1137+
}
1138+
if (addNewOptionPrompt && addNewOptionPrompt.path && addNewOptionPromptRender) {
1139+
return (
1140+
<div
1141+
key={`new-option-notice-inner-${type}`}
1142+
className={`${this.prefixCls}-new-option-prompt ${this.prefixCls}-new-option-prompt-${type}`}
1143+
>
1144+
{addNewOptionPromptRender({ ...renderProps, ...(addNewOptionPrompt as any) })}
11331145
</div>
11341146
);
11351147
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
order: 19
3+
title:
4+
zh-CN: 新增数据功能
5+
en-US: Add new option
6+
---
7+
8+
## zh-CN
9+
10+
新增数据功能自定义渲染。
11+
12+
## en-US
13+
14+
新增数据功能自定义渲染。
15+
16+
````jsx
17+
import React, { useState, useEffect } from 'react';
18+
import { DataSet, Select, Button, Row, Col, Tooltip, Icon } from 'choerodon-ui/pro';
19+
import { configure, Spin } from 'choerodon-ui';
20+
21+
const C7NAddNewOptionPromptRender = ({
22+
type,
23+
component,
24+
record,
25+
field,
26+
code,
27+
path,
28+
disabledTooltipTitle,
29+
}) => {
30+
url = path;
31+
disabledTooltipTitle = disabledTooltipTitle || `当前账号无该字段对应功能的菜单权限,请联系管理员`;
32+
33+
// TODO: 按钮根据用户是否有 url 权限, 判断是否禁用
34+
const [isDisabled, setIsDisabled] = useState(false);
35+
const [isLoading, setIsLoading] = useState(true);
36+
useEffect(() => {
37+
// TODO: 模拟异步请求权限
38+
setTimeout(() => {
39+
setIsLoading(false);
40+
setIsDisabled(true);
41+
}, 1000);
42+
}, []);
43+
44+
const tooltip = isDisabled ? [
45+
'always',
46+
{
47+
title: disabledTooltipTitle,
48+
},
49+
] : undefined;
50+
51+
if (!path) {
52+
return undefined;
53+
}
54+
55+
if (isLoading) {
56+
return <Spin />;
57+
}
58+
59+
if (component === 'Select' && type === 'prompt') {
60+
return (
61+
<>
62+
<span className={`c7n-pro-select-new-option-prompt-tip`}>没有找到数据?</span>
63+
<Button funcType="flat" color="primary" href={url} disabled={isDisabled} tooltip={tooltip}>
64+
立即添加{isDisabled ? <Icon type="help" /> : undefined}
65+
</Button>
66+
</>
67+
);
68+
}
69+
if (component === 'Select' && type === 'noDataPrompt') {
70+
return (
71+
<>
72+
<span className={`c7n-pro-select-new-option-prompt-tip`}>暂无数据</span>
73+
<Button funcType="flat" color="primary" href={url} disabled={isDisabled} tooltip={tooltip}>
74+
立即添加{isDisabled ? <Icon type="help" /> : undefined}
75+
</Button>
76+
</>
77+
);
78+
}
79+
if (component === 'Lov' && type === 'prompt') {
80+
return (
81+
<>
82+
<span className={`c7n-pro-select-new-option-prompt-tip`}>没有找到数据?</span>
83+
<Button funcType="flat" color="primary" href={url} disabled={isDisabled} tooltip={tooltip}>
84+
立即添加{isDisabled ? <Icon type="help" /> : undefined}
85+
</Button>
86+
</>
87+
);
88+
}
89+
if (component === 'Lov' && type === 'noDataPrompt') {
90+
return (
91+
<>
92+
<div>图片占位</div>
93+
<span className={`c7n-pro-select-new-option-prompt-tip`}>暂无数据</span>
94+
<Button funcType="flat" color="primary" href={url} disabled={isDisabled} tooltip={tooltip}>
95+
立即添加{isDisabled ? <Icon type="help" /> : undefined}
96+
</Button>
97+
</>
98+
);
99+
}
100+
};
101+
102+
const addNewOptionPromptRender = (props) => {
103+
return React.createElement(C7NAddNewOptionPromptRender, { ...props });
104+
};
105+
106+
configure({
107+
addNewOptionPromptRender: addNewOptionPromptRender,
108+
});
109+
110+
function handleDataSetChange({ record, name, value, oldValue }) {
111+
console.log('[dataset newValue]', value, '[oldValue]', oldValue, `[record.get('${name}')]`, record.get(name));
112+
}
113+
114+
const { Option } = Select;
115+
116+
const data = [{
117+
user: 'wu',
118+
user2: {
119+
text: 'Wu',
120+
value: 'wu',
121+
},
122+
}];
123+
124+
class App extends React.Component {
125+
ds = new DataSet({
126+
data,
127+
fields: [
128+
{ name: 'user', type: 'string', textField: 'text', label: '用户' },
129+
{ name: 'user2', type: 'object', textField: 'text', label: '用户object' },
130+
],
131+
events: {
132+
update: handleDataSetChange,
133+
},
134+
});
135+
136+
render() {
137+
return (
138+
<Row>
139+
<Col span={12}>
140+
<Select dataSet={this.ds} searchable name="user" addNewOptionPrompt={{ path: "/components-pro/button-cn/" }}>
141+
<Option value="jack">Jack</Option>
142+
<Option value="lucy">Lucy</Option>
143+
<Option value="wu">Wu</Option>
144+
</Select>
145+
</Col>
146+
<Col span={12}>
147+
<Select dataSet={this.ds} name="user2" addNewOptionPrompt={{ path: "/components-pro/button-cn/", disabledTooltipTitle: '自定义提示' }}>
148+
<Option value="jack">Jack</Option>
149+
<Option value="lucy">Lucy</Option>
150+
<Option value="wu">Wu</Option>
151+
</Select>
152+
</Col>
153+
</Row>
154+
);
155+
}
156+
}
157+
158+
ReactDOM.render(
159+
<App />,
160+
mountNode
161+
);
162+
````

components-pro/select/index.en-US.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ title: Select
4949
| popupShowComboValue | popup 弹窗中的选项是否显示 combo 复合值; 当不展示复合值时, defaultActiveFirstOption 无效, enter 或者 失焦选中复合值; | boolean | true |
5050
| virtual | 支持虚拟滚动 | boolean| false |
5151
| showInputPrompt | 可输入时,下拉框中是否显示输入提示。返回 true 或字符串时, 会同时显示到 placeholder 中 | boolean \| ReactNode \| (({ searchable, combo }) => boolean \| ReactNode) \| undefined | |
52-
| addNewOptionPrompt | 自定义添加新选项提示; type: prompt 有数据时底部提示, noDataPrompt 无数据时提示; component: Select Lov | (props: { type: 'prompt' \| 'noDataPrompt'; component: 'Select' \| 'Lov'; record?: Record; field?: Field; code?: string; }) => ReactNode| |
52+
| addNewOptionPrompt | 自定义新增选项功能: 传入 path(根据addNewOptionPromptRender渲染) 或者 完全自定义渲染; type: prompt 有数据时底部提示, noDataPrompt 无数据时提示; component: Select Lov | { path: string; disabledTooltipTitle?: string; } \| ((props: { type: 'prompt' \| 'noDataPrompt'; component: 'Select' \| 'Lov'; record?: Record; field?: Field; code?: string; }) => ReactNode) | |
5353

5454
更多属性请参考 [TriggerField](/components-pro/trigger-field/#TriggerField)
5555

components-pro/select/index.zh-CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ title: Select
4949
| popupShowComboValue | popup 弹窗中的选项是否显示 combo 复合值; 当不展示复合值时, defaultActiveFirstOption 无效, enter 或者 失焦选中复合值; | boolean | true |
5050
| virtual | 支持虚拟滚动 | boolean| false |
5151
| showInputPrompt | 可输入时,下拉框中是否显示输入提示。返回 true 或字符串时, 会同时显示到 placeholder 中 | boolean \| ReactNode \| (({ searchable, combo }) => boolean \| ReactNode) \| undefined | |
52-
| addNewOptionPrompt | 自定义添加新选项提示; type: prompt 有数据时底部提示, noDataPrompt 无数据时提示; component: Select Lov | (props: { type: 'prompt' \| 'noDataPrompt'; component: 'Select' \| 'Lov'; record?: Record; field?: Field; code?: string; }) => ReactNode| |
52+
| addNewOptionPrompt | 自定义新增选项功能: 传入 path(根据addNewOptionPromptRender渲染) 或者 完全自定义渲染; type: prompt 有数据时底部提示, noDataPrompt 无数据时提示; component: Select Lov | { path: string; disabledTooltipTitle?: string; } \| ((props: { type: 'prompt' \| 'noDataPrompt'; component: 'Select' \| 'Lov'; record?: Record; field?: Field; code?: string; }) => ReactNode) | |
5353

5454
更多属性请参考 [TriggerField](/components-pro/trigger-field/#TriggerField)
5555

components/configure/index.en-US.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ const prefixCls = getConfig('prefixCls');
218218
| selectScrollLoad | Select 组件是否开启选项滚动加载 | boolean | |
219219
| richTextFontFamilies | RichText 组件工具栏字体选择列表,配置的字体需要通过 Quill 注册才能生效 | ({ name: string; family: string })\[\] | |
220220
| selectShowInputPrompt | Select、Lov、TreeSelect可输入时,下拉框中是否显示输入提示。返回 true 或字符串时, 会同时显示到 placeholder 中 | boolean \| ReactNode \| (({ searchable, combo }) => boolean \| ReactNode) \| undefined | |
221+
| addNewOptionPromptRender | Select Lov 新增选项功能渲染函数 | (props: { type: 'prompt' \| 'noDataPrompt'; component: 'Select' \| 'Lov'; record?: Record; field?: Field; code?: string; path: string; disabledTooltipTitle?: string; }) => ReactNode | |
221222

222223
### Customizable
223224

components/configure/index.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ export interface AttachmentConfig extends DataSetAttachmentConfig {
171171

172172
export type TreeCheckboxPosition = undefined | 'default' | 'left';
173173

174+
export type AddNewOptionPromptRenderType = (props: {
175+
type: 'prompt' | 'noDataPrompt';
176+
component: 'Select' | 'Lov';
177+
record?: Record;
178+
field?: Field;
179+
code?: string;
180+
path: string;
181+
disabledTooltipTitle?: string;
182+
}) => ReactNode;
183+
174184
export interface Config extends DataSetConfig {
175185
prefixCls?: string;
176186
proPrefixCls?: string;
@@ -294,6 +304,8 @@ export interface Config extends DataSetConfig {
294304
selectTrigger?: Action[];
295305
selectScrollLoad?: boolean;
296306
selectShowInputPrompt?: boolean | ReactNode | (({ searchable, combo }) => boolean | ReactNode);
307+
/** Select Lov 新增选项功能渲染函数 */
308+
addNewOptionPromptRender?: AddNewOptionPromptRenderType;
297309
secretFieldEnable?: () => boolean;
298310
secretFieldTypes?: () => object[];
299311
secretFieldFetchVerifyCode?: (type: string) => Promise<object>;

components/configure/index.zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ const prefixCls = getConfig('prefixCls');
221221
| selectScrollLoad | Select 组件是否开启选项滚动加载 | boolean | |
222222
| richTextFontFamilies | RichText 组件工具栏字体选择列表,配置的字体需要通过 Quill 注册才能生效 | ({ name: string; family: string })\[\] | |
223223
| selectShowInputPrompt | Select、Lov、TreeSelect可输入时,下拉框中是否显示输入提示。返回 true 或字符串时, 会同时显示到 placeholder 中 | boolean \| ReactNode \| (({ searchable, combo }) => boolean \| ReactNode) \| undefined | |
224+
| addNewOptionPromptRender | Select Lov 新增选项功能渲染函数 | (props: { type: 'prompt' \| 'noDataPrompt'; component: 'Select' \| 'Lov'; record?: Record; field?: Field; code?: string; path: string; disabledTooltipTitle?: string; }) => ReactNode | |
224225

225226
### Customizable
226227

0 commit comments

Comments
 (0)