mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-30 02:48:55 +08:00
fix:修复历史数据dialog没有type的兼容 (#8209)
* 修复编辑态获取焦点等事件触发drawer,新建弹窗切换到现有弹窗过滤自身 * 兼容历史弹窗schema没有type的修复
This commit is contained in:
parent
e3b74d4ac9
commit
707d5ef900
@ -29,6 +29,10 @@ export class DrawerAction implements RendererAction {
|
||||
renderer: ListenerContext,
|
||||
event: RendererEvent<any>
|
||||
) {
|
||||
// 防止editor preview模式下执行
|
||||
if ((action as any).$$id !== undefined) {
|
||||
return;
|
||||
}
|
||||
renderer.props.onAction?.(
|
||||
event,
|
||||
{
|
||||
|
@ -21,7 +21,8 @@ import {
|
||||
JSONGetById,
|
||||
JSONPipeIn,
|
||||
JSONPipeOut,
|
||||
JSONUpdate
|
||||
JSONUpdate,
|
||||
getFixDialogType
|
||||
} from '../util';
|
||||
import {createObject, createObjectFromChain} from 'amis-core';
|
||||
import {CommonConfigWrapper} from './CommonConfigWrapper';
|
||||
@ -253,7 +254,7 @@ function addDefinitions(
|
||||
schema: Schema,
|
||||
definitions: Schema,
|
||||
dialogMaxIndex: number,
|
||||
selectDialog: Schema
|
||||
selectDialog: any
|
||||
) {
|
||||
let newSchema;
|
||||
let dialogRefsName = '';
|
||||
@ -265,14 +266,20 @@ function addDefinitions(
|
||||
}
|
||||
});
|
||||
}
|
||||
let dialogType = getFixDialogType(schema, selectDialog.$$id);
|
||||
let newDefinitions = {...definitions};
|
||||
if (!dialogRefsName) {
|
||||
dialogRefsName = dialogMaxIndex
|
||||
? `dialog-${dialogMaxIndex + 1}`
|
||||
: 'dialog-1';
|
||||
? `${dialogType}-ref-${dialogMaxIndex + 1}`
|
||||
: `${dialogType}-ref-1`;
|
||||
}
|
||||
// 防止definition被查找到替换为$ref重新生成一下
|
||||
newDefinitions[dialogRefsName] = JSONPipeIn(JSONPipeOut({...selectDialog}));
|
||||
newDefinitions[dialogRefsName] = JSONPipeIn(
|
||||
JSONPipeOut({
|
||||
...selectDialog,
|
||||
type: dialogType
|
||||
})
|
||||
);
|
||||
newSchema = {
|
||||
...schema,
|
||||
definitions: newDefinitions
|
||||
@ -294,8 +301,8 @@ function currentDialogOnchagne(
|
||||
let definitions = schema.definitions || {};
|
||||
let dialogMaxIndex: number = 0;
|
||||
Object.keys(definitions).forEach(k => {
|
||||
if (k.includes('dialog-')) {
|
||||
let index = Number(k.split('-')[1]);
|
||||
if (k.includes('ref-')) {
|
||||
let index = Number(k.split('-')[2]);
|
||||
dialogMaxIndex = Math.max(dialogMaxIndex, index);
|
||||
}
|
||||
});
|
||||
|
@ -20,7 +20,8 @@ import {
|
||||
guid,
|
||||
appTranslate,
|
||||
JSONGetByPath,
|
||||
getDialogActions
|
||||
getDialogActions,
|
||||
getFixDialogType
|
||||
} from '../../src/util';
|
||||
import {
|
||||
InsertEventContext,
|
||||
@ -231,7 +232,13 @@ export const MainStore = types
|
||||
get filteredSchema() {
|
||||
let schema = self.schema;
|
||||
if (self.previewDialogId) {
|
||||
schema = this.getSchema(self.previewDialogId);
|
||||
let originDialogSchema = this.getSchema(self.previewDialogId);
|
||||
schema = {
|
||||
...originDialogSchema,
|
||||
type:
|
||||
originDialogSchema.type ||
|
||||
getFixDialogType(self.schema, self.previewDialogId)
|
||||
};
|
||||
}
|
||||
return filterSchemaForEditor(
|
||||
getEnv(self).schemaFilter?.(schema) ?? schema
|
||||
|
@ -1281,19 +1281,19 @@ export const getDialogActions = (
|
||||
const definitions = object.definitions;
|
||||
if (definitions) {
|
||||
Object.keys(definitions).forEach(key => {
|
||||
if (key.includes('dialog-')) {
|
||||
if (key.includes('ref-')) {
|
||||
if (listType === 'list') {
|
||||
dialogActions.push(definitions[key]);
|
||||
} else {
|
||||
const dialog = definitions[key];
|
||||
const dialogType =
|
||||
const dialogTypeName =
|
||||
dialog.type === 'drawer'
|
||||
? '抽屉'
|
||||
? '抽屉式弹窗'
|
||||
: dialog.dialogType
|
||||
? '确认对话框'
|
||||
: '弹窗';
|
||||
dialogActions.push({
|
||||
label: `${dialog.title || '-'}(${dialogType})`,
|
||||
label: `${dialog.title || '-'}(${dialogTypeName})`,
|
||||
value: dialog
|
||||
});
|
||||
}
|
||||
@ -1317,7 +1317,7 @@ export const getDialogActions = (
|
||||
[
|
||||
'drawer',
|
||||
{
|
||||
title: '弹窗',
|
||||
title: '抽屉式弹窗',
|
||||
body: 'drawer'
|
||||
}
|
||||
],
|
||||
@ -1325,28 +1325,63 @@ export const getDialogActions = (
|
||||
'confirmDialog',
|
||||
{
|
||||
title: '确认对话框',
|
||||
body: 'dialog'
|
||||
// 兼容历史args参数
|
||||
body: ['dialog', 'args']
|
||||
}
|
||||
]
|
||||
]);
|
||||
let dialogBody = dialogBodyMap.get(value)?.body!;
|
||||
let dialogBodyContent = Array.isArray(dialogBody)
|
||||
? object[dialogBody[0]] || object[dialogBody[1]]
|
||||
: object[dialogBody];
|
||||
|
||||
if (
|
||||
dialogBodyMap.has(value) &&
|
||||
object[dialogBody] &&
|
||||
!object[dialogBody].$ref
|
||||
dialogBodyContent &&
|
||||
!dialogBodyContent.$ref
|
||||
) {
|
||||
if (listType == 'list') {
|
||||
dialogActions.push(object[dialogBody]);
|
||||
} else {
|
||||
// 没有 type: dialog的历史数据兼容一下
|
||||
dialogActions.push({
|
||||
label: `${object[dialogBody]?.title || '-'}(${
|
||||
dialogBodyMap.get(value)?.title
|
||||
})`,
|
||||
value: object[dialogBody]
|
||||
...dialogBodyContent,
|
||||
type: dialogBody
|
||||
});
|
||||
} else {
|
||||
// 新建弹窗切换到现有弹窗把自身过滤掉
|
||||
if (!filterId || (filterId && filterId !== dialogBodyContent.id)) {
|
||||
dialogActions.push({
|
||||
label: `${dialogBodyContent?.title || '-'}(${
|
||||
dialogBodyMap.get(value)?.title
|
||||
})`,
|
||||
value: dialogBodyContent
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return dialogActions;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取弹窗的类型,来源于事件或definitions,由于历史数据可能没有type: dialog,在这里兼容一下
|
||||
* @param json
|
||||
* @param previewDialogId
|
||||
*/
|
||||
export const getFixDialogType = (json: Schema, dialogId: string) => {
|
||||
const dialogBodyMap = {
|
||||
dialog: 'dialog',
|
||||
drawer: 'drawer',
|
||||
confirmDialog: 'dialog'
|
||||
};
|
||||
let parentSchema = JSONGetParentById(json, dialogId);
|
||||
// 事件中的弹窗
|
||||
if (parentSchema.actionType) {
|
||||
return dialogBodyMap[parentSchema.actionType as keyof typeof dialogBodyMap];
|
||||
}
|
||||
// definitions中的弹窗
|
||||
else {
|
||||
let dialogRefSchema = JSONGetById(parentSchema, dialogId);
|
||||
return dialogRefSchema.type;
|
||||
}
|
||||
};
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
BaseEventContext,
|
||||
defaultValue,
|
||||
EditorManager,
|
||||
getFixDialogType,
|
||||
getSchemaTpl,
|
||||
JsonGenerateID,
|
||||
JSONPipeIn,
|
||||
@ -20,7 +21,6 @@ import {
|
||||
DataSchema,
|
||||
filterTree,
|
||||
findTree,
|
||||
JSONTraverse,
|
||||
mapTree,
|
||||
normalizeApi,
|
||||
PlainObject,
|
||||
@ -2911,7 +2911,8 @@ export const getEventControlConfig = (
|
||||
actionConfigSubmitFormatter: (
|
||||
config: ActionConfig,
|
||||
type?: string,
|
||||
actionData?: ActionData
|
||||
actionData?: ActionData,
|
||||
shcema?: Schema
|
||||
) => {
|
||||
let action: ActionConfig = {...config, groupType: undefined};
|
||||
action.__title = findActionNode(
|
||||
@ -3032,18 +3033,24 @@ export const getEventControlConfig = (
|
||||
}
|
||||
};
|
||||
|
||||
const chooseCurrentDialog = (action: ActionConfig) => {
|
||||
const chooseCurrentDialog = (action: ActionConfig, schema: Schema) => {
|
||||
const selectDialog = action.__selectDialog;
|
||||
let dialogType = getFixDialogType(schema, selectDialog.$$id);
|
||||
// 选择现有弹窗后为了使之前的弹窗和现有弹窗$$id唯一,这里重新生成一下
|
||||
let dialogCopy = JSONPipeIn(JSONPipeOut({...selectDialog}));
|
||||
let dialogCopy = JSONPipeIn(
|
||||
JSONPipeOut({
|
||||
...selectDialog,
|
||||
type: dialogType
|
||||
})
|
||||
);
|
||||
// 在这里记录一下新dialogId
|
||||
action.__relatedDialogId = dialogCopy.$$id;
|
||||
if (selectDialog?.dialogType) {
|
||||
action.actionType = 'dialog';
|
||||
action.dialog = dialogCopy;
|
||||
} else {
|
||||
action.actionType = selectDialog.type;
|
||||
action[selectDialog.type] = dialogCopy;
|
||||
action.actionType = selectDialog.type || dialogType;
|
||||
action[selectDialog.type || dialogType] = dialogCopy;
|
||||
}
|
||||
};
|
||||
|
||||
@ -3051,7 +3058,7 @@ export const getEventControlConfig = (
|
||||
if (config.__dialogSource === 'new') {
|
||||
setInitSchema(config.groupType, action);
|
||||
} else if (config.__dialogSource === 'current') {
|
||||
chooseCurrentDialog(action);
|
||||
chooseCurrentDialog(action, shcema!);
|
||||
}
|
||||
}
|
||||
// 编辑
|
||||
@ -3071,7 +3078,7 @@ export const getEventControlConfig = (
|
||||
};
|
||||
}
|
||||
} else if (config.__dialogSource === 'current') {
|
||||
chooseCurrentDialog(action);
|
||||
chooseCurrentDialog(action, shcema!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
render as amisRender
|
||||
} from 'amis';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import {FormControlProps, autobind, findTree} from 'amis-core';
|
||||
import {FormControlProps, Schema, autobind, findTree} from 'amis-core';
|
||||
import ActionDialog from './action-config-dialog';
|
||||
import {
|
||||
findActionNode,
|
||||
@ -36,7 +36,8 @@ import {
|
||||
RendererPluginAction,
|
||||
RendererPluginEvent,
|
||||
SubRendererPluginAction,
|
||||
getDialogActions
|
||||
getDialogActions,
|
||||
getFixDialogType
|
||||
} from 'amis-editor-core';
|
||||
export * from './helper';
|
||||
import {i18n as _i18n} from 'i18n-runtime';
|
||||
@ -63,7 +64,8 @@ interface EventControlProps extends FormControlProps {
|
||||
actionConfigSubmitFormatter?: (
|
||||
actionConfig: ActionConfig,
|
||||
type?: string,
|
||||
actionData?: ActionData
|
||||
actionData?: ActionData,
|
||||
schema?: Schema
|
||||
) => ActionConfig; // 动作配置提交时格式化
|
||||
owner?: string; // 组件标识
|
||||
}
|
||||
@ -110,6 +112,12 @@ interface EventControlState {
|
||||
appLocaleState?: number;
|
||||
}
|
||||
|
||||
const dialogObjMap = {
|
||||
dialog: 'dialog',
|
||||
drawer: 'drawer',
|
||||
confirmDialog: ['dialog', 'args']
|
||||
};
|
||||
|
||||
export class EventControl extends React.Component<
|
||||
EventControlProps,
|
||||
EventControlState
|
||||
@ -697,8 +705,18 @@ export class EventControl extends React.Component<
|
||||
}
|
||||
|
||||
// 获取现有弹窗列表
|
||||
getDialogList(manager: EditorManager) {
|
||||
return getDialogActions(manager.store.schema, 'source');
|
||||
getDialogList(
|
||||
manager: EditorManager,
|
||||
action?: ActionConfig,
|
||||
actionType?: keyof typeof dialogObjMap
|
||||
) {
|
||||
if (action && actionType && dialogObjMap[actionType]) {
|
||||
let dialogBodyContent = dialogObjMap[actionType];
|
||||
let filterId = Array.isArray(dialogBodyContent)
|
||||
? action[dialogBodyContent[0]].id || action[dialogBodyContent[1]].id
|
||||
: action[dialogBodyContent].id;
|
||||
return getDialogActions(manager.store.schema, 'source', filterId);
|
||||
} else return getDialogActions(manager.store.schema, 'source');
|
||||
}
|
||||
|
||||
// 唤起动作配置弹窗
|
||||
@ -751,6 +769,8 @@ export class EventControl extends React.Component<
|
||||
);
|
||||
}
|
||||
|
||||
const actionGroupType = actionConfig?.__actionType || action.actionType;
|
||||
|
||||
data.actionData = {
|
||||
eventKey: data.actionData!.eventKey,
|
||||
actionIndex: data.actionData!.actionIndex,
|
||||
@ -758,12 +778,12 @@ export class EventControl extends React.Component<
|
||||
pluginActions,
|
||||
getContextSchemas,
|
||||
...actionConfig,
|
||||
groupType: actionConfig?.__actionType || action.actionType,
|
||||
groupType: actionGroupType,
|
||||
__actionDesc: actionNode?.description ?? '', // 树节点描述
|
||||
__actionSchema: actionNode!.schema, // 树节点schema
|
||||
__subActions: hasSubActionNode?.actions, // 树节点子动作
|
||||
__cmptTreeSource: supportComponents ?? [],
|
||||
__dialogActions: this.getDialogList(manager),
|
||||
__dialogActions: this.getDialogList(manager, action, actionGroupType),
|
||||
__superCmptTreeSource: allComponents,
|
||||
// __supersCmptTreeSource: '',
|
||||
__setValueDs: setValueDs
|
||||
@ -772,15 +792,12 @@ export class EventControl extends React.Component<
|
||||
|
||||
// 编辑时准备已选的弹窗来源和标题
|
||||
if (actionConfig?.actionType == 'openDialog') {
|
||||
const dialogActionType = data.actionData?.groupType;
|
||||
const definitions = manager.store.schema.definitions;
|
||||
|
||||
const dialogObjMap = new Map([
|
||||
['dialog', 'dialog'],
|
||||
['drawer', 'drawer'],
|
||||
['confirmDialog', 'dialog']
|
||||
]);
|
||||
const dialogObj = dialogObjMap.get(dialogActionType!);
|
||||
let dialogBody =
|
||||
dialogObjMap[actionGroupType as keyof typeof dialogObjMap];
|
||||
const dialogObj = Array.isArray(dialogBody)
|
||||
? dialogBody[0] || dialogBody[1]
|
||||
: dialogBody;
|
||||
|
||||
const dialogRef = actionConfig?.[dialogObj!]?.$ref;
|
||||
|
||||
@ -861,7 +878,8 @@ export class EventControl extends React.Component<
|
||||
) : null;
|
||||
}
|
||||
|
||||
getRefsFromCurrentDialog(definitions: any, action: any) {
|
||||
getRefsFromCurrentDialog(store: any, action: any) {
|
||||
let definitions = store.schema.definitions;
|
||||
let dialogMaxIndex: number = 0;
|
||||
let dialogRefsName = '';
|
||||
if (definitions) {
|
||||
@ -870,16 +888,17 @@ export class EventControl extends React.Component<
|
||||
if (dialog.$$id === action.__selectDialog.$$id) {
|
||||
dialogRefsName = k;
|
||||
}
|
||||
if (k.includes('dialog-')) {
|
||||
let index = Number(k.split('-')[1]);
|
||||
if (k.includes('ref-')) {
|
||||
let index = Number(k.split('-')[2]);
|
||||
dialogMaxIndex = Math.max(dialogMaxIndex, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
let dialogType = getFixDialogType(store.schema, action.__selectDialog.$$id);
|
||||
if (!dialogRefsName) {
|
||||
dialogRefsName = dialogMaxIndex
|
||||
? `dialog-${dialogMaxIndex + 1}`
|
||||
: 'dialog-1';
|
||||
? `${dialogType}-ref-${dialogMaxIndex + 1}`
|
||||
: `${dialogType}-ref-1`;
|
||||
}
|
||||
return dialogRefsName;
|
||||
}
|
||||
@ -890,14 +909,12 @@ export class EventControl extends React.Component<
|
||||
const {actionData} = this.state;
|
||||
const store = manager.store;
|
||||
const action =
|
||||
actionConfigSubmitFormatter?.(config, type, actionData) ?? config;
|
||||
actionConfigSubmitFormatter?.(config, type, actionData, store.schema) ??
|
||||
config;
|
||||
delete action.__actionSchema;
|
||||
if (type === 'add') {
|
||||
if (
|
||||
action.actionType === 'dialog' ||
|
||||
action.actionType === 'drawer' ||
|
||||
action.actionType === 'confirmDialog'
|
||||
) {
|
||||
if (['dialog', 'drawer', 'confirmDialog'].includes(action.actionType)) {
|
||||
this.addAction?.(config.eventKey, action);
|
||||
let args =
|
||||
action.actionType === 'dialog'
|
||||
? 'dialog'
|
||||
@ -912,24 +929,18 @@ export class EventControl extends React.Component<
|
||||
}/actions/${actionLength}/${args}`;
|
||||
store.setActiveDialogPath(path);
|
||||
} else if (config?.__dialogSource === 'current') {
|
||||
let dialogRefsName = this.getRefsFromCurrentDialog(
|
||||
store.schema.definitions,
|
||||
action
|
||||
);
|
||||
let dialogRefsName = this.getRefsFromCurrentDialog(store, action);
|
||||
let path = `definitions/${dialogRefsName}`;
|
||||
store.setActiveDialogPath(path);
|
||||
} else {
|
||||
this.addAction?.(config.eventKey, action);
|
||||
}
|
||||
|
||||
this.addAction?.(config.eventKey, action);
|
||||
} else {
|
||||
this.addAction?.(config.eventKey, action);
|
||||
}
|
||||
} else if (type === 'update') {
|
||||
if (
|
||||
action.actionType === 'dialog' ||
|
||||
action.actionType === 'drawer' ||
|
||||
action.actionType === 'confirmDialog'
|
||||
) {
|
||||
if (['dialog', 'drawer', 'confirmDialog'].includes(action.actionType)) {
|
||||
this.updateAction?.(config.eventKey, config.actionIndex, action);
|
||||
let args =
|
||||
action.actionType === 'dialog'
|
||||
? 'dialog'
|
||||
@ -943,14 +954,10 @@ export class EventControl extends React.Component<
|
||||
}/actions/${config.actionIndex}/${args}`;
|
||||
store.setActiveDialogPath(path);
|
||||
} else if (config.__dialogSource === 'current') {
|
||||
let dialogRefsName = this.getRefsFromCurrentDialog(
|
||||
store.schema.definitions,
|
||||
action
|
||||
);
|
||||
let dialogRefsName = this.getRefsFromCurrentDialog(store, action);
|
||||
let path = `definitions/${dialogRefsName}`;
|
||||
store.setActiveDialogPath(path);
|
||||
}
|
||||
this.updateAction?.(config.eventKey, config.actionIndex, action);
|
||||
} else {
|
||||
this.updateAction?.(config.eventKey, config.actionIndex, action);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user