vxe-pc-ui
Version:
A vue based PC component library
496 lines (495 loc) • 15.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _vue = require("vue");
var _ui = require("../../ui");
var _dom = require("../../ui/src/dom");
var _widgetInfo = require("./widget-info");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _button = _interopRequireDefault(require("../../button/src/button"));
var _layoutWidget = _interopRequireDefault(require("./layout-widget"));
var _layoutPreview = _interopRequireDefault(require("./layout-preview"));
var _layoutSetting = _interopRequireDefault(require("./layout-setting"));
var _layoutStyle = _interopRequireDefault(require("./layout-style"));
var _defaultSettingData = require("./default-setting-data");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _default = exports.default = (0, _vue.defineComponent)({
name: 'VxeFormDesign',
props: {
size: {
type: String,
default: () => (0, _ui.getConfig)().formDesign.size || (0, _ui.getConfig)().size
},
config: Object,
height: {
type: [String, Number],
default: () => (0, _ui.getConfig)().formDesign.height
},
widgets: {
type: Array,
default: () => _xeUtils.default.clone((0, _ui.getConfig)().formDesign.widgets) || []
},
showHeader: {
type: Boolean,
default: () => (0, _ui.getConfig)().formDesign.showHeader
},
showPc: {
type: Boolean,
default: () => (0, _ui.getConfig)().formDesign.showPc
},
showMobile: {
type: Boolean,
default: () => (0, _ui.getConfig)().formDesign.showMobile
},
formRender: Object
},
emits: ['click-widget', 'add-widget', 'copy-widget', 'remove-widget', 'drag-widget'],
setup(props, context) {
const {
emit,
slots
} = context;
const xID = _xeUtils.default.uniqueId();
const refElem = (0, _vue.ref)();
const refLayoutStyle = (0, _vue.ref)();
const {
computeSize
} = (0, _ui.useSize)(props);
const reactData = (0, _vue.reactive)({
formData: {},
widgetConfigs: [],
widgetObjList: [],
dragWidget: null,
sortWidget: null,
activeWidget: null
});
const internalData = (0, _vue.reactive)({});
const refMaps = {
refElem
};
const computeMaps = {
computeSize
};
const $xeFormDesign = {
xID,
props,
context,
reactData,
internalData,
getRefMaps: () => refMaps,
getComputeMaps: () => computeMaps
};
const createWidget = name => {
return new _widgetInfo.FormDesignWidgetInfo($xeFormDesign, name, reactData.widgetObjList);
};
const createEmptyWidget = () => {
return new _widgetInfo.FormDesignWidgetInfo($xeFormDesign, '', reactData.widgetObjList);
};
const loadConfig = config => {
if (config) {
const {
formConfig,
widgetData
} = config;
if (formConfig) {
loadFormConfig(formConfig);
}
if (widgetData) {
loadWidgetData(widgetData);
}
}
const {
activeWidget,
widgetObjList
} = reactData;
if (activeWidget) {
const rest = _xeUtils.default.findTree(widgetObjList, item => item.id === activeWidget.id, {
children: 'children'
});
if (rest) {
reactData.activeWidget = rest.item;
} else {
reactData.activeWidget = widgetObjList[0] || null;
}
} else {
reactData.activeWidget = widgetObjList[0] || null;
}
return (0, _vue.nextTick)();
};
const reloadConfig = config => {
clearConfig();
return loadConfig(config);
};
const getFormConfig = () => {
return _xeUtils.default.clone(reactData.formData, true);
};
const loadFormConfig = data => {
reactData.formData = Object.assign({}, createSettingForm(), data);
return (0, _vue.nextTick)();
};
const getWidgetById = id => {
const {
widgetObjList
} = reactData;
if (id) {
const widgetId = _xeUtils.default.toNumber(id);
const rest = _xeUtils.default.findTree(widgetObjList, item => item && item.id === widgetId, {
children: 'children'
});
if (rest) {
return rest.item;
}
}
return null;
};
const getWidgetData = () => {
const objList = _xeUtils.default.clone(reactData.widgetObjList, true);
_xeUtils.default.eachTree(objList, item => {
item.model.value = null;
}, {
children: 'children'
});
return objList;
};
const loadWidgetData = widgetData => {
reactData.widgetObjList = (widgetData || []).map(item => (0, _widgetInfo.configToWidget)(item));
return (0, _vue.nextTick)();
};
const openStyleSetting = () => {
const $layoutStyle = refLayoutStyle.value;
if ($layoutStyle) {
$layoutStyle.openStylePreview();
}
return (0, _vue.nextTick)();
};
const clearConfig = () => {
reactData.widgetObjList = [];
initSettingForm();
return (0, _vue.nextTick)();
};
const formDesignMethods = {
dispatchEvent(type, params, evnt) {
emit(type, (0, _ui.createEvent)(evnt, {
$xeFormDesign
}, params));
},
createWidget,
createEmptyWidget,
getConfig() {
return {
formConfig: getFormConfig(),
widgetData: getWidgetData()
};
},
clearConfig,
loadConfig,
reloadConfig,
getFormConfig,
loadFormConfig,
getWidgetById,
getFormData() {
const {
widgetObjList
} = reactData;
const formData = {};
_xeUtils.default.eachTree(widgetObjList, widget => {
formData[widget.field] = null;
}, {
children: 'children'
});
return formData;
},
getWidgetData,
loadWidgetData,
refreshPreviewView() {
const $layoutStyle = refLayoutStyle.value;
if ($layoutStyle) {
$layoutStyle.updatePreviewView();
}
return (0, _vue.nextTick)();
},
openStyleSetting
};
const updateWidgetConfigs = () => {
const {
widgets
} = props;
const widgetConfs = [];
const baseWidgets = [];
const layoutWidgets = [];
const advancedWidgets = [];
const customGroups = [];
_ui.renderer.forEach((item, name) => {
const {
createFormDesignWidgetConfig
} = item;
if (createFormDesignWidgetConfig) {
const widthItem = createWidget(name);
const widgetConf = (0, _widgetInfo.getWidgetConfig)(name);
const widgetCustomGroup = (0, _widgetInfo.getWidgetConfigCustomGroup)(name, $xeFormDesign);
// 如果自定义组
if (widgetCustomGroup) {
const cusGroup = customGroups.find(item => item.title === widgetCustomGroup);
if (cusGroup) {
cusGroup.children.push(widthItem);
} else {
customGroups.push({
title: widgetCustomGroup,
children: [widthItem]
});
}
} else {
switch (widgetConf.group) {
case 'layout':
layoutWidgets.push(widthItem);
break;
case 'advanced':
advancedWidgets.push(widthItem);
break;
default:
// 已废弃 title
if (!['title'].includes(widthItem.name)) {
baseWidgets.push(widthItem);
}
break;
}
}
}
});
if (baseWidgets.length) {
widgetConfs.push({
group: 'base',
children: baseWidgets
});
}
if (layoutWidgets.length) {
widgetConfs.push({
group: 'layout',
children: layoutWidgets
});
}
if (advancedWidgets.length) {
widgetConfs.push({
group: 'advanced',
children: advancedWidgets
});
}
if (customGroups.length) {
widgetConfs.push(...customGroups);
}
if (widgets && widgets.length) {
reactData.widgetConfigs = props.widgets.map(config => {
return {
title: config.customGroup,
group: config.group,
children: config.children ? config.children.map(name => {
const widthItem = createWidget(name);
return widthItem;
}) : []
};
});
} else {
reactData.widgetConfigs = widgetConfs;
}
};
const validWidgetUnique = widgetName => {
const {
widgetObjList
} = reactData;
const widgetConf = (0, _widgetInfo.getWidgetConfig)(widgetName);
if (widgetConf.unique) {
const existWidgetList = [];
_xeUtils.default.eachTree(widgetObjList, obj => {
if (obj.name === widgetName) {
existWidgetList.push(obj);
}
}, {
children: 'children'
});
const status = existWidgetList.length < 1;
if (!status) {
if (_ui.VxeUI.modal) {
_ui.VxeUI.modal.message({
content: (0, _ui.getI18n)('vxe.formDesign.error.wdFormUni'),
status: 'error',
id: 'wdFormUni'
});
}
}
return status;
}
return true;
};
const formDesignPrivateMethods = {
validWidgetUnique,
handleClickWidget(evnt, item) {
if (item && item.name) {
evnt.stopPropagation();
reactData.activeWidget = item;
formDesignMethods.dispatchEvent('click-widget', {
widget: item
}, evnt);
}
},
handleCopyWidget(evnt, widget) {
const {
widgetObjList
} = reactData;
const rest = _xeUtils.default.findTree(widgetObjList, obj => obj.id === widget.id, {
children: 'children'
});
if (rest) {
evnt.stopPropagation();
if (validWidgetUnique(widget.name)) {
const {
path
} = rest;
const rootIndex = Number(path[0]);
const newWidget = createWidget(widget.name);
// 标题副本
if (newWidget.title) {
newWidget.title = (0, _ui.getI18n)('vxe.formDesign.widget.copyTitle', [`${widget.title}`.replace((0, _ui.getI18n)('vxe.formDesign.widget.copyTitle', ['']), '')]);
}
if (rootIndex >= widgetObjList.length - 1) {
widgetObjList.push(newWidget);
} else {
widgetObjList.splice(rootIndex + 1, 0, newWidget);
}
reactData.activeWidget = newWidget;
reactData.widgetObjList = [...widgetObjList];
formDesignMethods.dispatchEvent('copy-widget', {
widget,
newWidget
}, evnt);
}
}
},
handleRemoveWidget(evnt, widget) {
const {
widgetObjList
} = reactData;
const rest = _xeUtils.default.findTree(widgetObjList, obj => obj.id === widget.id, {
children: 'children'
});
if (rest) {
const {
index,
parent,
items
} = rest;
evnt.stopPropagation();
if (index >= items.length - 1) {
reactData.activeWidget = items[index - 1];
} else {
reactData.activeWidget = items[index + 1] || null;
}
// 如果是行控件,使用空的控件占位
if (parent && parent.name === 'row') {
items[index] = createEmptyWidget();
} else {
items.splice(index, 1);
}
reactData.widgetObjList = [...widgetObjList];
formDesignMethods.dispatchEvent('remove-widget', {
widget
}, evnt);
}
}
};
const createSettingForm = () => {
const {
formRender,
showPc,
showMobile
} = props;
let conf = (0, _defaultSettingData.getDefaultSettingFormData)({
pcVisible: showPc,
mobileVisible: showMobile
});
// 如果为自定义渲染
if (formRender) {
const compConf = _ui.renderer.get(formRender.name);
const createFormConfig = compConf ? compConf.createFormDesignSettingFormConfig : null;
conf = (createFormConfig ? createFormConfig({}) : {}) || {};
}
return conf;
};
const initSettingForm = () => {
reactData.formData = createSettingForm();
};
const openStylePreviewEvent = () => {
openStyleSetting();
};
Object.assign($xeFormDesign, formDesignMethods, formDesignPrivateMethods);
const renderLayoutHeader = () => {
const extraSlot = slots.extra;
return (0, _vue.h)('div', {
class: 'vxe-form-design--header-wrapper'
}, [(0, _vue.h)('div', {
class: 'vxe-form-design--header-left'
}), (0, _vue.h)('div', {
class: 'vxe-form-design--header-middle'
}), (0, _vue.h)('div', {
class: 'vxe-form-design--header-right'
}, [extraSlot ? (0, _vue.h)('div', {
class: 'vxe-form-design--header-extra'
}, extraSlot({})) : (0, _ui.renderEmptyElement)($xeFormDesign), (0, _vue.h)('div', {
class: 'vxe-form-design--header-setting'
}, [(0, _vue.h)(_button.default, {
mode: 'text',
status: 'primary',
icon: (0, _ui.getIcon)().FORM_DESIGN_STYLE_SETTING,
content: (0, _ui.getI18n)('vxe.formDesign.styleSetting.btn'),
onClick: openStylePreviewEvent
})])])]);
};
const renderVN = () => {
const {
height,
showHeader
} = props;
const vSize = computeSize.value;
const headerSlot = slots.header;
const footerSlot = slots.footer;
return (0, _vue.h)('div', {
ref: refElem,
class: ['vxe-form-design', {
[`size--${vSize}`]: vSize
}],
style: height ? {
height: (0, _dom.toCssUnit)(height)
} : null
}, [showHeader || headerSlot ? (0, _vue.h)('div', {
class: 'vxe-form-design--header'
}, headerSlot ? headerSlot({}) : renderLayoutHeader()) : (0, _vue.createCommentVNode)(), (0, _vue.h)('div', {
class: 'vxe-form-design--body'
}, [(0, _vue.h)(_layoutWidget.default), (0, _vue.h)(_layoutPreview.default), (0, _vue.h)(_layoutSetting.default), (0, _vue.h)(_layoutStyle.default, {
ref: refLayoutStyle
})]), footerSlot ? (0, _vue.h)('div', {
class: 'vxe-form-design--footer'
}, footerSlot ? footerSlot({}) : []) : (0, _vue.createCommentVNode)()]);
};
$xeFormDesign.renderVN = renderVN;
(0, _vue.watch)(() => props.widgets, () => {
updateWidgetConfigs();
});
(0, _vue.watch)(() => props.widgets, () => {
updateWidgetConfigs();
});
(0, _vue.watch)(() => props.config, value => {
loadConfig(value || {});
});
initSettingForm();
updateWidgetConfigs();
if (props.config) {
loadConfig(props.config);
}
(0, _vue.provide)('$xeFormDesign', $xeFormDesign);
return $xeFormDesign;
},
render() {
return this.renderVN();
}
});