UNPKG

@riil-frontend/component-page-creater

Version:

page creater components,include components list,component attribute panel and page canvas

840 lines (739 loc) 28.1 kB
import _Box from "@alifd/next/es/box"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _Dialog from "@alifd/next/es/dialog"; import _extends from "@babel/runtime/helpers/extends"; import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import React, { Component } from 'react'; import _ from 'lodash'; import PropTypes from 'prop-types'; import { getUUID } from '@riil-frontend/utils'; import './index.scss'; import { COMLIST_TEMPLATE_TYPE, CONTAINER_COM_TYPE, LAYOUT_TYPE } from '../constant'; import DragLayoutCanvas from '../drag-panel'; import HorizontalEditor from '../edit-layout/HorizontalEditor'; import SingleEditor from '../edit-layout/SingleEditor'; import VerticalEditor from '../edit-layout/VerticalEditor'; import ComList from '../com-list/index'; import AttributesPanel from '../attr-panel/AttributesPanel'; import { dispatchResizeEvent, getComRequire, validateToPromis } from '../util'; import HideArrowBtn from './compontent/HideArrowBtn'; /** * 页面组装器 */ var Editor = /*#__PURE__*/function (_Component) { _inheritsLoose(Editor, _Component); function Editor(props) { var _this; _this = _Component.call(this, props) || this; _this.onChange = function (pageConfig) { //修改页面配置列表 var configs = _this.state.appPageConfig.configs.map(function (item) { if (item.pageId === pageConfig.pageId) { return pageConfig; } else { return item; } }); var hasSelected = false; pageConfig.widgets.forEach(function (ele) { if (ele.id === _this.state.selected) { hasSelected = true; } if (ele.type === CONTAINER_COM_TYPE) { ele.attributes.cols.forEach(function (colItem) { colItem.widgets.forEach(function (colWidItem) { if (colWidItem.id === _this.state.selected) { hasSelected = true; } }); }); } }); if (!hasSelected) { _this.setState({ selected: undefined }); } //修改页面页面配置 var _appPageConfig = _extends({}, _this.state.appPageConfig, { configs: configs }); _this.onAppChange(_appPageConfig); }; _this.onAppChange = function (appPageConfig) { if (_this.props.onChange) { _this.props.onChange(appPageConfig); } if (!('appPageConfig' in _this.props)) { _this.setState({ appPageConfig: appPageConfig }); } }; _this.onItemDragStart = function (config, e) { var isDroppable = true; if (config.isOnlyOne && _this.state.currentPageConfig.widgets.find(function (item) { return item.type === config.type; })) { isDroppable = false; } var hasTemplate = _this.state.currentPageConfig.widgets.find(function (item) { return item.type === CONTAINER_COM_TYPE; }); //如果有模板,则禁止放入业务组件,如果有业务组件,则禁止放入模板,如果是空模板,则都可放入 if (hasTemplate) { if (config.type === CONTAINER_COM_TYPE) { isDroppable = true; } else { isDroppable = false; } } else if (_this.state.currentPageConfig.widgets.length > 0) { if (config.type === CONTAINER_COM_TYPE) { isDroppable = false; } else { isDroppable = true; } } //从组件列表中,拖拽布局时,启用此方法 if (!config.importFrom || config.type === COMLIST_TEMPLATE_TYPE) { _this.setState({ droppingItem: { i: '', w: 0, h: 0 }, isDroppable: true }); return true; } _this.setState({ droppingItem: { i: config.layouts.i, w: config.layouts.w, h: config.layouts.h }, isDroppable: isDroppable }); return isDroppable; }; _this.onItemDragEnd = function () { _this.setState({ droppingItem: null, isDroppable: false }); }; _this.onClose = function (key) { _Dialog.confirm({ title: '删除页签', content: '当前操作会删除当前页签以及页签内所有组件,请确认是否删除当前页签?', onOk: function onOk() { var appPageConfig = _this.state.appPageConfig; var configs = appPageConfig.configs.filter(function (item, index) { if (index != key) { return true; } }); if (configs.length === 0) { _Dialog.show({ type: 'alert', content: '至少保留一个页签' }); return; } _this.setState({ tabSelectedIndex: '0' }); _this.onAppChange(_extends({}, appPageConfig, { configs: configs })); } }); }; _this.addNewTab = function (type) { var appPageConfig = _this.state.appPageConfig; var layoutConfig = _extends({}, DragLayoutCanvas.defaultProps.pageConfig.layoutConfig, { cols: 24 }); var item = _extends({}, DragLayoutCanvas.defaultProps.pageConfig, { pageName: '未命名', id: getUUID(), pageId: getUUID(), layoutConfig: layoutConfig }); if (type === LAYOUT_TYPE.horizontal) { item.icon = 'form'; } var _config = _extends({}, appPageConfig, { configs: [].concat(appPageConfig.configs, [item]) }); _this.onAppChange(_config); }; _this.convertTabsData = function (appPageConfig) { var cf = appPageConfig.configs.map(function (item) { var newObj = {}; newObj.id = item.id; newObj.pageName = item.pageName; newObj.pageId = item.pageId; return newObj; }); return _extends({}, appPageConfig, { configs: cf }); }; _this.clearPanel = function () { _this.onChange(_extends({}, _this.state.currentPageConfig, { widgets: [] })); }; _this.checkForms = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { var _this$attrRef, _this$attrRef$templat, _this$attrRef$templat2, _this$attrRef$templat3, _this$attrRef2, _this$attrRef2$pageRe, _this$attrRef2$pageRe2, _this$attrRef2$pageRe3, _this$attrRef3, _this$attrRef3$compon, _this$attrRef3$compon2, _this$attrRef3$compon3, _this$attrRef3$compon4, _this$attrRef3$compon5, _this$attrRef4, _this$attrRef4$compon, _this$attrRef4$compon2, _this$attrRef4$compon3; var templateValidator, pageValidator, componentValidator, componentActionValidator, templateResult, pageResult, componentResult, validateAction, componentActionResult; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: templateValidator = (_this$attrRef = _this.attrRef) === null || _this$attrRef === void 0 ? void 0 : (_this$attrRef$templat = _this$attrRef.templateRef) === null || _this$attrRef$templat === void 0 ? void 0 : (_this$attrRef$templat2 = _this$attrRef$templat.current) === null || _this$attrRef$templat2 === void 0 ? void 0 : (_this$attrRef$templat3 = _this$attrRef$templat2.field) === null || _this$attrRef$templat3 === void 0 ? void 0 : _this$attrRef$templat3.validate; pageValidator = (_this$attrRef2 = _this.attrRef) === null || _this$attrRef2 === void 0 ? void 0 : (_this$attrRef2$pageRe = _this$attrRef2.pageRef) === null || _this$attrRef2$pageRe === void 0 ? void 0 : (_this$attrRef2$pageRe2 = _this$attrRef2$pageRe.current) === null || _this$attrRef2$pageRe2 === void 0 ? void 0 : (_this$attrRef2$pageRe3 = _this$attrRef2$pageRe2.field) === null || _this$attrRef2$pageRe3 === void 0 ? void 0 : _this$attrRef2$pageRe3.validate; componentValidator = (_this$attrRef3 = _this.attrRef) === null || _this$attrRef3 === void 0 ? void 0 : (_this$attrRef3$compon = _this$attrRef3.componentRef) === null || _this$attrRef3$compon === void 0 ? void 0 : (_this$attrRef3$compon2 = _this$attrRef3$compon.current) === null || _this$attrRef3$compon2 === void 0 ? void 0 : (_this$attrRef3$compon3 = _this$attrRef3$compon2.comAttrPanelRef) === null || _this$attrRef3$compon3 === void 0 ? void 0 : (_this$attrRef3$compon4 = _this$attrRef3$compon3.current) === null || _this$attrRef3$compon4 === void 0 ? void 0 : (_this$attrRef3$compon5 = _this$attrRef3$compon4.field) === null || _this$attrRef3$compon5 === void 0 ? void 0 : _this$attrRef3$compon5.validate; componentActionValidator = (_this$attrRef4 = _this.attrRef) === null || _this$attrRef4 === void 0 ? void 0 : (_this$attrRef4$compon = _this$attrRef4.componentRef) === null || _this$attrRef4$compon === void 0 ? void 0 : (_this$attrRef4$compon2 = _this$attrRef4$compon.current) === null || _this$attrRef4$compon2 === void 0 ? void 0 : (_this$attrRef4$compon3 = _this$attrRef4$compon2.actions) === null || _this$attrRef4$compon3 === void 0 ? void 0 : _this$attrRef4$compon3.validate; _context2.next = 6; return validateToPromis(templateValidator); case 6: templateResult = _context2.sent; _context2.next = 9; return validateToPromis(pageValidator); case 9: pageResult = _context2.sent; _context2.next = 12; return validateToPromis(componentValidator); case 12: componentResult = _context2.sent; validateAction = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(valid) { var promise, result; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!valid) { _context.next = 8; break; } promise = function promise() { return new Promise(function (resolve, reject) { valid().then(function (value) { return resolve(null); })["catch"](function (error) { return resolve(error); }); }); }; _context.next = 4; return promise(); case 4: result = _context.sent; return _context.abrupt("return", result); case 8: return _context.abrupt("return", null); case 9: case "end": return _context.stop(); } } }, _callee); })); return function validateAction(_x) { return _ref2.apply(this, arguments); }; }(); if (!componentActionValidator) { _context2.next = 20; break; } _context2.next = 17; return validateAction(componentActionValidator); case 17: _context2.t0 = _context2.sent; _context2.next = 21; break; case 20: _context2.t0 = null; case 21: componentActionResult = _context2.t0; return _context2.abrupt("return", !templateResult && !pageResult && !componentResult && !componentActionResult); case 23: case "end": return _context2.stop(); } } }, _callee2); })); _this.checkWidgetsAttr = function () { var errorMsgs = []; var hasBusinessCom = false; _this.state.appPageConfig.configs.forEach(function (item) { item.widgets.forEach(function (ele) { var attr = ele.attributes; var Com = getComRequire(ele.type, ele.importFrom, _this.props.customGetComRequire); var validate = Com.validate; if (attr && validate) { var isValidate = validate(attr); if (!isValidate) { errorMsgs.push({ page: item, widget: ele }); } } if (ele.type === CONTAINER_COM_TYPE) { ele.attributes.cols.forEach(function (colItem) { if (colItem.widgets.length > 0) { hasBusinessCom = true; } colItem.widgets.forEach(function (colWidItem) { var colWidCOM = getComRequire(colWidItem.type, colWidItem.importFrom, _this.props.customGetComRequire); var colWidAttr = colWidItem.attributes; var colWidValidate = colWidCOM.validate; if (colWidAttr && colWidValidate) { var colWidIsValidate = colWidValidate(colWidAttr); if (!colWidIsValidate) { errorMsgs.push({ page: item, widget: colWidItem, containerWidget: ele }); } } }); }); } else { hasBusinessCom = true; } }); }); return { errorMsgs: errorMsgs, hasBusinessCom: hasBusinessCom }; }; _this.checkAll = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() { var formCheck, _this$checkWidgetsAtt, errorMsgs, hasBusinessCom; return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return _this.checkForms(); case 2: formCheck = _context3.sent; _this$checkWidgetsAtt = _this.checkWidgetsAttr(), errorMsgs = _this$checkWidgetsAtt.errorMsgs, hasBusinessCom = _this$checkWidgetsAtt.hasBusinessCom; return _context3.abrupt("return", { formCheck: formCheck, widgetsCheck: errorMsgs, hasBusinessCom: hasBusinessCom }); case 5: case "end": return _context3.stop(); } } }, _callee3); })); var _pageConfig = props.appPageConfig || Editor.defaultConfig.appPageConfig; _this.domHeight = []; _this.state = { appPageConfig: _pageConfig, tabSelectedIndex: '0', currentPageConfig: _pageConfig.configs[0], droppingItem: { i: 'drop', w: 6, h: 10 }, isEdit: true, selected: undefined, isDroppable: false, leftShow: true, rightShow: true }; return _this; } var _proto = Editor.prototype; _proto.componentDidMount = function componentDidMount() { var parentDom = document.getElementsByClassName('creater-canvas')[0]; var dis = parentDom.scrollHeight - parentDom.clientHeight; this.domHeight.push(dis); dispatchResizeEvent(0); } /** * 属性props变更时的声明周期函数 * 当配置appPageConfig属性发生变化时, * 会重新设置tabSelectedIndex,appPageConfig,currentPageConfig状态 * @param {object} nextProps * @param {object} nextState */ ; _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { if ('appPageConfig' in nextProps && nextProps.appPageConfig && !_.isEqual(nextProps.appPageConfig, this.props.appPageConfig)) { var index = nextProps.appPageConfig.configs.length > nextState.tabSelectedIndex ? nextState.tabSelectedIndex : '0'; var currentPageConfig = nextProps.appPageConfig.configs[index]; this.setState({ appPageConfig: nextProps.appPageConfig, currentPageConfig: currentPageConfig, tabSelectedIndex: index }); return false; } else if (nextState.appPageConfig && !_.isEqual(nextState.appPageConfig, this.state.appPageConfig)) { var _index = nextState.appPageConfig.configs.length > nextState.tabSelectedIndex ? nextState.tabSelectedIndex : '0'; var _currentPageConfig = nextState.appPageConfig.configs[_index]; this.setState({ currentPageConfig: _currentPageConfig, tabSelectedIndex: _index }); return false; } return true; }; _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) { var _this2 = this; setTimeout(function () { var parentDom = document.getElementsByClassName('creater-canvas')[0]; if (!parentDom) { return; } var dis = parentDom.scrollHeight - parentDom.clientHeight; _this2.domHeight.push(dis); if (_this2.domHeight.length > 2) { _this2.domHeight = [_this2.domHeight[1], _this2.domHeight[2]]; } if (_this2.domHeight.length === 2 && _this2.domHeight[0] !== _this2.domHeight[1]) { dispatchResizeEvent(0); } }, 100); } /** * 从列表添加组件、删除组件、修改属性面板、拖拽组件位置、修改组件大小 * 以上操作会进入此方法 * @param {object} pageConfig */ ; /** * 属性面板发生设置时,调用此方法,修改config * @param {object} config */ _proto.onAttrPanelChange = function onAttrPanelChange(pageConfig) { this.onChange(pageConfig); }; _proto.onTemplateChange = function onTemplateChange(appPageConfig) { this.onAppChange(appPageConfig); } /** * 页面关闭被点击后,回调,触发配置变更方法 * @param {string} key */ ; _proto.render = function render() { var _this3 = this; var _this$props = this.props, comList = _this$props.comList, pageProps = _this$props.pageProps, request = _this$props.request, jumpto = _this$props.jumpto, attributeProps = _this$props.attributeProps, comListProps = _this$props.comListProps, customGetComRequire = _this$props.customGetComRequire, layoutProps = _this$props.layoutProps; var _ref4 = comListProps || { collapseProps: null }, collapseProps = _ref4.collapseProps, comListOther = _objectWithoutPropertiesLoose(_ref4, ["collapseProps"]); var _this$state = this.state, appPageConfig = _this$state.appPageConfig, currentPageConfig = _this$state.currentPageConfig, tabSelectedIndex = _this$state.tabSelectedIndex, droppingItem = _this$state.droppingItem, isEdit = _this$state.isEdit, selected = _this$state.selected, isDroppable = _this$state.isDroppable; var layoutType = appPageConfig.layoutType || LAYOUT_TYPE.horizontal; var dragCanvas = null; if (layoutType === LAYOUT_TYPE.horizontal) { dragCanvas = /*#__PURE__*/React.createElement(HorizontalEditor, { addNewTab: this.addNewTab.bind(this, LAYOUT_TYPE.horizontal), request: request, onTabChange: function onTabChange(obj) { _this3.setState(obj); }, tabSelectedIndex: tabSelectedIndex, appPageConfig: appPageConfig, onClickBlank: function onClickBlank() { _this3.setState({ selected: undefined }); }, selected: selected, droppingItem: droppingItem, isDroppable: isDroppable, isEdit: isEdit, onChange: function onChange(item) { _this3.onChange(item); }, onWidgetSelect: function onWidgetSelect(id) { _this3.setState({ selected: id }); }, pageProps: pageProps, jumpto: jumpto, onClose: function onClose(key) { _this3.onClose(key); }, onAppChange: function onAppChange(obj) { _this3.onAppChange(obj); }, layoutProps: layoutProps, customGetComRequire: customGetComRequire }); } else if (layoutType === LAYOUT_TYPE.single) { dragCanvas = /*#__PURE__*/React.createElement(SingleEditor, { request: request, onTabChange: function onTabChange(obj) { _this3.setState(obj); }, tabSelectedIndex: tabSelectedIndex, appPageConfig: appPageConfig, onClickBlank: function onClickBlank() { _this3.setState({ selected: undefined }); }, selected: selected, droppingItem: droppingItem, isDroppable: isDroppable, isEdit: isEdit, onChange: function onChange(item) { _this3.onChange(item); }, onWidgetSelect: function onWidgetSelect(id) { _this3.setState({ selected: id }); }, pageProps: pageProps, jumpto: jumpto, onClose: function onClose(key) { _this3.onClose(key); }, onAppChange: function onAppChange(obj) { _this3.onAppChange(obj); }, layoutProps: layoutProps, customGetComRequire: customGetComRequire }); } else if (layoutType === LAYOUT_TYPE.vertical) { dragCanvas = /*#__PURE__*/React.createElement(VerticalEditor, { addNewTab: this.addNewTab, request: request, onTabChange: function onTabChange(obj) { _this3.setState(obj); }, tabSelectedIndex: tabSelectedIndex, appPageConfig: appPageConfig, onClickBlank: function onClickBlank() { _this3.setState({ selected: undefined }); }, selected: selected, droppingItem: droppingItem, isDroppable: false, isEdit: isEdit, onChange: function onChange(item) { _this3.onChange(item); }, onWidgetSelect: function onWidgetSelect(id) { _this3.setState({ selected: id }); }, pageProps: pageProps, jumpto: jumpto, onClose: function onClose(key) { _this3.onClose(key); }, onAppChange: function onAppChange(obj) { _this3.onAppChange(obj); }, layoutProps: layoutProps, customGetComRequire: customGetComRequire }); } return /*#__PURE__*/React.createElement("div", { className: "uicbb-editor" }, /*#__PURE__*/React.createElement("div", { className: "com-list", style: { width: this.state.leftShow ? 294 : 0 } }, /*#__PURE__*/React.createElement("div", { className: "com-list-content", style: { width: '100%', height: '100%', display: this.state.leftShow ? 'block' : 'none' } }, /*#__PURE__*/React.createElement(ComList, _extends({ comList: comList, style: { height: '100%' }, onItemDragStart: this.onItemDragStart, onItemDragEnd: this.onItemDragEnd, collapseProps: collapseProps }, comListOther, { customGetComRequire: customGetComRequire }))), /*#__PURE__*/React.createElement(_Box, { direction: "row", align: "center", style: { position: 'absolute', top: 'calc(50% - 14px)', width: 10, right: this.state.leftShow ? 4 : 0 } }, /*#__PURE__*/React.createElement(HideArrowBtn, { onClick: function onClick() { _this3.setState({ leftShow: !_this3.state.leftShow }); dispatchResizeEvent(100); }, dir: this.state.leftShow ? 'left' : 'right' }))), /*#__PURE__*/React.createElement("div", { className: "drag-canvas" }, dragCanvas), /*#__PURE__*/React.createElement("div", { className: "attr-panel", style: { width: this.state.rightShow ? 284 : 0 } }, /*#__PURE__*/React.createElement("div", { className: "attr-panel-content", style: { width: '100%', height: '100%', display: this.state.rightShow ? 'block' : 'none' } }, /*#__PURE__*/React.createElement(AttributesPanel, _extends({ ref: function ref(node) { _this3.attrRef = node; }, templateData: appPageConfig, pageConfig: currentPageConfig, selectId: selected, onChange: this.onAttrPanelChange.bind(this), onTemplateChange: this.onTemplateChange.bind(this), pageProps: pageProps, request: request }, attributeProps, { customGetComRequire: customGetComRequire }))), /*#__PURE__*/React.createElement(_Box, { direction: "row", align: "center", style: { position: 'absolute', top: 'calc(50% - 14px)', width: 10, left: this.state.rightShow ? 4 : 0 } }, /*#__PURE__*/React.createElement(HideArrowBtn, { onClick: function onClick() { _this3.setState({ rightShow: !_this3.state.rightShow }); dispatchResizeEvent(100); }, dir: this.state.rightShow ? 'right' : 'left' })))); }; return Editor; }(Component); Editor.propTypes = { /** * 组件列表数据exp:[{key:'workbench',title:'工作台',children:[{type: 'component-exp-alarm-list', importFrom: 'npm',icon:'help'}] }],, * */ comList: PropTypes.array, /** * 透传给DragLayoutCanvas的公共属性 */ pageProps: PropTypes.any, /** *应用框架级数据请求方法,用来实现数据请求,参考 {request} from 'ice' */ request: PropTypes.any, /** * 页面配置数据 */ appPageConfig: PropTypes.object, /** * ResponsiveReactGridLayout组件属性 */ layoutProps: PropTypes.object, /** * (path)=>{}页面跳转操作 */ jumpto: PropTypes.func, /** * 从列表添加组件、删除组件、修改属性面板、拖拽组件位置、修改组件大小触发回调 * (pageConfig)=>{} */ onChange: PropTypes.func, /** * attrConfig:属性面板分页签数据,可自定义扩展,自定义扩展数据中的render为属性面板自定义实例 * @example [ { name: '模板设置', key: 'template' }, { name: '页面设置', key: 'page' }, { name: '组件设置', key: 'component' }, { name: '自定义', key: 'custom',render:(selectWidget,currentPage,template)=><Button>{selectWidget?.id}</Button> }, ] * layoutList 切换分页布局属性,目前支持一下三种分页布局方式 @example [ { key: LAYOUT_TYPE.horizontal, label: '左侧页签', img: 'hlayout.png', }, { key: LAYOUT_TYPE.vertical, label: '上页签', img: 'vlayout.png', }, { key: LAYOUT_TYPE.single, label: '无页签', img: 'slayout.png', }, ] * imgPath 布局属性组件图片路径 @example '/img/uicbb/layout/' * tabProps 透传tab页签属性 */ attributeProps: PropTypes.object, /** * 组件列表属性 * {collapseProps - 折叠面板组件属性透传} */ comListProps: PropTypes.object, customGetComRequire: PropTypes.func, editMode: PropTypes.string }; Editor.defaultConfig = { comList: [], layoutProps: {}, appPageConfig: { pageId: '', layoutType: LAYOUT_TYPE.single, configs: [DragLayoutCanvas.defaultProps.pageConfig] } }; Editor.defaultProps = {}; export default Editor;