mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: 编辑器支持只读模式 (#10857)
* feat: 扩展编辑器功能 * 弹框支持readonly * bugfix * bugfix --------- Co-authored-by: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com> Co-authored-by: hsm-lv <80095014+hsm-lv@users.noreply.github.com>
This commit is contained in:
parent
859ae8d72a
commit
13f1890db7
@ -83,6 +83,7 @@
|
|||||||
min-width: 980px;
|
min-width: 980px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
// 覆盖amis默认top值,避免导致未垂直居中
|
// 覆盖amis默认top值,避免导致未垂直居中
|
||||||
.ae-Editor-toolbar svg.icon {
|
.ae-Editor-toolbar svg.icon {
|
||||||
@ -125,6 +126,18 @@
|
|||||||
border: 1px dashed rgb(206, 208, 211);
|
border: 1px dashed rgb(206, 208, 211);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.subEditor-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
& .subEditor-dialog {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 弹窗编辑器面板
|
// 弹窗编辑器面板
|
||||||
.subEditor-dialog {
|
.subEditor-dialog {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -135,6 +135,7 @@ export interface EditorProps extends PluginEventListener {
|
|||||||
getHostNodeDataSchema?: () => Promise<any>;
|
getHostNodeDataSchema?: () => Promise<any>;
|
||||||
|
|
||||||
getAvaiableContextFields?: (node: EditorNodeType) => Promise<any>;
|
getAvaiableContextFields?: (node: EditorNodeType) => Promise<any>;
|
||||||
|
readonly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Editor extends Component<EditorProps> {
|
export default class Editor extends Component<EditorProps> {
|
||||||
@ -275,6 +276,10 @@ export default class Editor extends Component<EditorProps> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.readonly) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const manager = this.manager;
|
const manager = this.manager;
|
||||||
const store = manager.store;
|
const store = manager.store;
|
||||||
|
|
||||||
@ -573,7 +578,8 @@ export default class Editor extends Component<EditorProps> {
|
|||||||
previewProps,
|
previewProps,
|
||||||
autoFocus,
|
autoFocus,
|
||||||
isSubEditor,
|
isSubEditor,
|
||||||
amisEnv
|
amisEnv,
|
||||||
|
readonly
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -588,7 +594,7 @@ export default class Editor extends Component<EditorProps> {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="ae-Editor-inner" onContextMenu={this.handleContextMenu}>
|
<div className="ae-Editor-inner" onContextMenu={this.handleContextMenu}>
|
||||||
{!preview && (
|
{!preview && !readonly && (
|
||||||
<LeftPanels
|
<LeftPanels
|
||||||
store={this.store}
|
store={this.store}
|
||||||
manager={this.manager}
|
manager={this.manager}
|
||||||
@ -618,6 +624,7 @@ export default class Editor extends Component<EditorProps> {
|
|||||||
amisEnv={amisEnv}
|
amisEnv={amisEnv}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
toolbarContainer={this.getToolbarContainer}
|
toolbarContainer={this.getToolbarContainer}
|
||||||
|
readonly={readonly}
|
||||||
></Preview>
|
></Preview>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -628,6 +635,7 @@ export default class Editor extends Component<EditorProps> {
|
|||||||
theme={theme}
|
theme={theme}
|
||||||
appLocale={appLocale}
|
appLocale={appLocale}
|
||||||
amisEnv={amisEnv}
|
amisEnv={amisEnv}
|
||||||
|
readonly={readonly}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -639,6 +647,7 @@ export default class Editor extends Component<EditorProps> {
|
|||||||
manager={this.manager}
|
manager={this.manager}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
amisEnv={amisEnv}
|
amisEnv={amisEnv}
|
||||||
|
readonly={readonly}
|
||||||
/>
|
/>
|
||||||
<ScaffoldModal
|
<ScaffoldModal
|
||||||
store={this.store}
|
store={this.store}
|
||||||
|
@ -19,6 +19,7 @@ export interface HighlightBoxProps {
|
|||||||
onSwitch?: (id: string) => void;
|
onSwitch?: (id: string) => void;
|
||||||
manager: EditorManager;
|
manager: EditorManager;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
readonly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default observer(function ({
|
export default observer(function ({
|
||||||
@ -30,7 +31,8 @@ export default observer(function ({
|
|||||||
node,
|
node,
|
||||||
toolbarContainer,
|
toolbarContainer,
|
||||||
onSwitch,
|
onSwitch,
|
||||||
manager
|
manager,
|
||||||
|
readonly
|
||||||
}: HighlightBoxProps) {
|
}: HighlightBoxProps) {
|
||||||
const handleWResizerMouseDown = React.useCallback(
|
const handleWResizerMouseDown = React.useCallback(
|
||||||
(e: MouseEvent) => startResize(e, 'horizontal'),
|
(e: MouseEvent) => startResize(e, 'horizontal'),
|
||||||
@ -250,7 +252,7 @@ export default observer(function ({
|
|||||||
draggable={!!curFreeContainerId || isDraggableContainer}
|
draggable={!!curFreeContainerId || isDraggableContainer}
|
||||||
onDragStart={handleDragStart}
|
onDragStart={handleDragStart}
|
||||||
>
|
>
|
||||||
{isActive ? (
|
{isActive && !readonly ? (
|
||||||
<div
|
<div
|
||||||
className={`ae-Editor-toolbarPopover ${
|
className={`ae-Editor-toolbarPopover ${
|
||||||
isRightElem ? 'is-right-elem' : ''
|
isRightElem ? 'is-right-elem' : ''
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Tab, Tabs} from 'amis';
|
import {Tab, Tabs, toast} from 'amis';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import {EditorManager} from '../../manager';
|
import {EditorManager} from '../../manager';
|
||||||
import {EditorStoreType} from '../../store/editor';
|
import {EditorStoreType} from '../../store/editor';
|
||||||
@ -16,6 +16,7 @@ interface RightPanelsProps {
|
|||||||
theme?: string;
|
theme?: string;
|
||||||
appLocale?: string;
|
appLocale?: string;
|
||||||
amisEnv?: any;
|
amisEnv?: any;
|
||||||
|
readonly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RightPanelsStates {
|
interface RightPanelsStates {
|
||||||
@ -62,6 +63,29 @@ export class RightPanels extends React.Component<
|
|||||||
return findDOMNode(this) as HTMLElement;
|
return findDOMNode(this) as HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
handlePanelChangeValue(
|
||||||
|
...arg: Parameters<typeof this.props.manager.panelChangeValue>
|
||||||
|
) {
|
||||||
|
const {manager, readonly} = this.props;
|
||||||
|
|
||||||
|
if (readonly) {
|
||||||
|
const diff = arg[1];
|
||||||
|
if (
|
||||||
|
!diff?.find((item: any) =>
|
||||||
|
item.path.find(
|
||||||
|
(p: string) => !p.startsWith('__') && p !== 'pullRefresh'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toast.error('不支持编辑');
|
||||||
|
} else {
|
||||||
|
manager.panelChangeValue(...arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {store, manager, theme} = this.props;
|
const {store, manager, theme} = this.props;
|
||||||
const {isOpenStatus, isFixedStatus} = this.state;
|
const {isOpenStatus, isFixedStatus} = this.state;
|
||||||
@ -77,7 +101,7 @@ export class RightPanels extends React.Component<
|
|||||||
path: node?.path,
|
path: node?.path,
|
||||||
node: node,
|
node: node,
|
||||||
value: store.value,
|
value: store.value,
|
||||||
onChange: manager.panelChangeValue,
|
onChange: this.handlePanelChangeValue,
|
||||||
store: store,
|
store: store,
|
||||||
manager: manager,
|
manager: manager,
|
||||||
popOverContainer: this.getPopOverContainer
|
popOverContainer: this.getPopOverContainer
|
||||||
@ -90,7 +114,7 @@ export class RightPanels extends React.Component<
|
|||||||
info={node?.info}
|
info={node?.info}
|
||||||
path={node?.path}
|
path={node?.path}
|
||||||
value={store.value}
|
value={store.value}
|
||||||
onChange={manager.panelChangeValue}
|
onChange={this.handlePanelChangeValue}
|
||||||
store={store}
|
store={store}
|
||||||
manager={manager}
|
manager={manager}
|
||||||
popOverContainer={this.getPopOverContainer}
|
popOverContainer={this.getPopOverContainer}
|
||||||
|
@ -39,6 +39,8 @@ export interface PreviewProps {
|
|||||||
autoFocus?: boolean;
|
autoFocus?: boolean;
|
||||||
|
|
||||||
toolbarContainer?: () => any;
|
toolbarContainer?: () => any;
|
||||||
|
|
||||||
|
readonly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PreviewState {
|
export interface PreviewState {
|
||||||
@ -604,9 +606,11 @@ export default class Preview extends Component<PreviewProps> {
|
|||||||
toolbarContainer={toolbarContainer}
|
toolbarContainer={toolbarContainer}
|
||||||
onSwitch={this.handleNavSwitch}
|
onSwitch={this.handleNavSwitch}
|
||||||
manager={manager}
|
manager={manager}
|
||||||
|
readonly={this.props.readonly}
|
||||||
>
|
>
|
||||||
{node.childRegions.map(region =>
|
{node.childRegions.map(region =>
|
||||||
!node.memberImmutable(region.region) &&
|
!node.memberImmutable(region.region) &&
|
||||||
|
!this.props.readonly &&
|
||||||
store.isRegionActive(region.id, region.region) ? (
|
store.isRegionActive(region.id, region.region) ? (
|
||||||
<RegionHighlightBox
|
<RegionHighlightBox
|
||||||
manager={manager}
|
manager={manager}
|
||||||
|
@ -19,6 +19,7 @@ export interface SubEditorProps {
|
|||||||
manager: EditorManager;
|
manager: EditorManager;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
amisEnv?: RenderOptions;
|
amisEnv?: RenderOptions;
|
||||||
|
readonly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
@ -97,7 +98,7 @@ export class SubEditor extends React.Component<SubEditorProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildSchema() {
|
buildSchema() {
|
||||||
const {store, manager, amisEnv} = this.props;
|
const {store, manager, amisEnv, readonly} = this.props;
|
||||||
const subEditorContext = store.subEditorContext;
|
const subEditorContext = store.subEditorContext;
|
||||||
const config = manager.config;
|
const config = manager.config;
|
||||||
let superEditorData: any = store.superEditorData;
|
let superEditorData: any = store.superEditorData;
|
||||||
@ -118,6 +119,7 @@ export class SubEditor extends React.Component<SubEditorProps> {
|
|||||||
? {
|
? {
|
||||||
type: 'form',
|
type: 'form',
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
|
wrapWithPanel: false,
|
||||||
wrapperComponent: 'div',
|
wrapperComponent: 'div',
|
||||||
onValidate: async (value: any) => {
|
onValidate: async (value: any) => {
|
||||||
const result = await store.subEditorContext?.validate?.(value);
|
const result = await store.subEditorContext?.validate?.(value);
|
||||||
@ -190,6 +192,7 @@ export class SubEditor extends React.Component<SubEditorProps> {
|
|||||||
getAvaiableContextFields={node =>
|
getAvaiableContextFields={node =>
|
||||||
manager.getAvailableContextFields(node)
|
manager.getAvailableContextFields(node)
|
||||||
}
|
}
|
||||||
|
readonly={readonly}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -244,10 +247,14 @@ export class SubEditor extends React.Component<SubEditorProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {store, theme, manager} = this.props;
|
const {store, theme, manager, readonly} = this.props;
|
||||||
|
if (!store.subEditorContext) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return render(
|
return render(
|
||||||
{
|
{
|
||||||
type: 'dialog',
|
type: readonly ? 'container' : 'dialog',
|
||||||
|
className: readonly ? 'subEditor-container' : 'subEditor-dialog',
|
||||||
...this.buildSchema()
|
...this.buildSchema()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -101,6 +101,8 @@ export function SchemaFrom({
|
|||||||
return schema;
|
return schema;
|
||||||
}, [body, controls, submitOnChange]);
|
}, [body, controls, submitOnChange]);
|
||||||
|
|
||||||
|
const [init, setInit] = React.useState(true);
|
||||||
|
|
||||||
const themeConfig = React.useMemo(() => getThemeConfig(), []);
|
const themeConfig = React.useMemo(() => getThemeConfig(), []);
|
||||||
const submitSubscribers = React.useRef<Array<Function>>([]);
|
const submitSubscribers = React.useRef<Array<Function>>([]);
|
||||||
const subscribeSubmit = React.useCallback(
|
const subscribeSubmit = React.useCallback(
|
||||||
@ -147,10 +149,10 @@ export function SchemaFrom({
|
|||||||
newValue = pipeOut ? await pipeOut(newValue, value) : newValue;
|
newValue = pipeOut ? await pipeOut(newValue, value) : newValue;
|
||||||
const diffValue = diff(value, newValue);
|
const diffValue = diff(value, newValue);
|
||||||
// 没有变化时不触发onChange
|
// 没有变化时不触发onChange
|
||||||
if (!diffValue) {
|
if (!diffValue || init) {
|
||||||
|
setInit(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(newValue, diffValue, (schema, value, id, diff) => {
|
onChange(newValue, diffValue, (schema, value, id, diff) => {
|
||||||
return submitSubscribers.current.reduce((schema, fn) => {
|
return submitSubscribers.current.reduce((schema, fn) => {
|
||||||
return fn(schema, value, id, diff);
|
return fn(schema, value, id, diff);
|
||||||
|
@ -1029,6 +1029,9 @@ export abstract class BasePlugin implements PluginInterface {
|
|||||||
|
|
||||||
static scene = ['global'];
|
static scene = ['global'];
|
||||||
|
|
||||||
|
name?: string;
|
||||||
|
rendererName?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如果配置里面有 rendererName 自动返回渲染器信息。
|
* 如果配置里面有 rendererName 自动返回渲染器信息。
|
||||||
* @param renderer
|
* @param renderer
|
||||||
@ -1279,6 +1282,13 @@ export abstract class BasePlugin implements PluginInterface {
|
|||||||
originalValue: node.schema.value // 记录原始值,循环引用检测需要
|
originalValue: node.schema.value // 记录原始值,循环引用检测需要
|
||||||
} as any;
|
} as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getKeyAndName() {
|
||||||
|
return {
|
||||||
|
key: this.rendererName,
|
||||||
|
name: this.name
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +23,8 @@ import {
|
|||||||
appTranslate,
|
appTranslate,
|
||||||
JSONGetByPath,
|
JSONGetByPath,
|
||||||
addModal,
|
addModal,
|
||||||
mergeDefinitions
|
mergeDefinitions,
|
||||||
|
getModals
|
||||||
} from '../../src/util';
|
} from '../../src/util';
|
||||||
import {
|
import {
|
||||||
InsertEventContext,
|
InsertEventContext,
|
||||||
@ -404,6 +405,9 @@ export const MainStore = types
|
|||||||
): EditorNodeType | undefined {
|
): EditorNodeType | undefined {
|
||||||
return self.root.getNodeById(id, regionOrType);
|
return self.root.getNodeById(id, regionOrType);
|
||||||
},
|
},
|
||||||
|
getNodeByComponentId(id: string): EditorNodeType | undefined {
|
||||||
|
return self.root.getNodeByComponentId(id);
|
||||||
|
},
|
||||||
|
|
||||||
get activeNodeInfo(): RendererInfo | null | undefined {
|
get activeNodeInfo(): RendererInfo | null | undefined {
|
||||||
return this.getNodeById(self.activeId)?.info;
|
return this.getNodeById(self.activeId)?.info;
|
||||||
@ -1039,64 +1043,7 @@ export const MainStore = types
|
|||||||
// 获取弹窗大纲列表
|
// 获取弹窗大纲列表
|
||||||
get modals(): Array<EditorModalBody> {
|
get modals(): Array<EditorModalBody> {
|
||||||
const schema = self.schema;
|
const schema = self.schema;
|
||||||
const modals: Array<DialogSchema | DrawerSchema> = [];
|
const modals: Array<DialogSchema | DrawerSchema> = getModals(schema);
|
||||||
|
|
||||||
JSONTraverse(schema, (value: any, key: string, host: any) => {
|
|
||||||
if (
|
|
||||||
key === 'actionType' &&
|
|
||||||
['dialog', 'drawer', 'confirmDialog'].includes(value)
|
|
||||||
) {
|
|
||||||
const key = value === 'drawer' ? 'drawer' : 'dialog';
|
|
||||||
const body = host[key] || host['args'];
|
|
||||||
if (
|
|
||||||
body &&
|
|
||||||
!body.$ref &&
|
|
||||||
!modals.find(item => item.$$id === body.$$id)
|
|
||||||
) {
|
|
||||||
modals.push({
|
|
||||||
...body,
|
|
||||||
type: key,
|
|
||||||
actionType: value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 公共组件排在前面
|
|
||||||
Object.keys(schema.definitions || {})
|
|
||||||
.reverse()
|
|
||||||
.forEach(key => {
|
|
||||||
const definition = schema.definitions[key];
|
|
||||||
if (['dialog', 'drawer'].includes(definition.type)) {
|
|
||||||
// 不要把已经内嵌弹窗中的弹窗再放到外面
|
|
||||||
if (
|
|
||||||
definition.$$originId &&
|
|
||||||
modals.find(item => item.$$id === definition.$$originId)
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
modals.unshift({
|
|
||||||
...definition,
|
|
||||||
$$ref: key
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 子弹窗时,自己就是个弹窗
|
|
||||||
if (['dialog', 'drawer', 'confirmDialog'].includes(schema.type)) {
|
|
||||||
const idx = modals.findIndex(item => item.$$id === schema.$$id);
|
|
||||||
if (~idx) {
|
|
||||||
modals.splice(idx, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
modals.unshift({
|
|
||||||
...schema,
|
|
||||||
// 如果还包含这个,子弹窗里面收集弹窗的时候会出现多份内嵌弹窗
|
|
||||||
definitions: undefined
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return modals;
|
return modals;
|
||||||
},
|
},
|
||||||
@ -1367,7 +1314,8 @@ export const MainStore = types
|
|||||||
setActiveId(
|
setActiveId(
|
||||||
id: string,
|
id: string,
|
||||||
region: string = '',
|
region: string = '',
|
||||||
selections: Array<string> = []
|
selections: Array<string> = [],
|
||||||
|
onEditorActive: boolean = true
|
||||||
) {
|
) {
|
||||||
const node = id ? self.getNodeById(id) : undefined;
|
const node = id ? self.getNodeById(id) : undefined;
|
||||||
|
|
||||||
@ -1381,6 +1329,39 @@ export const MainStore = types
|
|||||||
// if (!self.panelKey && id) {
|
// if (!self.panelKey && id) {
|
||||||
// self.panelKey = 'config';
|
// self.panelKey = 'config';
|
||||||
// }
|
// }
|
||||||
|
const schema = self.getSchema(id);
|
||||||
|
|
||||||
|
onEditorActive && (window as any).onEditorActive?.(schema);
|
||||||
|
},
|
||||||
|
|
||||||
|
setActiveIdByComponentId(id: string) {
|
||||||
|
const node = self.getNodeByComponentId(id);
|
||||||
|
if (node) {
|
||||||
|
this.setActiveId(node.id, node.region, [], false);
|
||||||
|
this.closeSubEditor();
|
||||||
|
} else {
|
||||||
|
const modals = self.modals;
|
||||||
|
const modalSchema = find(modals, modal => modal.id === id);
|
||||||
|
if (modalSchema) {
|
||||||
|
this.openSubEditor({
|
||||||
|
value: modalSchema,
|
||||||
|
title: '弹窗预览',
|
||||||
|
onChange: (value: any) => {}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const subEditorRef = this.getSubEditorRef();
|
||||||
|
if (subEditorRef) {
|
||||||
|
subEditorRef.store.setActiveIdByComponentId(id);
|
||||||
|
const $$id = subEditorRef.props.value.$$id;
|
||||||
|
const modalSchema = find(modals, modal => modal.$$id === $$id);
|
||||||
|
this.openSubEditor({
|
||||||
|
value: modalSchema,
|
||||||
|
title: '弹窗预览',
|
||||||
|
onChange: (value: any) => {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setSelections(ids: Array<string>) {
|
setSelections(ids: Array<string>) {
|
||||||
|
@ -104,6 +104,28 @@ export const EditorNode = types
|
|||||||
return resolved;
|
return resolved;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getNodeByComponentId(id: string) {
|
||||||
|
let pool = self.children.concat();
|
||||||
|
let resolved: any = undefined;
|
||||||
|
|
||||||
|
while (pool.length) {
|
||||||
|
const item = pool.shift();
|
||||||
|
const schema = item.schema;
|
||||||
|
|
||||||
|
if (schema && schema.id === id) {
|
||||||
|
resolved = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将当前节点的子节点全部放置到 pool中
|
||||||
|
if (item.children.length) {
|
||||||
|
pool.push.apply(pool, item.uniqueChildren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolved;
|
||||||
|
},
|
||||||
|
|
||||||
setInfo(value: RendererInfo) {
|
setInfo(value: RendererInfo) {
|
||||||
info = value;
|
info = value;
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,8 @@ import merge from 'lodash/merge';
|
|||||||
import {EditorModalBody} from './store/editor';
|
import {EditorModalBody} from './store/editor';
|
||||||
import {filter} from 'lodash';
|
import {filter} from 'lodash';
|
||||||
import type {SchemaType} from 'amis/lib/Schema';
|
import type {SchemaType} from 'amis/lib/Schema';
|
||||||
|
import type {DialogSchema} from '../../amis/src/renderers/Dialog';
|
||||||
|
import type {DrawerSchema} from '../../amis/src/renderers/Drawer';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
guid,
|
guid,
|
||||||
@ -1852,6 +1854,62 @@ export function setDefaultColSize(
|
|||||||
return tempList;
|
return tempList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getModals(schema: any) {
|
||||||
|
const modals: Array<DialogSchema | DrawerSchema> = [];
|
||||||
|
JSONTraverse(schema, (value: any, key: string, host: any) => {
|
||||||
|
if (
|
||||||
|
key === 'actionType' &&
|
||||||
|
['dialog', 'drawer', 'confirmDialog'].includes(value)
|
||||||
|
) {
|
||||||
|
const key = value === 'drawer' ? 'drawer' : 'dialog';
|
||||||
|
const body = host[key] || host['args'];
|
||||||
|
if (body && !body.$ref && !modals.find(item => item.$$id === body.$$id)) {
|
||||||
|
modals.push({
|
||||||
|
...body,
|
||||||
|
type: key,
|
||||||
|
actionType: value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 公共组件排在前面
|
||||||
|
Object.keys(schema.definitions || {})
|
||||||
|
.reverse()
|
||||||
|
.forEach(key => {
|
||||||
|
const definition = schema.definitions[key];
|
||||||
|
if (['dialog', 'drawer'].includes(definition.type)) {
|
||||||
|
// 不要把已经内嵌弹窗中的弹窗再放到外面
|
||||||
|
if (
|
||||||
|
definition.$$originId &&
|
||||||
|
modals.find(item => item.$$id === definition.$$originId)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
modals.unshift({
|
||||||
|
...definition,
|
||||||
|
$$ref: key
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 子弹窗时,自己就是个弹窗
|
||||||
|
if (['dialog', 'drawer', 'confirmDialog'].includes(schema.type)) {
|
||||||
|
const idx = modals.findIndex(item => item.$$id === schema.$$id);
|
||||||
|
if (~idx) {
|
||||||
|
modals.splice(idx, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
modals.unshift({
|
||||||
|
...schema,
|
||||||
|
// 如果还包含这个,子弹窗里面收集弹窗的时候会出现多份内嵌弹窗
|
||||||
|
definitions: undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return modals;
|
||||||
|
}
|
||||||
export const RAW_TYPE_MAP: {
|
export const RAW_TYPE_MAP: {
|
||||||
[k in SchemaType | 'user-select' | 'department-select']?:
|
[k in SchemaType | 'user-select' | 'department-select']?:
|
||||||
| 'string'
|
| 'string'
|
||||||
|
Loading…
Reference in New Issue
Block a user