Skip to content

Commit 7e98591

Browse files
ycjcl868sorrycc
authored andcommitted
feat: api.ConfigForm component (umijs#3265)
1 parent e17ebf6 commit 7e98591

18 files changed

Lines changed: 354 additions & 85 deletions

File tree

docs/plugin/umi-ui.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,120 @@ api.addPanel({
489489
![](https://gw.alipayobjects.com/zos/antfincdn/ynwTwNrNjv/6af464b4-742b-4ce8-9ee2-92c826f2e51b.png)
490490

491491

492+
493+
### api.ConfigForm
494+
495+
配置表单页面,对 [api.Field](#api-field) 的上层封装,增加查询、修改接口即可生成表单页面:
496+
497+
498+
`api.ConfigForm` 参数如下:
499+
500+
```js
501+
interface IConfigFormProps {
502+
/** config title in the top */
503+
title: string;
504+
/** list config interface */
505+
list: string;
506+
/** edit config interface */
507+
edit: string;
508+
/** enable Toc, default false */
509+
enableToc?: boolean;
510+
/** Search fuse options, detail in https://github.com/krisk/Fuse */
511+
fuseOpts?: FuseOptions<number>;
512+
}
513+
```
514+
515+
使用示例:
516+
517+
服务端
518+
519+
```js
520+
// server
521+
export default (api) => {
522+
// more options in `api.Field` IFieldProps
523+
const data = [
524+
{
525+
"name": "base",
526+
"group": "Group1",
527+
"type": "string",
528+
"default": "/",
529+
"title": "group1",
530+
"description": "description1",
531+
},
532+
{
533+
"group": "Group2",
534+
"name": "group2",
535+
"title": "title2",
536+
"description": "description2",
537+
"type": "boolean",
538+
"default": false,
539+
},
540+
{
541+
"group": "Group2",
542+
// if you want link parent config, use `.` dot split
543+
"name": "group2.bar",
544+
"title": "title3",
545+
"description": "description3",
546+
"type": "boolean",
547+
"default": false,
548+
},
549+
]
550+
551+
api.onUISocket(({ action, failure, success }) => {
552+
const { type, payload, lang } = action;
553+
switch (type) {
554+
case 'org.umi.plugin.bar.config.list':
555+
success({
556+
data,
557+
});
558+
break;
559+
case 'org.umi.plugin.bar.config.edit':
560+
let config = payload.key;
561+
if (typeof payload.key === 'string') {
562+
config = {
563+
[payload.key]: payload.value,
564+
};
565+
}
566+
try {
567+
// your validate function
568+
// validateConfig(config);
569+
// (api as any).service.runCommand('config', {
570+
// _: ['set', config],
571+
// });
572+
success();
573+
} catch (e) {
574+
failure({
575+
message: e.message,
576+
errors: e.errors,
577+
});
578+
}
579+
break;
580+
default:
581+
break;
582+
}
583+
});
584+
}
585+
```
586+
587+
客户端
588+
589+
```jsx
590+
// client
591+
const { ConfigForm } = api;
592+
593+
api.addPanel({
594+
component: (
595+
<ConfigForm
596+
title="title Config"
597+
list="org.umi.plugin.bar.config.list"
598+
edit="org.umi.plugin.bar.config.edit"
599+
/>
600+
),
601+
});
602+
```
603+
604+
![image](https://user-images.githubusercontent.com/13595509/65481497-2fe6ef80-dec8-11e9-946f-7a8097c1e05e.png)
605+
492606
### api.notify
493607

494608
调用 Umi UI 通知栏,若用户停留在当前浏览器窗口,通知栏样式为 antd [Notification](https://ant.design/components/notification-cn),否则为系统原生通知栏。

docs/zh/plugin/umi-ui.md

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ api.addPanel({
405405
`api.Field` 参数如下:
406406

407407
```ts
408-
interface IFieldProps {
408+
interface IFieldProps {
409409
/** 表单类型 */
410410
/** 具体类型有:"string" | "boolean" | "object" | "string[]" | "object[]" | "list" | "textarea" | "any" */
411411
type: IConfigTypes;
@@ -423,6 +423,15 @@ api.addPanel({
423423
/** 其它类型与 Form.Item 一致 */
424424
[key: string]: any;
425425
}
426+
427+
interface IFieldLabel {
428+
/** label title */
429+
title: string;
430+
/** label description */
431+
description: string;
432+
/** description detail link */
433+
link: string;
434+
}
426435
```
427436

428437
例如,联动示例 :
@@ -489,7 +498,118 @@ api.addPanel({
489498

490499
![](https://gw.alipayobjects.com/zos/antfincdn/ynwTwNrNjv/6af464b4-742b-4ce8-9ee2-92c826f2e51b.png)
491500

501+
### api.ConfigForm
502+
503+
配置表单页面,对 [api.Field](#api-field) 的上层封装,增加查询、修改接口即可生成表单页面:
504+
505+
506+
`api.ConfigForm` 参数如下:
507+
508+
```js
509+
interface IConfigFormProps {
510+
/** config title in the top */
511+
title: string;
512+
/** list config interface */
513+
list: string;
514+
/** edit config interface */
515+
edit: string;
516+
/** enable Toc, default false */
517+
enableToc?: boolean;
518+
/** Search fuse options, detail in https://github.com/krisk/Fuse */
519+
fuseOpts?: FuseOptions<number>;
520+
}
521+
```
522+
523+
使用示例:
524+
525+
服务端
526+
527+
```js
528+
// server
529+
export default (api) => {
530+
// more options in `api.Field` IFieldProps
531+
const data = [
532+
{
533+
"name": "base",
534+
"group": "Group1",
535+
"type": "string",
536+
"default": "/",
537+
"title": "group1",
538+
"description": "description1",
539+
},
540+
{
541+
"group": "Group2",
542+
"name": "group2",
543+
"title": "title2",
544+
"description": "description2",
545+
"type": "boolean",
546+
"default": false,
547+
},
548+
{
549+
"group": "Group2",
550+
// if you want link parent config, use `.` dot split
551+
"name": "group2.bar",
552+
"title": "title3",
553+
"description": "description3",
554+
"type": "boolean",
555+
"default": false,
556+
},
557+
]
558+
559+
api.onUISocket(({ action, failure, success }) => {
560+
const { type, payload, lang } = action;
561+
switch (type) {
562+
case 'org.umi.plugin.bar.config.list':
563+
success({
564+
data,
565+
});
566+
break;
567+
case 'org.umi.plugin.bar.config.edit':
568+
let config = payload.key;
569+
if (typeof payload.key === 'string') {
570+
config = {
571+
[payload.key]: payload.value,
572+
};
573+
}
574+
try {
575+
// your validate function
576+
// validateConfig(config);
577+
// (api as any).service.runCommand('config', {
578+
// _: ['set', config],
579+
// });
580+
success();
581+
} catch (e) {
582+
failure({
583+
message: e.message,
584+
errors: e.errors,
585+
});
586+
}
587+
break;
588+
default:
589+
break;
590+
}
591+
});
592+
}
593+
```
594+
595+
客户端
596+
597+
```jsx
598+
// client
599+
const { ConfigForm } = api;
600+
601+
api.addPanel({
602+
component: (
603+
<ConfigForm
604+
title="title Config"
605+
list="org.umi.plugin.bar.config.list"
606+
edit="org.umi.plugin.bar.config.edit"
607+
/>
608+
),
609+
});
610+
```
492611

612+
![image](https://user-images.githubusercontent.com/13595509/65481497-2fe6ef80-dec8-11e9-946f-7a8097c1e05e.png)
493613

494614
### api.notify()
495615

packages/umi-plugin-ui/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"@ant-design/compatible": "^0.0.1-alpha.1",
1111
"@ant-design/icons": "^4.0.0-alpha.8",
1212
"classnames": "^2.2.6",
13-
"fuse.js": "^3.4.5",
1413
"react-portal": "^4.2.0",
1514
"sockjs-client": "1.3.0",
1615
"styled-components": "^3.4.10",

packages/umi-plugin-ui/src/plugins/configuration/locales/en-US.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,4 @@ export default {
44
'org.umi.ui.configuration.project.config.title': 'Project Configuration',
55
'org.umi.ui.configuration.project.config.desc': 'Configuration {library} Project',
66
'org.umi.ui.configuration.project.config.react.title': 'umi-plugin-react',
7-
'org.umi.ui.configuration.search.placeholder': 'Search',
8-
'org.umi.ui.configuration.okText': 'Yes',
9-
'org.umi.ui.configuration.cancelText': 'No',
10-
'org.umi.ui.configuration.save': 'Save',
11-
'org.umi.ui.configuration.reset': 'Reset',
12-
'org.umi.ui.configuration.reset.tooltip':
13-
'Are you sure you want to reset the above configuration?',
14-
'org.umi.ui.configuration.reset.tooltip.desc': 'Current configuration {value} have been modified',
15-
'org.umi.ui.configuration.reset.tooltip.desc.empty': 'Configuration has not been modified',
16-
'org.umi.ui.configuration.edit.success': 'Edit Success',
17-
'org.umi.ui.configuration.edit.loading': 'Editing',
187
};

packages/umi-plugin-ui/src/plugins/configuration/locales/zh-CN.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,4 @@ export default {
44
'org.umi.ui.configuration.project.config.title': '项目配置',
55
'org.umi.ui.configuration.project.config.desc': '配置 {library} 项目',
66
'org.umi.ui.configuration.project.config.react.title': 'umi-plugin-react',
7-
'org.umi.ui.configuration.search.placeholder': '搜索',
8-
'org.umi.ui.configuration.okText': '确定',
9-
'org.umi.ui.configuration.cancelText': '取消',
10-
'org.umi.ui.configuration.save': '保存',
11-
'org.umi.ui.configuration.reset': '重置',
12-
'org.umi.ui.configuration.reset.tooltip': '你确定要重置以上配置吗',
13-
'org.umi.ui.configuration.reset.tooltip.desc': '当前配置 {value} 已被修改',
14-
'org.umi.ui.configuration.reset.tooltip.desc.empty': '配置没有修改',
15-
'org.umi.ui.configuration.edit.success': '配置修改成功',
16-
'org.umi.ui.configuration.edit.loading': '正在保存配置',
177
};

packages/umi-plugin-ui/src/plugins/configuration/ui/components/PluginConfig.tsx

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/umi-plugin-ui/src/plugins/configuration/ui/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useContext } from 'react';
22
import { IUiApi } from 'umi-types';
3-
import BasicConfig from './components/BasicConfig';
43
import Context from './Context';
54
import styles from './index.module.less';
65

@@ -10,6 +9,7 @@ interface IConfigManager {
109
}
1110

1211
function getSections(api: IUiApi) {
12+
const { ConfigForm } = api;
1313
const sections = [
1414
{
1515
key: 'project',
@@ -30,7 +30,7 @@ function getSections(api: IUiApi) {
3030
},
3131
),
3232
component: () => (
33-
<BasicConfig
33+
<ConfigForm
3434
title="org.umi.ui.configuration.project.config.title"
3535
list="org.umi.config.list"
3636
edit="org.umi.config.edit"

packages/umi-types/ui.d.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,41 @@ declare namespace IUI {
128128
disableRightOverflow?: boolean;
129129
}
130130

131+
// from fuzz.js
132+
export interface FuseOptions<T> {
133+
id?: keyof T;
134+
caseSensitive?: boolean;
135+
includeMatches?: boolean;
136+
includeScore?: boolean;
137+
shouldSort?: boolean;
138+
sortFn?: (a: { score: number }, b: { score: number }) => number;
139+
getFn?: (obj: any, path: string) => any;
140+
keys?: (keyof T)[] | T[keyof T] | { name: keyof T; weight: number }[];
141+
verbose?: boolean;
142+
tokenize?: boolean;
143+
tokenSeparator?: RegExp;
144+
matchAllTokens?: boolean;
145+
location?: number;
146+
distance?: number;
147+
threshold?: number;
148+
maxPatternLength?: number;
149+
minMatchCharLength?: number;
150+
findAllMatches?: boolean;
151+
}
152+
153+
interface IConfigFormProps {
154+
/** config title in the top */
155+
title: string;
156+
/** list config interface */
157+
list: string;
158+
/** edit config interface */
159+
edit: string;
160+
/** enable Toc, default false */
161+
enableToc?: boolean;
162+
/** Search fuse options */
163+
fuseOpts?: FuseOptions<number>;
164+
}
165+
131166
type IApiActionFactory<P = {}, K = {}> = (action: IAction<P, K>) => K;
132167

133168
type ICallRemote<T = unknown, P = unknown> = IApiActionFactory<T, P>;
@@ -200,6 +235,8 @@ declare namespace IUI {
200235
callRemote: ICallRemote;
201236
/** React Two Column Panel Layout */
202237
TwoColumnPanel: FC<ITwoColumnPanel>;
238+
/** React Config Form Component */
239+
ConfigForm: FC<IConfigFormProps>;
203240
/** Antd Form Field */
204241
Field: FC<IFieldProps>;
205242
listenRemote: IListenRemote;

0 commit comments

Comments
 (0)