mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 01:21:58 +00:00
fix variables
This commit is contained in:
parent
b18e3c14b3
commit
93a3c68f43
@ -25,9 +25,6 @@ Trunk.registerSetter('I18nSetter', {
|
||||
'zh-CN': '国际化输入',
|
||||
'en-US': 'International Input'
|
||||
},
|
||||
// TODO: below
|
||||
// condition?: (field: any) => boolean;
|
||||
// initialValue?: any | ((field: any) => any);
|
||||
recommend: true,
|
||||
});
|
||||
context.use(HOOKS.VE_SETTING_FIELD_VARIABLE_SETTER, VariableSetter);
|
||||
@ -112,7 +109,7 @@ function initDemoPanes() {
|
||||
description: '帮助',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
skeleton.add({
|
||||
area: 'topArea',
|
||||
type: 'Dock',
|
||||
@ -289,6 +286,10 @@ function initActionPane() {
|
||||
|
||||
async function init() {
|
||||
Engine.Env.setEnv('RE_VERSION', '7.2.0');
|
||||
Engine.Env.setSupportFeatures({
|
||||
subview: true,
|
||||
i18nPane: true,
|
||||
});
|
||||
await loadAssets();
|
||||
await loadSchema();
|
||||
await initTrunkPane();
|
||||
|
||||
4
packages/demo/src/vision/module.d.ts
vendored
4
packages/demo/src/vision/module.d.ts
vendored
@ -2,3 +2,7 @@ declare module "@ali/visualengine";
|
||||
declare module "@ali/visualengine-utils";
|
||||
declare module "@ali/ve-trunk-pane";
|
||||
declare module "@ali/vs-variable-setter";
|
||||
declare module "@ali/ve-datapool-pane";
|
||||
declare module "@ali/ve-i18n-manage-pane";
|
||||
declare module "@ali/ve-action-pane";
|
||||
declare module "@ali/vu-legao-design-fetch-context";
|
||||
|
||||
@ -71,9 +71,13 @@ export class Designer {
|
||||
this.hovering.enable = false;
|
||||
const { dragObject } = e;
|
||||
if (isDragNodeObject(dragObject)) {
|
||||
if (dragObject.nodes.length === 1 && dragObject.nodes[0].parent) {
|
||||
// ensure current selecting
|
||||
dragObject.nodes[0].select();
|
||||
if (dragObject.nodes.length === 1) {
|
||||
if (dragObject.nodes[0].parent) {
|
||||
// ensure current selecting
|
||||
dragObject.nodes[0].select();
|
||||
} else {
|
||||
this.currentSelection?.clear();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.currentSelection?.clear();
|
||||
|
||||
@ -2,9 +2,13 @@ import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { Node, ParentalNode } from './node';
|
||||
import { TransformStage } from './transform-stage';
|
||||
import { NodeData, isNodeSchema } from '@ali/lowcode-types';
|
||||
import { shallowEqual } from '@ali/lowcode-utils';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
export class NodeChildren {
|
||||
@obx.val private children: Node[];
|
||||
private emitter = new EventEmitter();
|
||||
|
||||
constructor(readonly owner: ParentalNode, data: NodeData | NodeData[]) {
|
||||
this.children = (Array.isArray(data) ? data : [data]).map(child => {
|
||||
return this.owner.document.createNode(child);
|
||||
@ -52,6 +56,9 @@ export class NodeChildren {
|
||||
|
||||
this.children = children;
|
||||
this.interalInitParent();
|
||||
if (!shallowEqual(children, originChildren)) {
|
||||
this.emitter.emit('change');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,6 +93,7 @@ export class NodeChildren {
|
||||
deleted.internalSetParent(null);
|
||||
deleted.purge();
|
||||
}
|
||||
this.emitter.emit('change');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -118,6 +126,8 @@ export class NodeChildren {
|
||||
children.splice(index, 0, node);
|
||||
}
|
||||
|
||||
this.emitter.emit('change');
|
||||
|
||||
// check condition group
|
||||
if (node.conditionGroup) {
|
||||
if (
|
||||
@ -208,14 +218,7 @@ export class NodeChildren {
|
||||
}
|
||||
|
||||
mergeChildren(remover: () => any, adder: (children: Node[]) => NodeData[] | null, sorter: () => any) {
|
||||
/*
|
||||
const children = this.children.slice();
|
||||
children.forEach(child => child.internalSetParent(null));
|
||||
|
||||
this.children = children;
|
||||
this.interalInitParent();
|
||||
*/
|
||||
|
||||
let changed = false;
|
||||
if (remover) {
|
||||
const willRemove = this.children.filter(remover);
|
||||
if (willRemove.length > 0) {
|
||||
@ -226,6 +229,7 @@ export class NodeChildren {
|
||||
node.remove();
|
||||
}
|
||||
});
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (adder) {
|
||||
@ -236,11 +240,23 @@ export class NodeChildren {
|
||||
this.children.push(node);
|
||||
node.internalSetParent(this.owner);
|
||||
});
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (sorter) {
|
||||
this.children = this.children.sort(sorter);
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
this.emitter.emit('change');
|
||||
}
|
||||
}
|
||||
|
||||
onChange(fn: () => void) {
|
||||
this.emitter.on('change', fn);
|
||||
return () => {
|
||||
this.emitter.removeListener('change', fn);
|
||||
};
|
||||
}
|
||||
|
||||
private purged = false;
|
||||
|
||||
@ -593,6 +593,10 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
return this.props;
|
||||
}
|
||||
|
||||
onChildrenChange(fn: () => void) {
|
||||
return this.children?.onChange(fn);
|
||||
}
|
||||
|
||||
mergeChildren(remover: () => any, adder: (children: Node[]) => NodeData[] | null, sorter: () => any) {
|
||||
this.children?.mergeChildren(remover, adder, sorter);
|
||||
}
|
||||
@ -654,6 +658,10 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
this._addons[key] = exportData;
|
||||
}
|
||||
|
||||
getRect(): DOMRect | null {
|
||||
return this.document.simulator?.computeRect(this) || null;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@ -39,9 +39,24 @@ export function registerSetter(
|
||||
title: (setter as any).displayName || (setter as any).name || 'CustomSetter',
|
||||
};
|
||||
}
|
||||
if (!setter.initialValue) {
|
||||
const initial = getInitialFromSetter(setter.component);
|
||||
if (initial) {
|
||||
setter.initialValue = (field: any) => {
|
||||
return initial.call(field, field.getValue());
|
||||
};
|
||||
}
|
||||
}
|
||||
settersMap.set(typeOrMaps, { type: typeOrMaps, ...setter });
|
||||
}
|
||||
|
||||
function getInitialFromSetter(setter: any) {
|
||||
return setter && (
|
||||
setter.initial || setter.Initial
|
||||
|| (setter.type && (setter.type.initial || setter.type.Initial))
|
||||
) || null; // eslint-disable-line
|
||||
}
|
||||
|
||||
export function getSetter(type: string): RegisteredSetter | null {
|
||||
return settersMap.get(type) || null;
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ import { intlNode } from '../../locale';
|
||||
|
||||
import './style.less';
|
||||
import { SettingField } from '@ali/lowcode-designer';
|
||||
import { IconVariable } from 'editor-skeleton/src/icons/variable';
|
||||
import { IconVariable } from '../../icons/variable';
|
||||
|
||||
export interface SetterItem {
|
||||
name: string;
|
||||
@ -120,14 +120,12 @@ export default class MixedSetter extends Component<{
|
||||
const { field } = this.props;
|
||||
let firstMatched: SetterItem | undefined;
|
||||
for (const setter of this.setters) {
|
||||
if (setter.name === this.used) {
|
||||
return setter;
|
||||
}
|
||||
const matched = !setter.condition || setter.condition(field);
|
||||
if (matched) {
|
||||
if (setter.name === this.used) {
|
||||
return setter;
|
||||
}
|
||||
if (!firstMatched) {
|
||||
firstMatched = setter;
|
||||
}
|
||||
if (matched && !firstMatched) {
|
||||
firstMatched = setter;
|
||||
}
|
||||
}
|
||||
return firstMatched;
|
||||
@ -234,6 +232,7 @@ export default class MixedSetter extends Component<{
|
||||
);
|
||||
} else {
|
||||
// =2: 另外一个 Setter 原地展示,icon 高亮,点击弹出调用 VariableSetter.show
|
||||
// FIXME! use variable placeholder setter
|
||||
const otherSetter = this.setters.find((item) => item.name !== 'VariableSetter')!;
|
||||
setterContent = this.renderCurrentSetter(otherSetter, {
|
||||
value: field.getMockOrValue(),
|
||||
@ -243,7 +242,7 @@ export default class MixedSetter extends Component<{
|
||||
<Title
|
||||
className={field.isUseVariable() ? 'variable-binded' : ''}
|
||||
title={{
|
||||
icon: IconVariable,
|
||||
icon: <IconVariable size={24} />,
|
||||
tip: tipContent,
|
||||
}}
|
||||
onClick={() => {
|
||||
@ -314,7 +313,7 @@ export default class MixedSetter extends Component<{
|
||||
actions: ReactNode,
|
||||
} | undefined;
|
||||
if (this.hasVariableSetter) {
|
||||
// FIXME: polyfill vision variable setter logic
|
||||
// polyfill vision variable setter logic
|
||||
const setterComponent = getSetter('VariableSetter')?.component as any;
|
||||
if (setterComponent && setterComponent.isPopup) {
|
||||
contents = this.contentsFromPolyfill(setterComponent);
|
||||
|
||||
@ -16,6 +16,14 @@
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.lc-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
.variable-binded {
|
||||
background: var(--color-brand, #006cff);
|
||||
color: #fff!important;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
.next-input,.next-date-picker {
|
||||
width: 100%;
|
||||
@ -39,4 +47,4 @@
|
||||
height: 32px;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ export class TitledPanelView extends Component<{ panel: Panel }> {
|
||||
hidden: !panel.visible,
|
||||
})}>
|
||||
<PanelTitle panel={panel} />
|
||||
<div className="lc-pane-body">{panel.body}</div>
|
||||
<div className="lc-panel-body">{panel.body}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -50,24 +50,28 @@ body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
.pane-title {
|
||||
// height: var(--pane-title-height);
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
.lc-panel-title {
|
||||
height: 32px;
|
||||
background-color: var(--pane-title-bg-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
.my-help-tip {
|
||||
.lc-help-tip {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.pane-body {
|
||||
.lc-panel-body {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: 32px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
/*
|
||||
.my-tabs {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -99,10 +103,7 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.titled > .pane-body {
|
||||
top: var(--pane-title-height);
|
||||
*/
|
||||
}
|
||||
}
|
||||
.lc-panel {
|
||||
@ -112,16 +113,7 @@ body {
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
.pane-title {
|
||||
height: var(--pane-title-height);
|
||||
background-color: var(--pane-title-bg-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
.my-help-tip {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
/*
|
||||
.my-tabs {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -154,6 +146,7 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
.my-dock {
|
||||
|
||||
@ -181,7 +181,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
|
||||
title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' },
|
||||
items: [
|
||||
{
|
||||
name: '__condition',
|
||||
name: '___condition',
|
||||
title: { type: 'i18n', 'zh-CN': '条件显示', 'en-US': 'Condition' },
|
||||
setter: 'ExpressionSetter',
|
||||
},
|
||||
@ -190,7 +190,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
|
||||
title: { type: 'i18n', 'zh-CN': '循环', 'en-US': 'Loop' },
|
||||
items: [
|
||||
{
|
||||
name: '__loop',
|
||||
name: '___loop',
|
||||
title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' },
|
||||
setter: {
|
||||
componentName: 'MixinSetter',
|
||||
@ -215,7 +215,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '__loopArgs.0',
|
||||
name: '___loopArgs.0',
|
||||
title: { type: 'i18n', 'zh-CN': '迭代变量名', 'en-US': 'Loop Item' },
|
||||
setter: {
|
||||
componentName: 'StringSetter',
|
||||
@ -225,7 +225,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
|
||||
},
|
||||
},
|
||||
{
|
||||
name: '__loopArgs.1',
|
||||
name: '___loopArgs.1',
|
||||
title: { type: 'i18n', 'zh-CN': '索引变量名', 'en-US': 'Loop Index' },
|
||||
setter: {
|
||||
componentName: 'StringSetter',
|
||||
|
||||
@ -6,6 +6,7 @@ import { PanelDockConfig } from '../types';
|
||||
import Panel from './panel';
|
||||
import { PanelDockView, WidgetView } from '../components/widget-views';
|
||||
import { IWidget } from './widget';
|
||||
import { composeTitle } from './utils';
|
||||
|
||||
export default class PanelDock implements IWidget {
|
||||
readonly isWidget = true;
|
||||
@ -63,7 +64,7 @@ export default class PanelDock implements IWidget {
|
||||
name: this.panelName,
|
||||
props: {
|
||||
// FIXME! give default title for panel
|
||||
// title: props ? composeTitle(props?.title, props?.icon, props?.description, true) : '',
|
||||
title: props ? composeTitle(props?.title, props?.icon, props?.description, true) : '',
|
||||
...panelProps,
|
||||
},
|
||||
contentProps,
|
||||
|
||||
@ -74,6 +74,8 @@ export default class Panel implements IWidget {
|
||||
);
|
||||
content.forEach((item) => this.add(item));
|
||||
}
|
||||
// compatiable for vision, init at first
|
||||
this.initBody();
|
||||
// todo: process shortcut
|
||||
}
|
||||
|
||||
@ -93,6 +95,7 @@ export default class Panel implements IWidget {
|
||||
editor: this.skeleton.editor,
|
||||
config: this.config,
|
||||
panel: this,
|
||||
pane: this,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -159,6 +162,18 @@ export default class Panel implements IWidget {
|
||||
show() {
|
||||
this.setActive(true);
|
||||
}
|
||||
|
||||
|
||||
getSupportedPositions() {
|
||||
return ['default'];
|
||||
}
|
||||
|
||||
getCurrentPosition() {
|
||||
return 'default';
|
||||
}
|
||||
|
||||
setPosition(position: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export function isPanel(obj: any): obj is Panel {
|
||||
|
||||
@ -5,6 +5,36 @@ import { SimulatorRenderer } from './renderer';
|
||||
import { host } from './host';
|
||||
import './renderer.less';
|
||||
|
||||
// patch cloneElement avoid lost keyProps
|
||||
const originCloneElement = window.React.cloneElement;
|
||||
(window as any).React.cloneElement = (child: any, { _leaf, ...props}: any = {}) => {
|
||||
if (child.ref && props.ref) {
|
||||
const dRef = props.ref;
|
||||
const cRef = child.ref;
|
||||
props.ref = (x: any) => {
|
||||
if (cRef) {
|
||||
if (typeof cRef === 'function') {
|
||||
cRef(x);
|
||||
} else {
|
||||
try {
|
||||
cRef.current = x;
|
||||
} catch (e) { }
|
||||
}
|
||||
}
|
||||
if (dRef) {
|
||||
if (typeof dRef === 'function') {
|
||||
dRef(x);
|
||||
} else {
|
||||
try {
|
||||
dRef.current = x;
|
||||
} catch (e) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return originCloneElement(child, props);
|
||||
}
|
||||
|
||||
export default class SimulatorRendererView extends Component<{ renderer: SimulatorRenderer }> {
|
||||
render() {
|
||||
const { renderer } = this.props;
|
||||
|
||||
@ -284,6 +284,17 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
|
||||
}
|
||||
|
||||
let initialFn = (slotName ? null : initial) || initialValue;
|
||||
if (slotName && initialValue === true) {
|
||||
initialFn = (field: any, value: any) => {
|
||||
if (isJSSlot(value)) {
|
||||
return value;
|
||||
}
|
||||
return {
|
||||
type: 'JSSlot',
|
||||
value: initialChildren,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
if (accessor && !slotName) {
|
||||
extraProps.getValue = (field: Field, fieldValue: any) => {
|
||||
@ -294,17 +305,25 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
|
||||
}
|
||||
}
|
||||
|
||||
const setterInitial = getInitialFromSetter(setter);
|
||||
|
||||
addInitial({
|
||||
name: slotName || name,
|
||||
initial: (field: Field, currentValue: any) => {
|
||||
// FIXME! read from prototype.defaultProps
|
||||
const defaults = extraProps.defaultValue;
|
||||
|
||||
if (typeof initialFn === 'function') {
|
||||
return initialFn.call(field, currentValue, defaults);
|
||||
if (typeof initialFn !== 'function') {
|
||||
initialFn = defaultInitial;
|
||||
}
|
||||
|
||||
return currentValue == null ? defaults : currentValue;
|
||||
const v = initialFn.call(field, currentValue, defaults);
|
||||
|
||||
if (setterInitial) {
|
||||
return setterInitial.call(field, v, defaults);
|
||||
}
|
||||
|
||||
return v;
|
||||
},
|
||||
});
|
||||
|
||||
@ -343,7 +362,6 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
|
||||
];
|
||||
if (allowTextInput !== false) {
|
||||
setters.unshift('I18nSetter');
|
||||
// FIXME: use I18nSetter
|
||||
}
|
||||
if (supportVariable) {
|
||||
setters.push('VariableSetter');
|
||||
@ -429,6 +447,18 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
|
||||
|
||||
type AddIntial = (initialItem: InitialItem) => void;
|
||||
|
||||
function getInitialFromSetter(setter: any) {
|
||||
return setter && (
|
||||
setter.initial || setter.Initial
|
||||
|| (setter.type && (setter.type.initial || setter.type.Initial))
|
||||
) || null; // eslint-disable-line
|
||||
}
|
||||
|
||||
function defaultInitial(value: any, defaultValue: any) {
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
|
||||
export function upgradeConfigure(items: OldPropConfig[], addInitial: AddIntial) {
|
||||
const configure: any[] = [];
|
||||
let ignoreSlotName: any = null;
|
||||
|
||||
@ -25,7 +25,6 @@ export class VisualEngineContext {
|
||||
component: plugin,
|
||||
title: { type: 'i18n', 'zh-CN': '变量绑定', 'en-US': 'Variable Binding' },
|
||||
// TODO: add logic below
|
||||
// condition?: (field: any) => boolean;
|
||||
// initialValue?: any | ((field: any) => any);
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user