diff --git a/packages/amis-editor/package.json b/packages/amis-editor/package.json index 1402cea5c..50d51fb4f 100644 --- a/packages/amis-editor/package.json +++ b/packages/amis-editor/package.json @@ -1,6 +1,6 @@ { "name": "amis-editor", - "version": "5.2.0-beta.34", + "version": "5.2.0-beta.37", "description": "amis 可视化编辑器", "main": "lib/index.js", "module": "esm/index.js", diff --git a/packages/amis-editor/src/plugin/Button.tsx b/packages/amis-editor/src/plugin/Button.tsx index 202057bb9..c6226f2a7 100644 --- a/packages/amis-editor/src/plugin/Button.tsx +++ b/packages/amis-editor/src/plugin/Button.tsx @@ -286,9 +286,8 @@ export class ButtonPlugin extends BasePlugin { title: '事件', className: 'p-none', body: - this.manager?.config.actionOptions?.showOldEntry !== false && - (!!context.schema.actionType || - ['submit', 'reset'].includes(context.schema.type)) + !!context.schema.actionType || + ['submit', 'reset'].includes(context.schema.type) ? [ getSchemaTpl('eventControl', { name: 'onEvent', diff --git a/packages/amis-editor/src/plugin/CRUD.tsx b/packages/amis-editor/src/plugin/CRUD.tsx index c858fba53..1ee50b729 100644 --- a/packages/amis-editor/src/plugin/CRUD.tsx +++ b/packages/amis-editor/src/plugin/CRUD.tsx @@ -85,34 +85,6 @@ export class CRUDPlugin extends BasePlugin { } ]; - sampleBuilder = (schema: any) => { - const data: any = { - items: [], - total: 0 - }; - - if (Array.isArray(schema?.columns)) { - const item = {}; - schema.columns.forEach((control: any) => { - if (control?.name) { - setVariable(item, control.name, 'sample'); - } - }); - - data.items.push(item); - } - - return JSON.stringify( - { - status: 0, - msg: '', - data: data - }, - null, - 2 - ); - }; - btnSchemas = { create: { label: '新增', @@ -394,8 +366,8 @@ export class CRUDPlugin extends BasePlugin { /** 统一api格式 */ valueSchema.api = typeof valueSchema.api === 'string' - ? valueSchema.api - : normalizeApi(valueSchema.api); + ? normalizeApi(valueSchema.api) + : valueSchema.api; hasFeatures && features.forEach((item: string) => { if (itemBtns.includes(item)) { diff --git a/packages/amis-editor/src/plugin/Chart.tsx b/packages/amis-editor/src/plugin/Chart.tsx index 30cbbe227..1fd1624e9 100644 --- a/packages/amis-editor/src/plugin/Chart.tsx +++ b/packages/amis-editor/src/plugin/Chart.tsx @@ -1,21 +1,20 @@ import {Button} from 'amis'; import React from 'react'; -import {registerEditorPlugin} from 'amis-editor-core'; import { + registerEditorPlugin, BaseEventContext, BasePlugin, - RegionConfig, - RendererInfo + RendererPluginAction, + diff, + defaultValue, + getSchemaTpl, + CodeEditor as AmisCodeEditor } from 'amis-editor-core'; -import {defaultValue, getSchemaTpl, } from 'amis-editor-core'; -import {diff} from 'amis-editor-core'; -import AMisCodeEditor from 'amis-editor-core'; -import {RendererPluginAction} from 'amis-editor-core'; const ChartConfigEditor = ({value, onChange}: any) => { return (
- +
); }; diff --git a/packages/amis-editor/src/plugin/Form/CodeEditor.tsx b/packages/amis-editor/src/plugin/Form/CodeEditor.tsx index cd5a1b61c..6a073f1e7 100644 --- a/packages/amis-editor/src/plugin/Form/CodeEditor.tsx +++ b/packages/amis-editor/src/plugin/Form/CodeEditor.tsx @@ -206,6 +206,11 @@ export class CodeEditorControlPlugin extends BasePlugin { } ]); }; + + filterProps(props: any) { + props.disabled = true; + return props; + } } registerEditorPlugin(CodeEditorControlPlugin); diff --git a/packages/amis-editor/src/plugin/Form/DiffEditor.tsx b/packages/amis-editor/src/plugin/Form/DiffEditor.tsx index 37bc4745a..45a144165 100644 --- a/packages/amis-editor/src/plugin/Form/DiffEditor.tsx +++ b/packages/amis-editor/src/plugin/Form/DiffEditor.tsx @@ -215,6 +215,11 @@ export class DiffEditorControlPlugin extends BasePlugin { } ]); }; + + filterProps(props: any) { + props.disabled = true; + return props; + } } registerEditorPlugin(DiffEditorControlPlugin); diff --git a/packages/amis-editor/src/plugin/Form/Form.tsx b/packages/amis-editor/src/plugin/Form/Form.tsx index ea128b656..7c6b2c2b5 100644 --- a/packages/amis-editor/src/plugin/Form/Form.tsx +++ b/packages/amis-editor/src/plugin/Form/Form.tsx @@ -537,7 +537,7 @@ export class FormPlugin extends BasePlugin { getSchemaTpl('api', { label: '保存接口', description: '用来保存表单数据', - sampleBuilder: (schema: any) => `{ + sampleBuilder: () => `{ "status": 0, "msg": "", @@ -579,8 +579,9 @@ export class FormPlugin extends BasePlugin { name: 'initApi', label: '初始化接口', description: '用来初始化表单数据', - sampleBuilder: (schema: any) => { + sampleBuilder: () => { const data = {}; + const schema = context?.schema; if (Array.isArray(schema?.body)) { schema.body.forEach((control: any) => { diff --git a/packages/amis-editor/src/plugin/Form/InputTree.tsx b/packages/amis-editor/src/plugin/Form/InputTree.tsx index e87d80384..697007af0 100644 --- a/packages/amis-editor/src/plugin/Form/InputTree.tsx +++ b/packages/amis-editor/src/plugin/Form/InputTree.tsx @@ -279,7 +279,7 @@ export class TreeControlPlugin extends BasePlugin { name: 'options' }, getSchemaTpl('source', { - sampleBuilder: (schema: any) => + sampleBuilder: () => JSON.stringify( { status: 0, diff --git a/packages/amis-editor/src/plugin/Form/Item.tsx b/packages/amis-editor/src/plugin/Form/Item.tsx index 74ad8cdc2..542038e26 100644 --- a/packages/amis-editor/src/plugin/Form/Item.tsx +++ b/packages/amis-editor/src/plugin/Form/Item.tsx @@ -105,8 +105,12 @@ export class ItemPlugin extends BasePlugin { getSchemaTpl('switch', { name: 'disabled', label: '禁用', - mode: 'inline', - className: 'w-full' + mode: 'horizontal', + horizontal: { + justify: true, + left: 8 + }, + inputClassName: 'is-inline ' }), ignoreValidator ? null : getSchemaTpl('required'), getSchemaTpl('description'), diff --git a/packages/amis-editor/src/plugin/Form/TreeSelect.tsx b/packages/amis-editor/src/plugin/Form/TreeSelect.tsx index 2d155b20d..652f11209 100644 --- a/packages/amis-editor/src/plugin/Form/TreeSelect.tsx +++ b/packages/amis-editor/src/plugin/Form/TreeSelect.tsx @@ -257,7 +257,14 @@ export class TreeSelectControlPlugin extends BasePlugin { mode: 'vertical' // 改成上下展示模式 }), - getSchemaTpl('clearable'), + getSchemaTpl('clearable', { + mode: 'horizontal', + horizontal: { + justify: true, + left: 8 + }, + inputClassName: 'is-inline ' + }), getSchemaTpl('hideNodePathLabel'), @@ -270,7 +277,7 @@ export class TreeSelectControlPlugin extends BasePlugin { }, getSchemaTpl('source', { - sampleBuilder: (schema: any) => + sampleBuilder: () => JSON.stringify( { status: 0, @@ -369,19 +376,25 @@ export class TreeSelectControlPlugin extends BasePlugin { '!this.autoFill || !this.autoFill.scene && !this.autoFill.action' }), - getSchemaTpl('creatable'), + getSchemaTpl('creatable', { + mode: 'row' + }), getSchemaTpl('api', { label: '新增选项接口', name: 'addApi' }), - getSchemaTpl('editable'), + getSchemaTpl('editable', { + mode: 'row' + }), getSchemaTpl('api', { label: '编辑选项接口', name: 'editApi' }), - getSchemaTpl('removable'), + getSchemaTpl('removable', { + mode: 'row' + }), getSchemaTpl('api', { label: '删除选项接口', name: 'deleteApi' @@ -392,6 +405,7 @@ export class TreeSelectControlPlugin extends BasePlugin { }, { title: '事件', + className: 'p-none', body: [ getSchemaTpl('eventControl', { name: 'onEvent', diff --git a/packages/amis-editor/src/plugin/Page.tsx b/packages/amis-editor/src/plugin/Page.tsx index 0d45fe8a6..9c8407b22 100644 --- a/packages/amis-editor/src/plugin/Page.tsx +++ b/packages/amis-editor/src/plugin/Page.tsx @@ -3,10 +3,7 @@ import {registerEditorPlugin} from 'amis-editor-core'; import {BaseEventContext, BasePlugin} from 'amis-editor-core'; import {getSchemaTpl} from 'amis-editor-core'; import {getEventControlConfig} from '../renderer/event-control/helper'; -import { - RendererPluginAction, - RendererPluginEvent -} from 'amis-editor-core'; +import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core'; import type {SchemaObject} from 'amis/lib/Schema'; export class PagePlugin extends BasePlugin { @@ -176,9 +173,9 @@ export class PagePlugin extends BasePlugin { getSchemaTpl('api', { label: '数据初始化接口', name: 'initApi', - sampleBuilder: (schema: any) => `{ - "status": 0, - "msg": "", + sampleBuilder: () => `{ + "status": 0, + "msg": "", data: { // 示例数据 diff --git a/packages/amis-editor/src/renderer/APIControl.tsx b/packages/amis-editor/src/renderer/APIControl.tsx index 2fae487ae..dd6e25c30 100644 --- a/packages/amis-editor/src/renderer/APIControl.tsx +++ b/packages/amis-editor/src/renderer/APIControl.tsx @@ -9,7 +9,7 @@ import {Input, PickerContainer, Spinner} from 'amis-ui'; import {getEnv} from 'mobx-state-tree'; import {normalizeApi, isEffectiveApi, isApiOutdated} from 'amis-core'; -import {isObject, autobind, createObject, tipedLabel} from 'amis-editor-core'; +import {isObject, autobind, createObject, tipedLabel, anyChanged} from 'amis-editor-core'; import type {SchemaObject, SchemaCollection, SchemaApi} from 'amis/lib/Schema'; import type {Api} from 'amis/lib/types'; @@ -189,13 +189,11 @@ export default class APIControl extends React.Component< componentDidUpdate(prevProps: APIControlProps) { const props = this.props; - - if (!isEqual(prevProps?.value, props?.value)) { + if (prevProps.value !== props.value) { this.setState({apiStr: this.transformApi2Str(props.value)}); this.updatePickerOptions(); } - - if (!isEqual(prevProps?.enablePickerMode, props?.enablePickerMode)) { + if (anyChanged(['enablePickerMode', 'pickerSchema'], prevProps, props)) { this.setState({schema: props.pickerSchema}); } @@ -322,7 +320,6 @@ export default class APIControl extends React.Component< if (typeof value !== 'string' || typeof values !== 'string') { api = merge({}, normalizeApi(values)); } - onChange?.(api); } diff --git a/packages/amis-editor/src/renderer/FormulaControl.tsx b/packages/amis-editor/src/renderer/FormulaControl.tsx index d3915029d..1cef9cb56 100644 --- a/packages/amis-editor/src/renderer/FormulaControl.tsx +++ b/packages/amis-editor/src/renderer/FormulaControl.tsx @@ -13,7 +13,7 @@ import isString from 'lodash/isString'; import isEqual from 'lodash/isEqual'; import omit from 'lodash/omit'; import cx from 'classnames'; -import {FormItem, Button, InputBox, Icon, render, ResultBox} from 'amis'; +import {FormItem, Button, InputBox, Icon, ResultBox} from 'amis'; import {FormulaExec, isExpression} from 'amis'; import {PickerContainer} from 'amis'; import {FormulaEditor} from 'amis-ui/lib/components/formula/Editor'; @@ -333,7 +333,8 @@ export default class FormulaControl extends React.Component< 'suffix', 'unitOptions', 'keyboard', - 'kilobitSeparator' + 'kilobitSeparator', + 'value' ]; // 当前组件要剔除的字段 @@ -364,7 +365,11 @@ export default class FormulaControl extends React.Component< } else { curRendererSchema.placeholder = '请输入静态默认值'; } + + // 设置popOverContainer + curRendererSchema.popOverContainer = window.document.body; } + return curRendererSchema; } @@ -399,6 +404,7 @@ export default class FormulaControl extends React.Component< rendererWrapper, manager, useExternalFormData = false, + render, ...rest } = this.props; @@ -454,21 +460,17 @@ export default class FormulaControl extends React.Component< rendererWrapper ? 'border-wrapper' : '' )} > - {render( - this.filterCustomRendererProps(rendererSchema), - { - data: useExternalFormData - ? { - ...this.props.data - } - : {}, - onChange: this.handleSimpleInputChange, - manager: manager - }, - { - ...(manager?.env || {}) - } - )} + {render('left', this.filterCustomRendererProps(rendererSchema), { + inputOnly: true, + value: value, + data: useExternalFormData + ? { + ...this.props.data + } + : {}, + onChange: this.handleSimpleInputChange, + manager: manager + })} )} {!simple && isExpr && ( diff --git a/packages/amis-editor/src/renderer/event-control/action-config-dialog.tsx b/packages/amis-editor/src/renderer/event-control/action-config-dialog.tsx index bc42d1cdd..6e024e010 100644 --- a/packages/amis-editor/src/renderer/event-control/action-config-dialog.tsx +++ b/packages/amis-editor/src/renderer/event-control/action-config-dialog.tsx @@ -116,7 +116,6 @@ export default class ActionDialog extends React.Component { } const actionNode = findActionNode(actionTree, value); - form.setValues({ ...removeKeys, __keywords: form.data.__keywords, @@ -158,7 +157,6 @@ export default class ActionDialog extends React.Component { commonActions, onClose } = this.props; - return amisRender( { type: 'dialog', diff --git a/packages/amis-editor/src/renderer/event-control/actions.tsx b/packages/amis-editor/src/renderer/event-control/actions.tsx index 2763d2c2e..a286bdc2f 100644 --- a/packages/amis-editor/src/renderer/event-control/actions.tsx +++ b/packages/amis-editor/src/renderer/event-control/actions.tsx @@ -15,7 +15,7 @@ import { renderCmptSelect, SUPPORT_DISABLED_CMPTS } from './helper'; - +import {BaseLabelMark} from '../../component/BaseControl'; const MSG_TYPES: {[key: string]: string} = { info: '提示', warning: '警告', @@ -57,7 +57,8 @@ const ACTION_TYPE_TREE = (manager: any): RendererPluginAction[] => { placeholder: 'http://', mode: 'horizontal', size: 'lg', - required: true + required: true, + visibleOn: 'data.actionType === "url"' }, { type: 'combo', @@ -108,7 +109,7 @@ const ACTION_TYPE_TREE = (manager: any): RendererPluginAction[] => {
打开 - {info?.args?.__pageName} + {info?.args?.pageName} 页面
@@ -191,6 +192,7 @@ const ACTION_TYPE_TREE = (manager: any): RendererPluginAction[] => { manager.openSubEditor({ title: '配置弹框内容', value: {type: 'dialog', ...value}, + data, onChange: (value: any) => onChange(value) }) } @@ -448,16 +450,16 @@ const ACTION_TYPE_TREE = (manager: any): RendererPluginAction[] => { type: 'checkbox', name: 'silent', option: '静默模式', + mode: 'inline', + className: 'm-r-none', + value: false, remark: { className: 'ae-BaseRemark', icon: 'fa fa-question-circle', - trigger: ['hover', 'click'], - placement: 'left', + shape: "circle", + placement: "left", content: '勾选后,服务请求将以静默模式发送,即不会弹出成功或报错提示。' - }, - mode: 'inline', - className: 'm-r-none', - value: false + } } ] } @@ -466,15 +468,35 @@ const ACTION_TYPE_TREE = (manager: any): RendererPluginAction[] => { { name: 'outputVar', type: 'input-text', - label: '请求出参', + label: '存储结果', placeholder: '请输入存储请求结果的变量名称', - description: '后面的动作可以通过\\${event.data.请求出参名称}来获取本次请求的返回结果', + description: '如需执行多次发送请求,可以修改此变量名用于区分不同请求返回的结果', mode: 'horizontal', size: 'lg', + value: 'responseResult', required: true } ] - } + }, + outputVarDataSchema: [ + { + type: 'object', + properties: { + 'event.data.${outputVar}.responseData': { + type: 'object', + title: '数据' + }, + 'event.data.${outputVar}.responseStatus': { + type: 'number', + title: '状态标识' + }, + 'event.data.${outputVar}.responseMsg': { + type: 'string', + title: '提示信息' + } + } + } + ] }, { actionLabel: '下载文件', @@ -487,7 +509,11 @@ const ACTION_TYPE_TREE = (manager: any): RendererPluginAction[] => { body: [ getArgsWrapper( getSchemaTpl('apiControl', { - name: 'api' + name: 'api', + label: '配置请求', + mode: 'horizontal', + size: 'lg', + required: true }) ) ] @@ -692,7 +718,7 @@ const ACTION_TYPE_TREE = (manager: any): RendererPluginAction[] => { mode: 'horizontal', label: '输入序号', placeholder: '请输入待更新序号', - visibleOn: `data.__comboType && __comboType === 'appoint'` + visibleOn: `data.__comboType && __comboType === 'appoint' && data.__rendererName && __rendererName === 'combo'` }, { type: 'combo', diff --git a/packages/amis-editor/src/renderer/event-control/helper.tsx b/packages/amis-editor/src/renderer/event-control/helper.tsx index 3a52be717..d1718c3d2 100644 --- a/packages/amis-editor/src/renderer/event-control/helper.tsx +++ b/packages/amis-editor/src/renderer/event-control/helper.tsx @@ -13,10 +13,17 @@ import { SubRendererPluginAction } from 'amis-editor-core'; import {ActionConfig, ContextVariables} from './types'; -import {DataSchema, filterTree, findTree, mapTree, normalizeApi} from 'amis-core'; +import { + DataSchema, + filterTree, + findTree, + mapTree, + normalizeApi +} from 'amis-core'; import CmptActionSelect from './comp-action-select'; import {Button} from 'amis'; import ACTION_TYPE_TREE from './actions'; +import { stores } from 'amis-core/lib/factory'; // 数据容器范围 export const DATA_CONTAINER = [ @@ -31,9 +38,7 @@ export const DATA_CONTAINER = [ ]; // 下拉展示可赋值属性范围 -export const SELECT_PROPS_CONTAINER = [ - 'form', -]; +export const SELECT_PROPS_CONTAINER = ['form']; // 是否数据容器 export const IS_DATA_CONTAINER = `${JSON.stringify( @@ -45,7 +50,6 @@ export const SHOW_SELECT_PROP = `${JSON.stringify( SELECT_PROPS_CONTAINER )}.includes(__rendererName)`; - // 表单项组件 export const FORMITEM_CMPTS = [ 'button-group-select', @@ -129,7 +133,7 @@ export const SUPPORT_DISABLED_CMPTS = [ 'nav', 'wizard' // 'card2' -] +]; export const getArgsWrapper = (items: any, multiple: boolean = false) => ({ type: 'combo', @@ -191,7 +195,7 @@ export const COMMON_ACTION_SCHEMA_MAP: { labelField: 'label', valueField: 'value', required: true, - visibleOn: `data.__rendererName && ${SHOW_SELECT_PROP}`, + visibleOn: `data.__rendererName && ${SHOW_SELECT_PROP}` }, { name: 'key', @@ -316,7 +320,9 @@ export const COMMON_ACTION_SCHEMA_MAP: { return (
提交 - {info?.rendererLabel} + + {info?.rendererLabel} + {info?.__rendererName === 'wizard' ? '全部数据' : '数据'}
); @@ -536,7 +542,7 @@ export const renderCmptActionSelect = ( true, async (value: string, oldVal: any, data: any, form: any) => { // 获取组件上下文. - const rendererType = form.data.__rendererName + const rendererType = form.data.__rendererName; if (form.data.__nodeId) { const dataSchema: any = await form.data.getContextSchemas?.( form.data.__nodeId, @@ -560,9 +566,13 @@ export const renderCmptActionSelect = ( if (form.data.actionType === 'setValue') { // todo:这里会闪一下,需要从amis查下问题 form.setValueByName('args.value', []); + form.setValueByName('args.__comboType', undefined); form.setValueByName('args.__valueInput', undefined); if (SELECT_PROPS_CONTAINER.includes(rendererType)) { - form.setValueByName('__setValueDs', variables.filter(item => item.value !== '$$id')); + form.setValueByName( + '__setValueDs', + variables.filter(item => item.value !== '$$id') + ); } else { form.setValueByName('__setValueDs', []); } @@ -595,7 +605,7 @@ export const getOldActionSchema = ( content: '温馨提示:添加下方事件动作后,下方事件动作将先于旧版动作执行,建议统一迁移至事件动作机制,帮助您实现更灵活的交互设计', inline: true, - tooltipTheme: "dark", + tooltipTheme: 'dark', body: [ { type: 'button', @@ -948,6 +958,7 @@ export const getEventControlConfig = ( manager: EditorManager, context: BaseEventContext ) => { + const isSubEditor = manager.store.isSubEditor; // 通用动作配置 const commonActions = manager?.config.actionOptions?.customActionGetter?.(manager); @@ -955,11 +966,53 @@ export const getEventControlConfig = ( const actionTree = manager?.config.actionOptions?.actionTreeGetter ? manager?.config.actionOptions?.actionTreeGetter(ACTION_TYPE_TREE(manager)) : ACTION_TYPE_TREE(manager); - + const allComponents = mapTree( + manager?.store?.outline ?? [], + (item: any) => { + const schema = manager?.store?.getSchema(item.id); + return { + id: item.id, + label: item.label, + value: schema?.id ?? item.id, + type: schema?.type ?? item.type, + schema, + disabled: !!item.region, + children: item?.children + }; + }, + 1, + true + ); + const checkComponent = (node: any, action: RendererPluginAction) => { + const actionType = action.actionType!; + const actions = manager?.pluginActions[node.type]; + const haveChild = !!node.children?.length; + let isSupport = false; + if (typeof action.supportComponents === 'string') { + isSupport = + action.supportComponents === '*' || + action.supportComponents === node.type; + } else if (Array.isArray(action.supportComponents)) { + isSupport = action.supportComponents.includes(node.type); + } + if (['reload', 'setValue'].includes(actionType)) { + isSupport = hasActionType(actionType, actions); + } + if (actionType === 'component' && !actions?.length) { + node.disabled = true; + } + if (isSupport) { + return true; + } else if (haveChild) { + node.disabled = true; + return true; + } + return false; + } return { - showOldEntry: manager?.config.actionOptions?.showOldEntry !== false && - (!!context.schema.actionType || - ['submit', 'reset'].includes(context.schema.type)), + showOldEntry: + !!context.schema.actionType || + ['submit', 'reset'].includes(context.schema.type), actions: manager?.pluginActions, events: manager?.pluginEvents, actionTree, @@ -967,6 +1020,7 @@ export const getEventControlConfig = ( owner: '', addBroadcast: manager?.addBroadcast, removeBroadcast: manager?.removeBroadcast, + allComponents: allComponents, getContextSchemas: async (id?: string, withoutSuper?: boolean) => { const dataSchema = await manager.getContextSchemas( id ?? context!.id, @@ -979,64 +1033,28 @@ export const getEventControlConfig = ( return manager.dataSchema; }, getComponents: (action: RendererPluginAction) => { - const actionType = action.actionType!; - const components = filterTree( - mapTree( - manager?.store?.outline ?? [], - (item: any) => { - const schema = manager?.store?.getSchema(item.id); - return { - id: item.id, - label: item.label, - value: schema?.id ?? item.id, - type: schema?.type ?? item.type, - schema, - disabled: !!item.region, - children: item?.children - }; - }, - 1, - true - ), - node => { - const actions = manager?.pluginActions[node.type]; - let isSupport = false; - if (typeof action.supportComponents === 'string') { - isSupport = - action.supportComponents === '*' || - action.supportComponents === node.type; - } else if (Array.isArray(action.supportComponents)) { - isSupport = action.supportComponents.includes(node.type); + let components = allComponents; + if (isSubEditor) { + let superTree = manager.store.getSuperEditorData; + while(superTree) { + if (superTree.__superCmptTreeSource) { + components = components.concat(superTree.__superCmptTreeSource); } - if (['reload', 'setValue'].includes(actionType)) { - isSupport = hasActionType(actionType, actions); - } - - if (actionType === 'component' && !actions?.length) { - node.disabled = true; - } - - if (isSupport) { - return true; - } else if (!isSupport && !!node.children?.length) { - node.disabled = true; - return true; - } - return false; - }, + superTree = superTree.__super; + } + } + const result = filterTree( + components, + (node) => checkComponent(node, action), 1, true ); - - return components; + return result; }, actionConfigInitFormatter: (action: ActionConfig) => { let config = {...action}; - if ( - ['setValue', 'url'].includes(action.actionType) && - action.args - ) { + if (['setValue', 'url'].includes(action.actionType) && action.args) { const prop = action.actionType === 'setValue' ? 'value' : 'params'; !config.args && (config.args = {}); if (Array.isArray(action.args[prop])) { @@ -1072,7 +1090,10 @@ export const getEventControlConfig = ( delete config.args?.value; } } - if (action.actionType === 'ajax' && typeof action?.args?.api === 'string') { + if ( + action.actionType === 'ajax' && + typeof action?.args?.api === 'string' + ) { action.args.api = normalizeApi(action?.args?.api); } // 获取动作专有配置参数 @@ -1130,10 +1151,7 @@ export const getEventControlConfig = ( // 标记一下组件特性动作 action.groupType = config.actionType; } - const hasSubActionNode = findSubActionNode( - actionTree, - config.groupType - ); + const hasSubActionNode = findSubActionNode(actionTree, config.groupType); if (hasSubActionNode) { // 修正动作 action.actionType = config.groupType; @@ -1153,13 +1171,19 @@ export const getEventControlConfig = ( // 转换下格式 if (['setValue', 'url'].includes(action.actionType)) { const propName = action.actionType === 'setValue' ? 'value' : 'params'; - if (action.actionType === 'setValue' && config.args?.__valueInput !== undefined) { + if ( + action.actionType === 'setValue' && + config.args?.__valueInput !== undefined + ) { action.args = { value: config.args?.__valueInput }; } else if (Array.isArray(config.args?.[propName])) { action.args = action.args ?? {}; - if (action.__rendererName === 'combo' && action.args?.index === undefined) { + if ( + action.__rendererName === 'combo' && + action.args?.index === undefined + ) { // combo特殊处理 let tempArr: any = []; config.args?.[propName].forEach((valueItem: any, index: number) => { @@ -1197,4 +1221,4 @@ export const getEventControlConfig = ( return action; } }; -}; \ No newline at end of file +}; diff --git a/packages/amis-editor/src/renderer/event-control/index.tsx b/packages/amis-editor/src/renderer/event-control/index.tsx index 7046987d3..05a18b23b 100644 --- a/packages/amis-editor/src/renderer/event-control/index.tsx +++ b/packages/amis-editor/src/renderer/event-control/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {findDOMNode} from 'react-dom'; import cx from 'classnames'; import Sortable from 'sortablejs'; -import {DataSchema, FormItem, Icon, TooltipWrapper} from 'amis'; +import {DataSchema, FormItem, Button, Icon, TooltipWrapper} from 'amis'; import cloneDeep from 'lodash/cloneDeep'; import { FormControlProps, @@ -73,6 +73,7 @@ interface EventControlState { groupType?: string; __actionDesc?: string; __cmptTreeSource?: ComponentInfo[]; + __superCmptTreeSource?: ComponentInfo[]; __actionSchema?: any; __subActions?: SubRendererPluginAction[]; __setValueDs?: any[]; @@ -445,36 +446,36 @@ export class EventControl extends React.Component< // 收集当前事件已有ajax动作的请求返回结果作为事件变量 let oldActions = onEvent[activeData.actionData!.eventKey].actions; if (activeData.type === 'update') { - oldActions = oldActions.slice( - 0, - activeData.actionData!.actionIndex || oldActions?.length - ); + // 编辑的时候只能拿到当前动作前面动作的事件变量 + oldActions = oldActions.slice(0, activeData.actionData!.actionIndex); } const withOutputVarActions = oldActions?.filter(item => item.outputVar); - const withOutputVarVariables = withOutputVarActions?.map( - (item: any, index: number) => { - const actionLabel = getPropOfAcion( - item, - 'actionLabel', - actionTree, - pluginActions, - commonActions - ); - return { - label: `${ - item.outputVar - ? item.outputVar + `(${actionLabel}结果)` - : `${actionLabel}结果` - }`, - tag: 'object', - type: 'object', - value: `${ - item.outputVar ? 'event.data.' + item.outputVar : 'event.data' - }` - }; - } - ); + const withOutputVarVariables = withOutputVarActions?.map((item: any, index: number) => { + const actionLabel = getPropOfAcion( + item, + 'actionLabel', + actionTree, + pluginActions, + commonActions + ); + const dataSchemaJson = getPropOfAcion( + item, + 'outputVarDataSchema', + actionTree, + pluginActions, + commonActions + ); + const dataSchema = new DataSchema(dataSchemaJson || []); + return { + label: `${item.outputVar ? item.outputVar + `(${actionLabel}结果)` : `${actionLabel}结果`}`, + tag: 'object', + children: dataSchema.getDataPropsAsOptions()?.map(variable => ({ + ...variable, + value: variable.value.replace('${outputVar}', item.outputVar) + })) + }; + }); const eventVariables: ContextVariables[] = [ { label: '事件变量', @@ -503,13 +504,13 @@ export class EventControl extends React.Component< getContextSchemas, actionConfigInitFormatter, getComponents, - actionTree + actionTree, + allComponents } = this.props; const {rawVariables} = this.state; // 收集事件变量 const eventVariables = this.getEventVariables(data); const variables = [...eventVariables, ...rawVariables]; - // 编辑操作,需要格式化动作配置 if (data.type === 'update') { const action = data.actionData!.action!; @@ -532,7 +533,7 @@ export class EventControl extends React.Component< item => item.value !== '$$id' ); } - } + }; data.actionData = { eventKey: data.actionData!.eventKey, actionIndex: data.actionData!.actionIndex, @@ -548,6 +549,8 @@ export class EventControl extends React.Component< __cmptTreeSource: actionConfig?.componentId ? getComponents?.(actionNode!) ?? [] : [], + __superCmptTreeSource: allComponents, + // __supersCmptTreeSource: '', __setValueDs: setValueDs // broadcastId: action.actionType === 'broadcast' ? action.eventName : '' }; @@ -565,10 +568,10 @@ export class EventControl extends React.Component< variables, pluginActions, getContextSchemas, - rawVariables + rawVariables, + __superCmptTreeSource: allComponents }; } - this.setState(data); } diff --git a/packages/amis-editor/src/tpl/api.tsx b/packages/amis-editor/src/tpl/api.tsx index 046104ecb..856d062c8 100644 --- a/packages/amis-editor/src/tpl/api.tsx +++ b/packages/amis-editor/src/tpl/api.tsx @@ -20,19 +20,15 @@ setSchemaTpl('api', (patch: any = {}) => { icon: 'fas fa-code', className: 'm-l-xs ae-ApiSample-icon', tooltipClassName: 'ae-ApiSample-tooltip', - children: () => { - return ( - ${sampleBuilder()}${ - apiDesc - ? `${apiDesc}` - : '' - }`} - /> - ); - }, + children: (data: any) => ( + ${sampleBuilder(data)} + `} + /> + ), trigger: 'click', rootClose: true, placement: 'left' @@ -321,7 +317,7 @@ setSchemaTpl('source', (patch: any = {}) => { name: 'source', label: '获取选项接口', description: '可以通过接口获取动态选项,一次拉取全部。', - sampleBuilder: (schema: any) => + sampleBuilder: () => JSON.stringify( { status: 0, @@ -442,19 +438,15 @@ setSchemaTpl('apiControl', (patch: any = {}) => { icon: 'fas fa-code', className: 'm-l-xs ae-ApiSample-icon', tooltipClassName: 'ae-ApiSample-tooltip', - children: () => { - return ( - ${sampleBuilder()}${ - apiDesc - ? `${apiDesc}` - : '' - }`} - /> - ); - }, + children: (data: any) => ( + ${sampleBuilder(data)} + `} + /> + ), trigger: 'click', rootClose: true, placement: 'left' @@ -526,7 +518,7 @@ setSchemaTpl('actionApiControl', (patch: any = {}) => { label: '示例', title: '接口返回示例', tooltipClassName: 'ae-ApiSample-tooltip', - render: (data: any) => ( + children: (data: any) => (