Skip to content

Commit

Permalink
chore: 弹窗交互调整 (baidu#9687)
Browse files Browse the repository at this point in the history
  • Loading branch information
2betop committed Mar 1, 2024
1 parent cbe6297 commit 549a905
Show file tree
Hide file tree
Showing 71 changed files with 3,043 additions and 1,581 deletions.
40 changes: 40 additions & 0 deletions docs/zh-CN/components/form/json-schema-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,45 @@ order: 61
}
```

## Mini 版本

通过设置 `mini` 属性可以开启 mini 版本,适用于宽度窄的情况。同时通过 `advancedSettings` 可以定制弹窗中的配置面板。

```schema: scope="body"
{
"type": "form",
"api": "/api/mock2/form/saveForm",
"debug": true,
"body": [
{
"type": "json-schema-editor",
"name": "schema",
"label": "字段类型",
"mini": true,
"style": {
"width": 300
},
"advancedSettings": {
"string": [
{
"type": "input-text",
"name": "maxLength",
"label": "Max Length"
}
],
"number": [
{
"type": "input-number",
"name": "max",
"label": "Max"
}
]
}
}
]
}
```

## 占位提示

> 2.8.0 及以上版本
Expand Down Expand Up @@ -160,6 +199,7 @@ order: 61
| showRootInfo | `boolean` | false | 是否显示顶级类型信息 |
| disabledTypes | `Array<string>` | | 用来禁用默认数据类型,默认类型有:string、number、interger、object、number、array、boolean、null |
| definitions | `object` | | 用来配置预设类型 |
| mini | `boolean` | | 用来开启迷你模式,适应于边栏面板,宽度较低的情况 |
| placeholder | `SchemaEditorItemPlaceholder` | `{key: "字段名", title: "名称", description: "描述", default: "默认值", empty: "<空>",}` | 属性输入控件的占位提示文本 | `2.8.0` |

### SchemaEditorItemPlaceholder
Expand Down
2 changes: 2 additions & 0 deletions packages/amis-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@types/jest": "^28.1.0",
"@types/react": "^18.0.24",
"@types/react-dom": "^18.0.8",
"@types/react-is": "^18.2.4",
"immutable": "^4.1.0",
"jest": "^29.0.3",
"jest-environment-jsdom": "^29.0.3",
Expand Down Expand Up @@ -47,6 +48,7 @@
"esm"
],
"dependencies": {
"amis-formula": "*",
"amis-formula": "^6.2.1",
"classnames": "2.3.2",
"file-saver": "^2.0.2",
Expand Down
19 changes: 11 additions & 8 deletions packages/amis-core/src/RootRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,15 @@ export class RootRenderer extends React.Component<RootRendererProps> {

window.open(mailto);
} else if (action.actionType === 'dialog') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
store.openDialog(
ctx,
undefined,
action.callback,
delegate || (this.context as any)
);
} else if (action.actionType === 'drawer') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
store.openDrawer(ctx, undefined, undefined, delegate);
} else if (action.actionType === 'toast') {
action.toast?.items?.forEach((item: any) => {
Expand Down Expand Up @@ -211,7 +211,7 @@ export class RootRenderer extends React.Component<RootRendererProps> {
);
});
} else if (action.actionType === 'ajax') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
store
.saveRemote(action.api as string, ctx, {
successMessage:
Expand Down Expand Up @@ -341,11 +341,14 @@ export class RootRenderer extends React.Component<RootRendererProps> {
openFeedback(dialog: any, ctx: any) {
return new Promise(resolve => {
const store = this.store;
store.setCurrentAction({
type: 'button',
actionType: 'dialog',
dialog: dialog
});
store.setCurrentAction(
{
type: 'button',
actionType: 'dialog',
dialog: dialog
},
this.props.resolveDefinitions
);
store.openDialog(
ctx,
undefined,
Expand Down
3 changes: 2 additions & 1 deletion packages/amis-core/src/SchemaRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import difference from 'lodash/difference';
import omit from 'lodash/omit';
import React from 'react';
import {isValidElementType} from 'react-is';
import LazyComponent from './components/LazyComponent';
import {
filterSchema,
Expand Down Expand Up @@ -349,7 +350,7 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
statusStore,
dispatchEvent: this.dispatchEvent
});
} else if (typeof schema.component === 'function') {
} else if (schema.component && isValidElementType(schema.component)) {
const isSFC = !(schema.component.prototype instanceof React.Component);
const {
data: defaultData,
Expand Down
1 change: 1 addition & 0 deletions packages/amis-core/src/actions/Action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ export const runAction = async (
{
...action,
args,
rawData: actionConfig.data,
data: action.actionType === 'reload' ? actionData : data, // 如果是刷新动作,则只传action.data
...key
},
Expand Down
19 changes: 15 additions & 4 deletions packages/amis-core/src/actions/DialogAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ export class DialogAction implements RendererAction {
{
actionType: 'dialog',
dialog: action.dialog,
reload: 'none'
reload: 'none',
data: action.rawData
},
action.data
);
Expand Down Expand Up @@ -142,11 +143,20 @@ export class ConfirmAction implements RendererAction {
renderer: ListenerContext,
event: RendererEvent<any>
) {
const type = action.dialog?.type ?? (action.args as any)?.type;
let modal: any = action.dialog ?? action.args;

if (modal.$ref && renderer.props.resolveDefinitions) {
modal = {
...renderer.props.resolveDefinitions(modal.$ref),
...modal
};
}

const type = modal?.type;

if (!type) {
const confirmed = await event.context.env.confirm?.(
filter(action.dialog?.msg, event.data) || action.args?.msg,
filter(modal?.msg, event.data) || action.args?.msg,
filter(action.dialog?.title, event.data) || action.args?.title,
{
closeOnEsc:
Expand Down Expand Up @@ -177,7 +187,8 @@ export class ConfirmAction implements RendererAction {
event,
{
actionType: 'dialog',
dialog: action.dialog ?? action.args,
dialog: modal,
data: action.rawData,
reload: 'none',
callback: (result: boolean) => resolve(result)
},
Expand Down
3 changes: 2 additions & 1 deletion packages/amis-core/src/actions/DrawerAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export class DrawerAction implements RendererAction {
{
actionType: 'drawer',
drawer: action.drawer,
reload: 'none'
reload: 'none',
data: action.rawData
},
action.data
);
Expand Down
29 changes: 16 additions & 13 deletions packages/amis-core/src/renderers/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1205,7 +1205,7 @@ export default class Form extends React.Component<FormProps, object> {
return;
}

store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);

if (action.actionType === 'reset-and-submit') {
store.reset(this.handleReset(action));
Expand Down Expand Up @@ -1372,27 +1372,27 @@ export default class Form extends React.Component<FormProps, object> {
}
});
} else if (action.type === 'reset' || action.actionType === 'reset') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
store.reset(onReset);
} else if (action.actionType === 'clear') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
store.clear(onReset);
} else if (action.actionType === 'validate') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
return this.validate(true, throwErrors, true, true);
} else if (action.actionType === 'dialog') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
store.openDialog(
data,
undefined,
action.callback,
delegate || (this.context as any)
);
} else if (action.actionType === 'drawer') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
store.openDrawer(data);
} else if (action.actionType === 'ajax') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
if (!isEffectiveApi(action.api)) {
return env.alert(__(`当 actionType 为 ajax 时,请设置 api 属性`));
}
Expand Down Expand Up @@ -1447,7 +1447,7 @@ export default class Form extends React.Component<FormProps, object> {
}
});
} else if (action.actionType === 'reload') {
store.setCurrentAction(action);
store.setCurrentAction(action, this.props.resolveDefinitions);
if (action.target) {
this.reloadTarget(filterTarget(action.target, data), data);
} else {
Expand Down Expand Up @@ -1558,11 +1558,14 @@ export default class Form extends React.Component<FormProps, object> {
openFeedback(dialog: any, ctx: any) {
return new Promise(resolve => {
const {store} = this.props;
store.setCurrentAction({
type: 'button',
actionType: 'dialog',
dialog: dialog
});
store.setCurrentAction(
{
type: 'button',
actionType: 'dialog',
dialog: dialog
},
this.props.resolveDefinitions
);
store.openDialog(
ctx,
undefined,
Expand Down
2 changes: 1 addition & 1 deletion packages/amis-core/src/renderers/wrapControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export interface ControlOutterProps extends RendererProps {
submitOnChange?: boolean;
validate?: (value: any, values: any, name: string) => any;
formItem?: IFormItemStore;
addHook?: (fn: () => any, type?: 'validate' | 'init' | 'flush') => void;
addHook?: (fn: () => any, type?: 'validate' | 'init' | 'flush') => () => void;
removeHook?: (fn: () => any, type?: 'validate' | 'init' | 'flush') => void;
$schema: {
pipeIn?: (value: any, data: any) => any;
Expand Down
38 changes: 32 additions & 6 deletions packages/amis-core/src/store/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,11 +548,17 @@ export const FormStore = ServiceStore.named('FormStore')
self.submiting = true;

try {
yield validate(hooks, true, true, failedMessage, validateErrCb);
const valid = yield validate(
hooks,
true,
true,
failedMessage,
validateErrCb
);

if (fn) {
const diff = difference(self.data, self.pristine);
const result = yield fn(
const result: any = yield fn(
createObject(
createObject(self.data.__super, {
diff: diff,
Expand All @@ -578,7 +584,7 @@ export const FormStore = ServiceStore.named('FormStore')
failedMessage?: string,
validateErrCb?: () => void
) => Promise<boolean> = flow(function* validate(
hooks?: Array<() => Promise<any>>,
hooks?: Array<(data: any) => Promise<any>>,
forceValidate?: boolean,
throwErrors?: boolean,
failedMessage?: string,
Expand Down Expand Up @@ -624,10 +630,30 @@ export const FormStore = ServiceStore.named('FormStore')
}
}

if (hooks && hooks.length) {
for (let i = 0, len = hooks.length; i < len; i++) {
yield hooks[i]();
try {
if (hooks && hooks.length) {
for (let i = 0, len = hooks.length; i < len; i++) {
const msg = yield hooks[i](self.data);

if (typeof msg == 'string' && msg) {
throw new Error(msg);
} else if (msg === false) {
// 不提示直接不通过校验
throw new ValidateError(
failedMessage || self.__('Form.validateFailed'),
self.errors
);
}
}
}
} catch (e) {
if (throwErrors) {
throw e;
} else {
toastValidateError(e.message);
}

return false;
}

if (!self.valid) {
Expand Down
27 changes: 21 additions & 6 deletions packages/amis-core/src/store/iRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,21 @@ export const iRendererStore = StoreNode.named('iRendererStore')
self.data = data;
},

setCurrentAction(action: object) {
setCurrentAction(action: any, resolveDefinitions?: (schema: any) => any) {
// 处理 $ref
resolveDefinitions &&
['dialog', 'drawer'].forEach(key => {
if (action[key]?.$ref) {
action = {
...action,
[key]: {
...resolveDefinitions(action[key].$ref),
...action[key]
}
};
}
});

self.action = action;
self.dialogData = false;
self.drawerOpen = false;
Expand All @@ -174,11 +188,11 @@ export const iRendererStore = StoreNode.named('iRendererStore')
}

const data = createObjectFromChain(chain);

if (self.action.dialog && self.action.dialog.data) {
const mappingData = self.action.data ?? self.action.dialog?.data;
if (mappingData) {
self.dialogData = createObjectFromChain([
top?.context,
dataMapping(self.action.dialog.data, data)
dataMapping(mappingData, data)
]);

const clonedAction = {
Expand Down Expand Up @@ -223,10 +237,11 @@ export const iRendererStore = StoreNode.named('iRendererStore')

const data = createObjectFromChain(chain);

if (self.action.drawer.data) {
const mappingData = self.action.data ?? self.action.drawer.data;
if (mappingData) {
self.drawerData = createObjectFromChain([
top?.context,
dataMapping(self.action.drawer.data, data)
dataMapping(mappingData, data)
]);

const clonedAction = {
Expand Down

0 comments on commit 549a905

Please sign in to comment.