diff --git a/packages/demo/package.json b/packages/demo/package.json index ab4a4afd5..562476b97 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -33,11 +33,15 @@ "@ali/ve-trunk-pane": "^5.1.0-beta.14", "@ali/vs-variable-setter": "^3.1.0", "@ali/vu-legao-design-fetch-context": "^1.0.3", + "@ali/ve-page-history": "1.2.0", + "@ali/ve-history-pane": "4.0.0", + "@ali/ve-page-history-pane": "^5.0.0-beta.0", "@alifd/next": "^1.19.12", "@alife/theme-lowcode-dark": "^0.1.0", "@alife/theme-lowcode-light": "^0.1.0", "react": "^16.8.1", - "react-dom": "^16.8.1" + "react-dom": "^16.8.1", + "@ali/vu-function-parser": "^2.5.0-beta.0" }, "devDependencies": { "@ali/iceluna-cli": "^0.0.16", diff --git a/packages/demo/public/schema.json b/packages/demo/public/schema.json index 1c7d2a300..591992766 100644 --- a/packages/demo/public/schema.json +++ b/packages/demo/public/schema.json @@ -2,7 +2,8 @@ "componentName": "Page", "fileName": "test", "dataSource": { - "list": [] + "list": [], + "online": [] }, "state": { "text": "outter" diff --git a/packages/demo/src/vision/index.ts b/packages/demo/src/vision/index.ts index 2427d10e6..157b496a3 100644 --- a/packages/demo/src/vision/index.ts +++ b/packages/demo/src/vision/index.ts @@ -1,10 +1,13 @@ /* eslint-disable */ import { createElement } from 'react'; import { Button } from '@alifd/next'; -import Engine, { Panes } from '@ali/visualengine'; +import Engine, { Panes, Prototype } from '@ali/visualengine'; import { ActionUtil as actionUtil } from '@ali/visualengine-utils'; import getTrunkPane from '@ali/ve-trunk-pane'; import DatapoolPane from '@ali/ve-datapool-pane'; +import PageHistoryManager from '@ali/ve-page-history'; +import HistoryPane from '@ali/ve-history-pane'; +import PageHistoryPane from '@ali/ve-page-history-pane'; // import I18nPane from '@ali/ve-i18n-pane'; import I18nManagePane from '@ali/ve-i18n-manage-pane'; import ActionPane from '@ali/ve-action-pane'; @@ -15,6 +18,9 @@ import { upgradeAssetsBundle } from './upgrade-assets'; import { isCSSUrl } from '@ali/lowcode-utils'; import { I18nSetter } from '@ali/visualengine-utils'; import VariableSetter from '@ali/vs-variable-setter'; +import { isObject, isArray } from 'lodash'; +import funcParser from '@ali/vu-function-parser'; + const { editor, skeleton, context, HOOKS, Trunk } = Engine; @@ -137,20 +143,20 @@ function initDemoPanes() { children: '保存', }), }); - skeleton.add({ - area: 'topArea', - type: 'Dock', - name: 'preview4', - props: { - align: 'center', - }, - content: createElement('img', { - src: 'https://img.alicdn.com/tfs/TB1WW.VC.z1gK0jSZLeXXb9kVXa-486-64.png', - style: { - height: 32, - }, - }), - }); + // skeleton.add({ + // area: 'topArea', + // type: 'Dock', + // name: 'preview4', + // props: { + // align: 'center', + // }, + // content: createElement('img', { + // src: 'https://img.alicdn.com/tfs/TB1WW.VC.z1gK0jSZLeXXb9kVXa-486-64.png', + // style: { + // height: 32, + // }, + // }), + // }); skeleton.add({ area: 'topArea', type: 'Dock', @@ -321,6 +327,87 @@ function initActionPane() { props, }); } +function replaceFuncProp(props?: any){ + const replaceProps = {}; + for (const name in props) { + const prop = props[name]; + if (!prop) { + continue; + } + if ((prop.compiled && prop.source) || prop.type === 'actionRef' || prop.type === 'js') { + replaceProps[name] = funcParser(prop); + } else if (isObject(prop)) { + replaceFuncProp(prop); + } else if (isArray(prop)) { + prop.map((propItem) => { + replaceFuncProp(propItem); + }); + } + } + + for (const name in replaceProps) { + props[name] = replaceProps[name]; + } + + return props; +}; + +// 操作历史与页面历史面板 +function initHistoryPane() { + // let historyConfigs = {getDesignerModuleConfigs( + // this.designerConfigs, + // 'history', + // )}; + let historyConfigs = { + enableRedoAndUndo: true, + enablePageHistory: true, + };; + + const isDemoMode = false; + const isEnvSupportsHistoryPane = true; + const historyManager = PageHistoryManager.getManager(); + + console.log('PageHistoryManager', historyManager); + console.log('PageHistoryManager.onOpenPane', historyManager.onOpenPane); + // 历史撤销、重做以及唤起页面历史按钮 + if (typeof HistoryPane === 'function') { + Panes.add(HistoryPane, { + props : { + showPageHistory: + isEnvSupportsHistoryPane + // && this.app.isForm() + && !isDemoMode, + historyManager, + historyConfigs, + index: -940, + } + }); + } else { + Panes.add(HistoryPane, { + index: -940, + }); + } + + // 页面历史 UI 面板 + if ( + PageHistoryPane + && !isDemoMode + && isEnvSupportsHistoryPane + ) { + Panes.add(PageHistoryPane, { + props : { + historyManager: { + historyManager, + app: { + + } + }, + index: -940, + }, + }); + } +} + async function init() { Engine.Env.setEnv('RE_VERSION', '7.2.0'); @@ -328,6 +415,7 @@ async function init() { subview: true, i18nPane: true, }); + Prototype.addGlobalPropsReducer(replaceFuncProp); await loadAssets(); await loadSchema(); await initTrunkPane(); @@ -335,7 +423,7 @@ async function init() { initI18nPane(); initActionPane(); initDemoPanes(); - + initHistoryPane(); Engine.init(); } init(); diff --git a/packages/demo/src/vision/module.d.ts b/packages/demo/src/vision/module.d.ts index 2217b3e06..ba843aea9 100644 --- a/packages/demo/src/vision/module.d.ts +++ b/packages/demo/src/vision/module.d.ts @@ -1,8 +1,12 @@ -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"; +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-history-pane'; +declare module '@ali/ve-page-history-pane'; +declare module '@ali/ve-page-history'; +declare module '@ali/ve-i18n-manage-pane'; +declare module '@ali/ve-action-pane'; +declare module '@ali/vu-legao-design-fetch-context'; +declare module "@ali/vu-function-parser"; diff --git a/packages/designer/src/designer/setting/utils.js b/packages/designer/src/designer/setting/utils.js index b8f5bbdcc..d9e7e389c 100644 --- a/packages/designer/src/designer/setting/utils.js +++ b/packages/designer/src/designer/setting/utils.js @@ -1,12 +1,16 @@ +// all this file for polyfill vision logic + +import { isValidElement } from 'react'; + function getHotterFromSetter(setter) { return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line } function getTransducerFromSetter(setter) { return setter && ( - setter.transducer || setter.Transducer - || (setter.type && (setter.type.transducer || setter.type.Transducer)) - ) || null; // eslint-disable-line + setter.transducer || setter.Transducer + || (setter.type && (setter.type.transducer || setter.type.Transducer)) + ) || null; // eslint-disable-line } function combineTransducer(transducer, arr, context) { @@ -23,9 +27,22 @@ function combineTransducer(transducer, arr, context) { export class Transducer { constructor(context, config) { + let { setter } = config; + + // 1. validElement + // 2. SetterConfig + // 3. SetterConfig[] + if (Array.isArray(setter)) { + setter = setter[0]; + } else if (isValidElement(setter) && setter.type.displayName === 'MixedSetter') { + setter = setter.props.setters[0]; + } else if (typeof setter === 'object' && setter.componentName === 'MixedSetter') { + setter = setter.props.setters[0]; + } + this.setterTransducer = combineTransducer( - getTransducerFromSetter(config.setter), - getHotterFromSetter(config.setter), + getTransducerFromSetter(setter), + getHotterFromSetter(setter), context, ); this.context = context; diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index eb92fb1c7..ac739d625 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -12,8 +12,8 @@ import { uniqueId } from '@ali/lowcode-utils'; export type GetDataType = T extends undefined ? NodeType extends { - schema: infer R; - } + schema: infer R; + } ? R : any : T; @@ -465,6 +465,14 @@ export class DocumentModel { getRoot() { return this.rootNode; } + + /** + * 兼容vision + */ + getHistory(): History { + return this.history; + } + get root() { return this.rootNode; } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 9f19ce0eb..4cc95b4e1 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -155,6 +155,7 @@ export class Node { private transformProps(props: any): any { // FIXME! support PropsList return this.document.designer.transformProps(props, this, TransformStage.Init); + // TODO: run transducers in metadata.experimental } diff --git a/packages/editor-skeleton/src/components/mixed-setter/index.tsx b/packages/editor-skeleton/src/components/mixed-setter/index.tsx index a0b7f9b9e..6f5ddeeeb 100644 --- a/packages/editor-skeleton/src/components/mixed-setter/index.tsx +++ b/packages/editor-skeleton/src/components/mixed-setter/index.tsx @@ -115,6 +115,8 @@ export default class MixedSetter extends Component<{ className?: string; }> { private setters = nomalizeSetters(this.props.setters); + // set name ,used in setting Transducer + static displayName = 'MixedSetter'; @obx.ref private used?: string; @computed private getCurrentSetter() { const { field } = this.props; diff --git a/packages/editor-skeleton/src/components/mixed-setter/style.less b/packages/editor-skeleton/src/components/mixed-setter/style.less index d277ae322..5d6f31674 100644 --- a/packages/editor-skeleton/src/components/mixed-setter/style.less +++ b/packages/editor-skeleton/src/components/mixed-setter/style.less @@ -25,7 +25,7 @@ border-radius: 3px; } } - .next-input,.next-date-picker { + .next-input,.next-date-picker,.next-month-picker { width: 100%; } &.lc-block-setter { diff --git a/packages/editor-skeleton/src/components/widget-views.tsx b/packages/editor-skeleton/src/components/widget-views.tsx index cdd646be7..13dad59f8 100644 --- a/packages/editor-skeleton/src/components/widget-views.tsx +++ b/packages/editor-skeleton/src/components/widget-views.tsx @@ -1,6 +1,7 @@ import { Component, ReactElement } from 'react'; +import { Icon } from '@alifd/next'; import classNames from 'classnames'; -import { Title, observer } from '@ali/lowcode-editor-core'; +import { Title, observer, Tip } from '@ali/lowcode-editor-core'; import { DockProps } from '../types'; import PanelDock from '../widget/panel-dock'; import { composeTitle } from '../widget/utils'; @@ -21,6 +22,25 @@ export function DockView({ title, icon, description, size, className, onClick }: ); } +function HelpTip({ tip }: any) { + if (tip && tip.url) { + return ( +
+ + + + {tip.content} +
+ ); + } + return ( +
+ + {tip.content} +
+ ) +} + @observer export class PanelDockView extends Component { componentDidMount() { @@ -196,7 +216,7 @@ class PanelTitle extends Component<{ panel: Panel; className?: string }> { data-name={panel.name} > - {/*pane.help ? <HelpTip tip={panel.help} /> : null*/} + {panel.help ? <HelpTip tip={panel.help} /> : null} </div> ); } diff --git a/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx b/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx index c5ea01b53..527b48b98 100644 --- a/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx @@ -13,21 +13,26 @@ export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, P } render() { const { area } = this.props; + const hideTitleBar = area.current?.config.props?.hideTitleBar; return ( <div className={classNames('lc-left-fixed-pane', { 'lc-area-visible': area.visible, })} > - <Button - text - className="lc-pane-close" - onClick={() => { - area.setVisible(false); - }} - > - <Icon type="close" /> - </Button> + { + !hideTitleBar && ( + <Button + text + className="lc-pane-close" + onClick={() => { + area.setVisible(false); + }} + > + <Icon type="close" /> + </Button> + ) + } <Contents area={area} /> </div> ); diff --git a/packages/editor-skeleton/src/layouts/left-float-pane.tsx b/packages/editor-skeleton/src/layouts/left-float-pane.tsx index 84feacd6f..d9b32b22a 100644 --- a/packages/editor-skeleton/src/layouts/left-float-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-float-pane.tsx @@ -32,6 +32,7 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> // focusout remove focus // onEsc const width = area.current?.config.props?.width; + const hideTitleBar = area.current?.config.props?.hideTitleBar; const style = width ? { width } : undefined; @@ -42,15 +43,19 @@ export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> })} style={style} > - <Button - text - className="lc-pane-close" - onClick={() => { - area.setVisible(false); - }} - > - <Icon type="close" /> - </Button> + { + !hideTitleBar && ( + <Button + text + className="lc-pane-close" + onClick={() => { + area.setVisible(false); + }} + > + <Icon type="close" /> + </Button> + ) + } <Contents area={area} /> </div> ); diff --git a/packages/editor-skeleton/src/layouts/theme.less b/packages/editor-skeleton/src/layouts/theme.less index 5171884c0..0d4651b17 100644 --- a/packages/editor-skeleton/src/layouts/theme.less +++ b/packages/editor-skeleton/src/layouts/theme.less @@ -57,4 +57,6 @@ --color-block-background-deep-dark: @normal-5; --color-layer-mask-background: @dark-alpha-7; --color-layer-tooltip-background: rgba(44,47,51,0.8); + + --pane-title-bg-color: rgba(31,56,88,.04); } diff --git a/packages/editor-skeleton/src/layouts/top-area.tsx b/packages/editor-skeleton/src/layouts/top-area.tsx index 532fc1fef..2b8535117 100644 --- a/packages/editor-skeleton/src/layouts/top-area.tsx +++ b/packages/editor-skeleton/src/layouts/top-area.tsx @@ -24,7 +24,11 @@ class Contents extends Component<{ area: Area }> { const left: any[] = []; const center: any[] = []; const right: any[] = []; - area.container.items.forEach(item => { + area.container.items.sort((a,b) => { + const index1 = a.config?.index || 0; + const index2 = b.config?.index || 0; + return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1); + }).forEach(item => { if (item.align === 'center') { center.push(item.content); } else if (item.align === 'left') { diff --git a/packages/editor-skeleton/src/layouts/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less index 94d335a90..4efca072d 100644 --- a/packages/editor-skeleton/src/layouts/workbench.less +++ b/packages/editor-skeleton/src/layouts/workbench.less @@ -54,19 +54,25 @@ body { display: none; } .lc-panel-title { - height: 32px; - background-color: var(--pane-title-bg-color); + height: 38px; + font-size: 14px; + background-color: var(--pane-title-bg-color,rgba(31,56,88,.04)); display: flex; align-items: center; + justify-content: center; padding: 0 15px; + border-bottom: 1px solid var(--color-line-normal,rgba(31,56,88,.1)); + .lc-help-tip { margin-left: 4px; + color: rgba(0,0,0,0.4); + cursor: pointer; } } .lc-panel-body { position: absolute; - top: 32px; + top: 38px; bottom: 0; left: 0; right: 0; diff --git a/packages/editor-skeleton/src/widget/panel-dock.ts b/packages/editor-skeleton/src/widget/panel-dock.ts index 105da7be4..e83bbddde 100644 --- a/packages/editor-skeleton/src/widget/panel-dock.ts +++ b/packages/editor-skeleton/src/widget/panel-dock.ts @@ -64,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, diff --git a/packages/editor-skeleton/src/widget/panel.ts b/packages/editor-skeleton/src/widget/panel.ts index d0336fe6c..f03e6a130 100644 --- a/packages/editor-skeleton/src/widget/panel.ts +++ b/packages/editor-skeleton/src/widget/panel.ts @@ -74,8 +74,6 @@ export default class Panel implements IWidget { ); content.forEach((item) => this.add(item)); } - // compatiable for vision, init at first - this.initBody(); // todo: process shortcut } diff --git a/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx b/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx index 5f3923042..70992e246 100644 --- a/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx +++ b/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx @@ -334,7 +334,7 @@ class Calendar extends Component { [CALENDAR_MODE_MONTH]: <MonthPanelHeader {...headerProps} />, [CALENDAR_MODE_YEAR]: <YearPanelHeader {...headerProps} />, }; - + return ( <div {...obj.pickOthers(Calendar.propTypes, others)} diff --git a/packages/vision-preset/src/bundle/prototype.ts b/packages/vision-preset/src/bundle/prototype.ts index 8fa44e3cd..f7b291873 100644 --- a/packages/vision-preset/src/bundle/prototype.ts +++ b/packages/vision-preset/src/bundle/prototype.ts @@ -5,6 +5,7 @@ import { addBuiltinComponentAction, isComponentMeta, registerMetadataTransducer, + TransformStage, } from '@ali/lowcode-designer'; import { OldPropConfig, @@ -112,9 +113,10 @@ function addGlobalExtraActions(action: () => ReactElement) { upgradeActions(action)?.forEach(addBuiltinComponentAction); } -const GlobalPropsReducers: any[] = []; +// const GlobalPropsReducers: any[] = []; function addGlobalPropsReducer(reducer: () => any) { - GlobalPropsReducers.push(reducer); + // GlobalPropsReducers.push(reducer); + designer.addPropsReducer(reducer, TransformStage.Render); } export interface OldGlobalPropConfig extends OldPropConfig { diff --git a/packages/vision-preset/src/panes.ts b/packages/vision-preset/src/panes.ts index 750307496..3604e6186 100644 --- a/packages/vision-preset/src/panes.ts +++ b/packages/vision-preset/src/panes.ts @@ -1,6 +1,6 @@ import { skeleton, editor } from './editor'; import { ReactElement } from 'react'; -import { IWidgetBaseConfig } from '@ali/lowcode-editor-skeleton'; +import { IWidgetBaseConfig, Skeleton } from '@ali/lowcode-editor-skeleton'; import { uniqueId } from '@ali/lowcode-utils'; export interface IContentItemConfig { @@ -63,7 +63,7 @@ function upgradeConfig(config: OldPaneConfig): IWidgetBaseConfig & { area: strin onDestroy: destroy, }, contentProps: props, - index, + index: index || props?.index, }; if (type === 'dock') { newConfig.type = 'PanelDock'; @@ -85,6 +85,7 @@ function upgradeConfig(config: OldPaneConfig): IWidgetBaseConfig & { area: strin } if (!isAction) { newConfig.panelProps = { + title, hideTitleBar, help: tip, width, @@ -156,6 +157,10 @@ const dockPane = Object.assign(skeleton.leftArea, { * compatible *VE.dockPane.activeDock* */ activeDock(item: any) { + if (!item) { + skeleton.leftFloatArea?.current?.hide(); + return; + } const name = item.name || item; skeleton.getPanel(name)?.active(); }, diff --git a/packages/vision-preset/src/vision.less b/packages/vision-preset/src/vision.less index 131227b3d..d0c17fcc0 100644 --- a/packages/vision-preset/src/vision.less +++ b/packages/vision-preset/src/vision.less @@ -96,3 +96,7 @@ html.engine-blur #engine { pointer-events: auto !important; } } + +.lc-left-float-pane { + font-size: 14px; +}