@zhsz/cool-design-crud
Version:
547 lines (546 loc) • 16.8 kB
JavaScript
"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
const core$1 = require("@formily/core");
const helper = require("./helper.js");
require("../../utils/test.js");
const core = require("../../hooks/core.js");
const index$1 = require("../../utils/index.js");
const schema = require("../../hooks/schema.js");
require("../../hooks/table.js");
const formHook = require("../../utils/form-hook.js");
const coolDesign = require("@zhsz/cool-design");
const tdesignVueNext = require("tdesign-vue-next");
const webVue = require("@arco-design/web-vue");
const parse = require("../../utils/parse.js");
const transform = require("../../utils/transform.js");
const index = require("../dialog/index.js");
const vue$1 = require("@formily/vue");
const lodashEs = require("lodash-es");
const XEUtils = require("xe-utils");
const cloneDeep = require("clone-deep");
function _isSlot(s) {
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !vue.isVNode(s);
}
const ClForm = /* @__PURE__ */ vue.defineComponent({
name: "cl-form",
components: {
BaseForm: coolDesign.BaseForm,
TdButton: tdesignVueNext.Button,
ClDialog: index.default,
Loading: tdesignVueNext.Loading
},
props: {
inner: Boolean,
inline: Boolean,
/**
* @zh 表单的布局方式,包括水平、垂直、多列
* @en The layout of the form, including horizontal, vertical, and multi-column
* @values 'horizontal', 'vertical', 'inline'
*/
layout: {
type: String,
default: "horizontal"
},
/**
* @zh 标签元素布局选项。参数同 `<col>` 组件一致
* @en Label element layout options. The parameters are the same as the `<col>` component
*/
labelColProps: {
type: Object
},
/**
* @zh 表单控件布局选项。参数同 `<col>` 组件一致
* @en Form control layout options. The parameters are the same as the `<col>` component
*/
wrapperColProps: {
type: Object
},
labelColStyle: Object,
wrapperColStyle: Object,
/**
* @zh 标签的对齐方向
* @en Alignment direction of the label
* @values 'left', 'right'
*/
labelAlign: {
type: String,
default: "right"
},
/**
* @zh 是否开启自动标签宽度,仅在 `layout="horizontal"` 下生效。
* @en Whether to enable automatic label width, it only takes effect under `layout="horizontal"`.
* @version 2.13.0
*/
autoLabelWidth: {
type: Boolean,
default: false
},
customClass: String,
/** 副作用逻辑,用于实现各种联动逻辑 */
formEffects: Function,
formRow: {
type: Object,
default: () => {
return {
style: "width:100%;margin:0;",
gutter: [16, 16],
justify: "start",
align: "start",
div: false,
wrap: true
};
}
}
},
setup(props, {
expose,
slots
}) {
const {
dict,
style,
pageLayoutId
} = core.useTools();
const config = vue.reactive({
title: "-",
width: "50%",
height: "100%",
showBox: false,
scope: {},
registerComponents: {},
effects: void 0,
props: {
formRow: props.formRow
},
on: {},
op: {
hidden: false,
saveButtonText: dict.label.save,
closeButtonText: dict.label.close,
buttons: ["close", "save"]
},
schema: {},
dialog: {
closeOnOverlayClick: false,
closeOnEscKeydown: false,
attach: "body"
},
form: {},
_data: {}
});
const Form = core$1.createForm({
effects: props.formEffects
});
const SchemaJson = vue.ref({});
let SchemaFieldState;
vue$1.Schema.enablePolyfills(["1.0"]);
vue$1.Schema.registerTypeDefaultComponents(coolDesign.registerTypes);
core$1.registerValidateFormats({
phone: coolDesign.SchemaFormats.REGEXP_PHONE
});
const form = vue.reactive({});
let defForm = null;
let closeAction = "close";
const saving = vue.ref(false);
const visible = vue.ref(false);
const loading = vue.ref(false);
const Action = helper.useAction({
config,
form,
Form
});
const FormApi = core.useElApi(["validate", "getState", "setState", "notify", "query", "clearErrors", "setEffects", "removeEffects", "addEffects"], Form);
const plugin = helper.usePlugins({
visible
});
function showLoading() {
loading.value = true;
}
function hideLoading() {
loading.value = false;
}
function done() {
saving.value = false;
}
function close(action) {
if (action) {
closeAction = action;
}
beforeClose(() => {
visible.value = false;
done();
});
onClosed();
}
function beforeClose(done2) {
var _a;
if ((_a = config.on) == null ? void 0 : _a.close) {
config.on.close(closeAction, done2);
} else {
done2();
}
}
function onClosed() {
Form.setValues({}, "overwrite");
Form.clearErrors();
}
function clear() {
for (const i in form) {
if (lodashEs.isArray(form[i])) {
form[i] = [];
} else if (XEUtils.isString(form[i])) {
form[i] = "";
} else if (lodashEs.isNumber(form[i])) {
form[i] = 0;
} else {
form[i] = void 0;
}
}
Form.setValues(form, "overwrite");
return form;
}
function reset() {
if (defForm) {
for (const i in defForm) {
form[i] = cloneDeep(defForm[i]);
}
}
Form.setValues(form, "overwrite");
return form;
}
function submit(callback) {
Form.submit(async (value) => {
var _a;
saving.value = true;
let d = cloneDeep(value);
for (const item in config.schema) {
const element = config.schema[item];
const value2 = d[item];
if (element.type !== "void") {
formHook.default.submit({
hook: element.hook,
prop: item,
value: value2,
form: d
});
} else if (element.properties) {
transform.processProperties(element.properties, formHook.default, d, "submit");
}
}
const submit2 = callback || ((_a = config.on) == null ? void 0 : _a.submit);
function findFieldsWithFilter(schema2) {
const fieldsWithFilter = [];
function traverse(node) {
if (node && typeof node === "object" && !Array.isArray(node)) {
for (const key in node) {
const field = node[key];
if ((field == null ? void 0 : field._filter) === true) {
fieldsWithFilter.push(key);
}
traverse(field);
}
}
}
traverse(schema2);
return fieldsWithFilter;
}
const filterFields = findFieldsWithFilter(config.schema || {});
function deepOmit(obj, keysToOmit) {
function omitKeysRecursively(value2) {
if (lodashEs.isArray(value2)) {
return value2.map(omitKeysRecursively);
} else if (lodashEs.isObject(value2)) {
return lodashEs.mapValues(lodashEs.omitBy(value2, (v, k) => keysToOmit.includes(k)), omitKeysRecursively);
}
return value2;
}
return omitKeysRecursively(obj);
}
d = deepOmit(d, filterFields);
if (submit2) {
submit2(await plugin.submit(d), {
close() {
close("save");
},
done
});
} else {
done();
}
});
}
function open(options, plugins) {
if (!options) {
return console.error("Options is not null");
}
if (options.isReset !== false) {
clear();
}
closeAction = "close";
function deep(schema2) {
const transformSchema = cloneDeep(schema2);
for (const item in transformSchema) {
const element = transformSchema[item];
if (lodashEs.isObject(element)) {
parse.calculateProperties(element, form);
}
}
return transformSchema;
}
for (const i in config) {
switch (i) {
case "schema":
config.schema = deep(options.schema || {});
break;
case "on":
case "op":
case "props":
case "dialog":
case "_data":
index$1.deepMerge(config[i], options[i] || {});
break;
case "title":
case "width":
default:
config[i] = options[i];
break;
}
}
const defaultSchema = transform.extractDefaultsRecursively(options.schema);
if (options == null ? void 0 : options.schema) {
for (const i in defaultSchema) {
form[i] = defaultSchema[i];
}
}
if (options == null ? void 0 : options.form) {
for (const i in options == null ? void 0 : options.form) {
form[i] = options.form[i];
}
}
for (const item in config.schema) {
const element = config.schema[item];
if (element.type !== "void") {
formHook.default.bind({
hook: element.hook,
schema: element,
prop: item,
value: form[item],
form
});
} else if (element.properties) {
transform.processProperties(element.properties, formHook.default, form, "bind");
}
}
if (!defForm) {
defForm = cloneDeep(form);
}
plugin.create(plugins);
SchemaFieldState = coolDesign.ClCreateSchemaField(config == null ? void 0 : config.registerComponents, config == null ? void 0 : config.scope);
SchemaJson.value = vue.unref(schema.useSchema(config, Form));
if (config.effects) {
Form.addEffects(Form.id, config.effects);
}
const log = lodashEs.debounce(() => {
if (config.effects) {
console.log("form ------> effects:", config.effects);
}
console.log("form ------> schema:", vue.unref(SchemaJson));
(config == null ? void 0 : config.scope) && console.log("form ------> scope", vue.unref(config == null ? void 0 : config.scope));
}, 1e3);
log();
bindForm(form);
visible.value = true;
vue.nextTick(() => {
setTimeout(() => {
var _a;
if ((_a = config.on) == null ? void 0 : _a.open) {
config.on.open(form);
}
}, 10);
});
}
function bindForm(data) {
for (const item in config.schema) {
const element = config.schema[item];
if (element.type !== "void") {
formHook.default.bind({
hook: element.hook,
prop: item,
value: data[item],
form: data
});
} else if (element.properties) {
transform.processProperties(element.properties, formHook.default, data, "bind");
}
}
Object.assign(form, data);
Form.setValues(form, "overwrite");
}
function renderFormItem(slot) {
return vue.createVNode(SchemaFieldState.SchemaField, {
"schema": vue.unref(SchemaJson)
}, {
default: () => [slot == null ? void 0 : slot()]
});
}
function renderForm() {
if (!visible.value)
return "";
const {
readOnly,
disabled
} = config._data;
Form.setState((state) => {
state.editable = !readOnly;
state.disabled = disabled;
});
const FormItem = renderFormItem(slots == null ? void 0 : slots.default);
return vue.createVNode(coolDesign.BaseForm, vue.mergeProps({
"form": Form
}, config.props, {
"layout": props.layout,
"labelColProps": props.labelColProps,
"wrapperColProps": props.wrapperColProps,
"labelColStyle": props.labelColStyle,
"wrapperColStyle": props.wrapperColStyle,
"labelAlign": config.props.labelAlign || props.labelAlign,
"autoLabelWidth": props.autoLabelWidth
}), {
default: () => {
return vue.createVNode("div", {
"class": "cl-form__container"
}, [slots.prepend && slots.prepend({
scope: Form
}), vue.createVNode(webVue.Row, config.props.formRow, _isSlot(FormItem) ? FormItem : {
default: () => [FormItem]
}), slots.append && slots.append({
scope: Form
})]);
}
});
}
function renderFooter() {
const {
hidden,
buttons,
saveButtonText,
closeButtonText,
justify
} = (
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
config.op
);
const {
style: style2
} = core.useTools();
let buttonList = [];
if (lodashEs.isFunction(buttons)) {
buttonList = buttons(Form);
} else if (lodashEs.isArray(buttons)) {
buttonList = buttons;
}
const Btns = buttonList == null ? void 0 : buttonList.map((e) => {
let _slot, _slot2;
switch (e) {
case "save":
return vue.createVNode(tdesignVueNext.Button, {
"theme": "primary",
"size": style2.size,
"disabled": loading.value,
"loading": saving.value,
"onClick": () => {
submit();
}
}, _isSlot(_slot = index$1.parseFunctionToString(saveButtonText, form)) ? _slot : {
default: () => [_slot]
});
case "close":
return vue.createVNode(tdesignVueNext.Button, {
"variant": "outline",
"size": style2.size,
"onClick": () => {
close("close");
}
}, _isSlot(_slot2 = index$1.parseFunctionToString(closeButtonText, form)) ? _slot2 : {
default: () => [_slot2]
});
default:
return !e.hidden && vue.createVNode(tdesignVueNext.Button, vue.mergeProps(lodashEs.omit(e, ["type", "onClick", "hidden"]), {
"type": e.type,
"size": style2.size,
"onClick": () => {
const closeFun = (action) => {
close(action);
};
e.onClick({
scope: Form,
close: closeFun
});
}
}), {
default: () => [e.label]
});
}
});
return hidden || vue.createVNode("div", {
"class": "cl-form__footer",
"style": {
justifyContent: justify || "flex-end"
}
}, [Btns]);
}
expose({
Form,
SchemaJson,
visible,
saving,
form,
config,
loading,
open,
done,
close,
clear,
reset,
submit,
bindForm,
showLoading,
hideLoading,
...Action,
...FormApi
});
const formNode = () => vue.createVNode("div", {
"class": ["cl-form", props.customClass]
}, [renderForm()]);
return () => {
var _a, _b, _c, _d, _e, _f;
if (props.inner) {
return formNode();
} else {
return vue.createVNode(index.default, {
"modelValue": visible.value,
"onUpdate:modelValue": ($event) => visible.value = $event,
"title": config.title,
"width": config.width,
"height": config.height,
"pageLayoutId": pageLayoutId,
"showBox": index$1.parseFunction(config == null ? void 0 : config.showBox, false),
"beforeClose": beforeClose,
"onClosed": onClosed,
"keepAlive": false,
"dialogProps": config.dialog,
"watermarkText": (_a = config.dialog) == null ? void 0 : _a.watermarkText,
"watermarkProps": (_b = config.dialog) == null ? void 0 : _b.watermarkProps,
"watermarkDic": ((_c = config.dialog) == null ? void 0 : _c.watermarkDic) || (dict == null ? void 0 : dict.watermark) || ((_d = config.dialog) == null ? void 0 : _d.watermarkDic),
"pageStyle": (_e = config.props) == null ? void 0 : _e.pageStyle,
"pageClass": (_f = config.props) == null ? void 0 : _f.pageClass
}, {
default: formNode,
footer: renderFooter
});
}
};
}
});
exports.default = ClForm;