UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

1,478 lines 132 kB
var Re = Object.defineProperty; var Le = (n, t, e) => t in n ? Re(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e; var v = (n, t, e) => Le(n, typeof t != "symbol" ? t + "" : t, e); import { createVNode as T, createTextVNode as Q, defineComponent as D, ref as L, watch as ce, onMounted as Z, onBeforeUnmount as ue, onUpdated as Be, Teleport as Ne, Fragment as Oe, nextTick as pe, inject as ne, computed as me, triggerRef as $e } from "vue"; import { resolveAppearance as Ae, createPropsResolver as fe, getPropsResolverGenerator as Ue } from "../dynamic-resolver/index.esm.js"; import { FDynamicFormGroup as ge } from "../dynamic-form/index.esm.js"; import { FDynamicFormGroupDesign as qe } from "../../designer/dynamic-form/index.esm.js"; import { FormSchemaEntityField$Type as oe, FormSchemaEntityFieldType$Type as je, EVENT_PROPERTY_TAB_IDS as re, getCustomClass as ze } from "../common/index.esm.js"; import { DgControl as g, canvasChanged as z, refreshCanvas as Ge, useDesignerComponent as He } from "../designer-canvas/index.esm.js"; import { FMessageBoxService as We } from "../message-box/index.esm.js"; import { cloneDeep as J, isPlainObject as se } from "lodash-es"; import { FormBindingType as De } from "../property-panel/index.esm.js"; import { AvatarProperty as _e } from "../avatar/index.esm.js/src/property-config/avatar.property-config"; import { CheckGroupProperty as Xe } from "../checkbox-group/index.esm.js/src/property-config/check-group.property-config"; import { CheckBoxProperty as Ye } from "../checkbox/index.esm.js/src/property-config/checkbox.property-config"; import { ComboListProperty as Je } from "../combo-list/index.esm.js/src/property-config/combo-list.property-config"; import { DatePickerProperty as Qe } from "../date-picker/index.esm.js/src/property-config/date-picker.property-config"; import { InputGroupProperty as Ze } from "../input-group/index.esm.js/src/property-config/input-group.property-config"; import { LanuageTextBoxPropertyConfig as Ke } from "../language-textbox/index.esm.js/src/property-config/language-textbox.property-config"; import { LookupPropertyConfig as et } from "../lookup/index.esm.js/src/property-config/lookup.property-config"; import { NumberRangeProperty as tt } from "../number-range/index.esm.js/src/property-config/number-range.property-config"; import { NumberSpinnerProperty as it } from "../number-spinner/index.esm.js/src/property-config/number-spinner.property-config"; import { RadioGroupProperty as nt } from "../radio-group/index.esm.js/src/property-config/radio-group.property-config"; import { SwitchProperty as ot } from "../switch/index.esm.js/src/property-config/switch.property-config"; import { TextareaProperty as rt } from "../textarea/index.esm.js/src/property-config/textarea.property-config"; import { TimePickerProperty as st } from "../time-picker/index.esm.js/src/property-config/time-picker.property-config"; const K = /* @__PURE__ */ new Map([ ["appearance", Ae] ]), lt = "https://json-schema.org/draft/2020-12/schema", at = "https://farris-design.gitee.io/table.schema.json", dt = "table", ct = "A Farris design-time layout table", ut = "object", pt = { id: { type: "string" }, type: { type: "string", default: "table" }, devMode: { type: "string", default: "advanced" }, appearance: { type: "object", properties: { class: { type: "string" }, style: { type: "string" } }, default: {} }, border: { type: "object", properties: { width: { type: "number" }, enableColor: { type: "boolean" }, color: { type: "string" } }, default: { width: 1, enableColor: !1, color: "#eaecf3" } }, font: { type: "object", properties: { size: { type: "number" }, enableColor: { type: "boolean" }, color: { type: "string" }, family: { type: "string" } }, default: { size: 13, enableColor: !1, color: "#2d2f33", family: "sans-serif" } }, rows: { type: "array", default: [] }, visible: { type: "boolean", default: !0 } }, mt = [ "id", "type", "rows" ], he = { $schema: lt, $id: at, title: dt, description: ct, type: ut, properties: pt, required: mt }, ft = "https://json-schema.org/draft/2020-12/schema", gt = "https://farris-design.gitee.io/table-td.schema.json", ht = "table-td", bt = "A Farris design-time layout table cell", yt = "object", vt = { id: { type: "string" }, type: { type: "string", default: "" }, tdType: { type: "string", default: "staticText" }, staticText: { type: "object", properties: { text: { type: "string" }, require: { type: "boolean" } }, default: { text: "", require: !1 } }, editor: { type: "object", properties: { type: { type: [ "string", "null" ] }, id: { type: "string" } }, default: { type: null } }, binding: { type: "object", default: {} }, modelValue: { type: [ "string", "boolean", "array", "number", "object" ], default: null }, colspan: { type: "number", default: 1 }, rowspan: { type: "number", default: 1 }, align: { type: "string", default: "left" }, valign: { type: "string", default: "middle" }, appearance: { type: "object", properties: { class: { type: "string" }, style: { type: "string" } }, default: { class: "", style: "" } }, size: { type: "object" }, markRow: { type: "number", default: 0 }, markCol: { type: "number", default: 0 }, invisible: { type: "boolean", default: !1 }, editorLabel: { type: "string", default: "" }, expandable: { type: [ "boolean", "string" ] }, expandMode: { type: "string", default: "text" }, expandContent: { type: "string" }, expandDisabled: { type: [ "boolean", "string" ] } }, Ct = [ "id", "type" ], wt = { onExpandClick: "扩展按钮点击事件", onClickLabel: "标签点击事件", fieldValueChanging: "绑定字段值变化前事件", fieldValueChanged: "绑定字段值变化后事件" }, xt = { $schema: ft, $id: gt, title: ht, description: bt, type: yt, properties: vt, required: Ct, events: wt }; function ee() { return "x" + Math.random().toString(36).slice(2, 10) + Date.now().toString(36).slice(-4); } function be() { return { id: ee(), type: "table-td", tdType: "editor", staticText: { text: "", require: !1 }, editor: { type: null }, binding: null, colspan: 1, rowspan: 1, align: "right", valign: "top", appearance: { class: "farris-group-wrap--input", style: "" }, size: null }; } function Tt(n, t) { const e = []; for (let i = 0; i < n; i++) { const o = []; for (let r = 0; r < t; r++) o.push(be()); e.push({ id: ee(), type: "table-row", columns: o }); } return e; } function te(n, t, e) { return (!t.rows || t.rows.length === 0) && (t.rows = Tt(2, 2)), t; } const _ = { id: { type: String, default: "" }, componentId: { type: String, default: "" }, customClass: { type: String, default: "" }, customStyle: { type: String, default: "" }, devMode: { type: String, default: "advanced" }, rows: { type: Array, default: () => [] }, border: { type: Object, default: () => ({ width: 1, enableColor: !1, color: "#eaecf3" }) }, font: { type: Object, default: () => ({ size: 13, enableColor: !1, color: "#2d2f33", family: "sans-serif" }) }, visible: { type: Boolean, default: !0 }, modelValue: { type: Object, default: () => ({}) } }, Qi = fe(_, he, K, te), le = Ue(_, he, K, te), ye = { id: { type: String, default: "" }, type: { type: String, default: "" }, tdType: { type: String, default: "staticText" }, staticText: { type: Object, default: () => ({ text: "", require: !1 }) }, editor: { type: Object, default: () => ({ type: null }) }, binding: { type: Object, default: () => ({}) }, modelValue: { type: [String, Number, Boolean, Object, Array], default: void 0 }, colspan: { type: Number, default: 1 }, rowspan: { type: Number, default: 1 }, align: { type: String, default: "left" }, valign: { type: String, default: "middle" }, appearance: { type: Object, default: () => ({ class: "", style: "" }) }, size: { type: Object, default: null }, markRow: { type: Number, default: 0 }, markCol: { type: Number, default: 0 }, invisible: { type: Boolean, default: !1 }, editorLabel: { type: String, default: "" }, expandable: { type: [Boolean, String], default: !1 }, expandMode: { type: String, default: "text" }, expandContent: { type: String, default: "" }, expandDisabled: { type: [Boolean, String], default: !1 } }, ae = fe(ye, xt, K, te); function ve(n, t = !1) { var i, o; const e = { "box-shadow": "0px 0px 0px 1px #eaecf3" }; return t && Object.assign(e, { width: "inherit", height: "inherit", background: "inherit", "margin-bottom": 0 }), (i = n.size) != null && i.height && (e.height = `${n.size.height}px`), (o = n.size) != null && o.width && (e.width = `${n.size.width}px`), e; } function Ce(n, t, e = !1) { var s, p; const i = n.border || {}, o = n.font || {}, r = { border: `${i.width ?? 1}px solid ${i.enableColor ? i.color : "#eaecf3"}`, "text-align": t.align || "left", "vertical-align": t.valign || "middle" }; if (o.size && (r["font-size"] = `${o.size}px`), o.enableColor && o.color && (r.color = o.color), o.family && (r["font-family"] = o.family), (s = t.appearance) != null && s.style && t.appearance.style.split(";").forEach((m) => { const [c, f] = m.split(":"); c && f && (r[c.trim()] = f.trim()); }), e) { const m = ((p = n.border) == null ? void 0 : p.width) || 1; r["border-width"] = `${m + 1}px !important`; } return r; } function we(n) { var t, e; return T("div", { class: "farris-label-wrap" }, [T("label", { class: "col-form-label" }, [(t = n.staticText) != null && t.require ? T("span", { class: "farris-label-info text-danger" }, [Q("*")]) : null, T("span", { class: "farris-label-text" }, [((e = n.staticText) == null ? void 0 : e.text) || ""])])]); } function xe(n, t) { var o, r; const e = (o = n.binding) == null ? void 0 : o.field; if (!e) return null; if (t.design) { const s = Object.assign({}, n.editor, { required: !1 }); return T(qe, { id: n.id, showLabel: !1, label: "", editor: s, required: !1, customClass: "h-100", customStyle: "pointer-events:none" }, null); } const i = t.data || {}; return T(ge, { id: n.id, key: n.id, showLabel: !1, customClass: "h-100", editor: n.editor, required: (r = n.editor) == null ? void 0 : r.required, modelValue: i[e], "onUpdate:modelValue": (s) => i[e] = s, onChange: (s) => t.onChange && t.onChange(e, s) }, null); } const X = /* @__PURE__ */ D({ name: "FTable", props: _, emits: ["update:modelValue", "change"], setup(n, t) { const e = L(n.modelValue || {}); ce(() => n.modelValue, (r) => { e.value = r || {}; }); function i(r, s) { t.emit("update:modelValue", e.value), t.emit("change", { field: r, value: s, modelValue: e.value }); } function o(r) { var m; const s = r.tdType === "staticText", p = t.slots[r.id]; return T("td", { key: r.id, colspan: r.colspan, rowspan: r.rowspan, class: [s ? "farris-group-wrap--label" : "farris-group-wrap--input", (m = r.appearance) == null ? void 0 : m.class], style: Ce(n, r) }, [s ? we(r) : p ? p() : xe(r, { data: e.value, onChange: i })]); } return () => { if (!n.visible) return null; const r = n.rows || []; return T("table", { class: ["table", n.customClass], style: ve(n) }, [T("tbody", null, [r.map((s) => T("tr", { key: s.id }, [s.columns.filter((p) => !p.invisible).map((p) => o(p))]))])]); }; } }), Y = /* @__PURE__ */ D({ name: "FTableTd", props: ye, emits: ["update:modelValue", "change"], inheritAttrs: !1, setup(n, t) { const e = L(n.modelValue); return ce(() => n.modelValue, (i) => { e.value = i; }), () => { var i, o, r; return n.tdType === "staticText" ? T("div", { class: "farris-label-wrap" }, [T("label", { class: "col-form-label" }, [(i = n.staticText) != null && i.require ? T("span", { class: "farris-label-info text-danger" }, [Q("*")]) : null, T("span", { class: "farris-label-text" }, [((o = n.staticText) == null ? void 0 : o.text) || ""])])]) : !n.editor || !n.editor.type ? null : T(ge, { id: n.id, key: n.id, showLabel: !1, customClass: "h-100", editor: n.editor, required: (r = n.editor) == null ? void 0 : r.required, modelValue: e.value, label: n.editorLabel, "onUpdate:modelValue": (s) => { e.value = s, t.emit("update:modelValue", s); }, onChange: (s, p) => { t.emit("change", s, p); } }, null); }; } }); class It { getTableTdMetadata() { return be(); } insertColumns(t, e) { for (let i = 0; i < t.length; i++) { const o = this.findPrevColIndex(i, e, t); if (o !== e && t[i].columns[e].invisible) { const r = this.getTableTdMetadata(); r.invisible = !0, t[i].columns.splice(e, 0, r); const s = t[i].columns[o].colspan; t[i].columns[o].colspan = s + 1; for (let p = 0; p < s + 1; p++) t[i].columns[o + p].markCol = p; } else { const r = this.getTableTdMetadata(); t[i].columns.splice(e, 0, r); } } } findPrevColIndex(t, e, i) { return e >= i[t].columns.length || !i[t].columns[e].markCol ? e : this.findPrevColIndex(t, e - 1, i); } findNextColIndex(t, e, i) { return e >= i[t].columns.length || !i[t].columns[e].markCol ? e : this.findNextColIndex(t, e + 1, i); } findPrevRowIndex(t, e, i) { return t >= i.length || !i[t].columns[e].markRow ? t : this.findPrevRowIndex(t - 1, e, i); } findNextRowIndex(t, e, i) { return t >= i.length || !i[t].columns[e].markRow ? t : this.findNextRowIndex(t + 1, e, i); } insertRow(t, e) { const i = []; for (let o = 0; o < e[0].columns.length; o++) { const r = this.findPrevRowIndex(t, o, e), s = this.getTableTdMetadata(); r !== t && e[t].columns[o].invisible ? (s.invisible = !0, i.push(s), e[r].columns[o].rowspan = e[r].columns[o].rowspan + 1) : i.push(s); } e.splice(t, 0, { id: ee(), type: "table-row", columns: i }); for (let o = 0; o < e[t].columns.length; o++) if (e[t].columns[o].invisible) { const r = this.findPrevRowIndex(t - 1, o, e); e[r].columns[o].invisible || this.markTableItem(r, o, e); } } markTableItem(t, e, i) { for (let o = i[t].columns[e].colspan, r = i[t].columns[e].rowspan, s = 0; s < r; s++) for (let p = 0; p < o; p++) i[t + s].columns[e + p].markCol = p, i[t + s].columns[e + p].markRow = s; } } class Te { constructor(t, e, i) { this.designViewModelUtils = t, this.formSchemaUtils = e, this.viewModelId = i; } /** * 移除单元格内的绑定、表达式等 */ removeDesignViewModelFieldInColumns(t) { const e = this.designViewModelUtils.getDgViewModel(this.viewModelId); e && t.forEach((i) => { if (i.binding && i.binding.field) { const o = i.binding.field; e.removeField([o]), this.removeExpression(i, o); } }); } /** * 移除表达式 */ removeExpression(t, e) { const i = this.formSchemaUtils, o = i.getExpressions ? i.getExpressions() : []; if (!o || !o.length) return; const r = o.findIndex((s) => s.target === e); r < 0 || ((o[r].rules || []).forEach((s) => { var c; const p = s.type === "visible" ? t[s.type] : (c = t.editor) == null ? void 0 : c[s.type]; (["visible", "readonly", "required"].includes(s.type) ? p && p.type === "Expression" && p.expressionId === s.id : !0) && !this.checkExpressionOccupiedRepeated(e, s, t.id) && (s.needDelete = !0); }), o[r].rules = (o[r].rules || []).filter((s) => !s.needDelete)); } /** References data-grid: checks if expression is reused by other controls before deletion. */ checkExpressionOccupiedRepeated(t, e, i) { const o = this.formSchemaUtils; return !o.getComponents || !o.getControlsInCmpWidthBinding ? !1 : !!o.getComponents().find((s) => o.getControlsInCmpWidthBinding(s.viewModel, t).filter((m) => { var f; if (m.id === i) return !1; const c = e.type === "visible" ? m[e.type] : (f = m.editor) == null ? void 0 : f[e.type]; return c && c.type === "Expression" && c.expressionId === e.id; }).length > 0); } } class Ft { constructor(t, e, i, o, r) { v(this, "tableTdHelper", new It()); v(this, "selectedColumnIndex", 0); v(this, "selectedRowIndex", 0); v(this, "targetColumn"); v(this, "targetRow"); v(this, "menuConfig", []); v(this, "tableUtils"); this.component = t, this.services = e, this.redraw = i, this.emitCanvasChanged = o, this.viewModelId = r, this.tableUtils = new Te(e.designViewModelUtils, e.formSchemaUtils, this.viewModelId); } /** Called by design component on right-click / widget-panel icon click to set the current target cell. */ setTarget(t, e) { this.selectedRowIndex = t, this.selectedColumnIndex = e, this.targetRow = this.component.rows[t], this.targetColumn = this.component.rows[t].columns[e]; } getMenuConfig() { return this.menuConfig = [ { id: "insertColumnToLeft", title: "左插入列", handle: () => this.insertColumnToLeft() }, { id: "insertColumnToRight", title: "右插入列", handle: () => this.insertColumnToRight() }, { id: "insertRowToTop", title: "上插入行", handle: () => this.insertRowToTop() }, { id: "insertRowToBottom", title: "下插入行", handle: () => this.insertRowToBottom() }, "-", { id: "mergeColumnToRight", title: "向右合并", handle: () => this.mergeColumnToRight(), disable: !this.showMergeColumnToRight() }, { id: "mergeRowToBottom", title: "向下合并", handle: () => this.mergeRowToBottom(), disable: !this.showMergeRowToBottom() }, "-", { id: "splitColumns", title: "拆分成列", handle: () => this.splitColumns(), disable: !this.showSplitColumns() }, { id: "splitRows", title: "拆分成行", handle: () => this.splitRows(), disable: !this.showSplitRows() }, "-", { id: "removeColumn", title: "删除当前列", handle: () => this.removeColumn(), disable: !this.showRemoveColumn() }, { id: "removeRow", title: "删除当前行", handle: () => this.removeRow(), disable: !this.showRemoveRow() } ], this.menuConfig; } question(t, e) { (this.services.messageBox || We).question(t, "", e); } // ===== Insert operations ===== insertColumnToLeft() { this.tableTdHelper.insertColumns(this.component.rows, this.selectedColumnIndex), this.selectedColumnIndex++, this.redraw(); } insertColumnToRight() { const t = this.targetColumn.colspan > 1 ? this.tableTdHelper.findNextColIndex(this.selectedRowIndex, this.selectedColumnIndex + 1, this.component.rows) : this.selectedColumnIndex + 1; this.tableTdHelper.insertColumns(this.component.rows, t), this.redraw(); } insertRowToTop() { this.tableTdHelper.insertRow(this.selectedRowIndex, this.component.rows), this.selectedRowIndex++, this.redraw(); } insertRowToBottom() { const t = this.targetColumn.rowspan > 1 ? this.tableTdHelper.findNextRowIndex(this.selectedRowIndex + 1, this.selectedColumnIndex, this.component.rows) : this.selectedRowIndex + 1; this.tableTdHelper.insertRow(t, this.component.rows), this.redraw(); } // ===== Merge right ===== showMergeColumnToRight() { const { rowspan: t, colspan: e } = this.targetColumn; if (this.selectedColumnIndex + e < this.targetRow.columns.length) { const i = this.targetRow.columns[e + this.selectedColumnIndex]; if (!i.invisible && t === i.rowspan) return !0; } return !1; } mergeColumnToRight() { const t = this.targetColumn.colspan, e = this.selectedColumnIndex + t, i = this.component.rows[this.selectedRowIndex].columns[e]; i.editor && i.editor.type ? this.question("合并后将重置右侧单元格的编辑器,确定合并?", () => { this.tableUtils.removeDesignViewModelFieldInColumns([i]), this.confirmToMergeColumnToRight(i, t); }) : this.confirmToMergeColumnToRight(i, t); } confirmToMergeColumnToRight(t, e) { const i = t.colspan; this.targetColumn.colspan = e + i, t.invisible = !0, this.resetTd(t), this.tableTdHelper.markTableItem(this.selectedRowIndex, this.selectedColumnIndex, this.component.rows), this.redraw(), this.emitCanvasChanged(); } // ===== Merge down ===== showMergeRowToBottom() { const t = this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex].rowspan, e = this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex].colspan; if (t + this.selectedRowIndex < this.component.rows.length) { const i = this.component.rows[t + this.selectedRowIndex].columns[this.selectedColumnIndex]; if (!i.invisible && e === i.colspan) return !0; } return !1; } mergeRowToBottom() { const t = this.targetColumn.rowspan, e = this.selectedRowIndex + t, i = this.component.rows[e].columns[this.selectedColumnIndex]; i.editor && i.editor.type ? this.question("合并后将重置下方单元格的编辑器,确定合并?", () => { this.tableUtils.removeDesignViewModelFieldInColumns([i]), this.confirmToMergeRowToBottom(i, t); }) : this.confirmToMergeRowToBottom(i, t); } confirmToMergeRowToBottom(t, e) { this.targetColumn.rowspan = e + t.rowspan, t.invisible = !0, this.resetTd(t), this.tableTdHelper.markTableItem(this.selectedRowIndex, this.selectedColumnIndex, this.component.rows), this.redraw(), this.emitCanvasChanged(); } resetTd(t) { t.staticText = { text: "", require: !1 }, t.editor = { type: null, binding: null }; } // ===== Split operations ===== showSplitColumns() { return this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex].colspan > 1; } splitColumns() { const { colspan: t, rowspan: e } = this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex]; for (let i = 0; i < t; i++) this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex + i].invisible = !1, this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex + i].colspan = 1, this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex + i].rowspan = e, this.tableTdHelper.markTableItem(this.selectedRowIndex, this.selectedColumnIndex + i, this.component.rows); this.redraw(); } showSplitRows() { return this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex].rowspan > 1; } splitRows() { const { colspan: t, rowspan: e } = this.component.rows[this.selectedRowIndex].columns[this.selectedColumnIndex]; for (let i = 0; i < e; i++) this.component.rows[this.selectedRowIndex + i].columns[this.selectedColumnIndex].invisible = !1, this.component.rows[this.selectedRowIndex + i].columns[this.selectedColumnIndex].rowspan = 1, this.component.rows[this.selectedRowIndex + i].columns[this.selectedColumnIndex].colspan = t, this.tableTdHelper.markTableItem(this.selectedRowIndex, this.selectedColumnIndex + i, this.component.rows); this.redraw(); } // ===== Remove column ===== showRemoveColumn() { const { rows: t } = this.component; return t[this.selectedRowIndex].columns.length > 1 && t[this.selectedRowIndex].columns[this.selectedColumnIndex].colspan === 1; } removeColumn() { this.checkIfHasEditorInColumn() ? this.question("确定移除当前列所有的编辑器配置?", () => this.confirmRemoveColumn()) : this.confirmRemoveColumn(); } confirmRemoveColumn() { const { rows: t } = this.component, e = []; for (let i = 0; i < t.length; i++) { const { colspan: o, rowspan: r } = t[i].columns[this.selectedColumnIndex]; if (t[i].columns[this.selectedColumnIndex].invisible) { const s = this.tableTdHelper.findPrevColIndex(i, this.selectedColumnIndex, t); s !== this.selectedColumnIndex && t[i].columns[s].colspan > 1 && (t[i].columns[s].colspan = t[i].columns[s].colspan - 1); } else o > 1 && (t[i].columns[this.selectedColumnIndex + 1].invisible = !1, t[i].columns[this.selectedColumnIndex + 1].colspan = o - 1, t[i].columns[this.selectedColumnIndex + 1].rowspan = r, this.tableTdHelper.markTableItem(i, this.selectedColumnIndex + 1, t)); e.push(t[i].columns[this.selectedColumnIndex]), t[i].columns.splice(this.selectedColumnIndex, 1); } this.tableUtils.removeDesignViewModelFieldInColumns(e), this.redraw({ clearPropertyPanel: !0 }), this.emitCanvasChanged(); } checkIfHasEditorInColumn() { for (const t of this.component.rows) { const e = t.columns[this.selectedColumnIndex]; if (e && e.tdType === "editor" && e.binding) return !0; } return !1; } // ===== Remove row ===== showRemoveRow() { const { rows: t } = this.component; return t.length > 1 && t[this.selectedRowIndex].columns[this.selectedColumnIndex].rowspan === 1; } removeRow() { this.checkIfHasEditorInRow() ? this.question("确定移除当前行所有的编辑器配置?", () => this.confirmRemoveRow()) : this.confirmRemoveRow(); } checkIfHasEditorInRow() { for (const t of this.component.rows[this.selectedRowIndex].columns) if (t && t.tdType === "editor" && t.binding) return !0; return !1; } confirmRemoveRow() { const { rows: t } = this.component; for (let e = 0; e < t[this.selectedRowIndex].columns.length; e++) { const i = t[this.selectedRowIndex].columns[e].rowspan, o = t[this.selectedRowIndex].columns[e].colspan; if (t[this.selectedRowIndex].columns[e].invisible) { const r = this.tableTdHelper.findPrevRowIndex(this.selectedRowIndex, e, t); r !== this.selectedRowIndex && t[r].columns[e].rowspan > 1 && (t[r].columns[e].rowspan = t[r].columns[e].rowspan - 1); } else i > 1 && (t[this.selectedRowIndex + 1].columns[e].invisible = !1, t[this.selectedRowIndex + 1].columns[e].rowspan = i - 1, t[this.selectedRowIndex + 1].columns[e].colspan = o, this.tableTdHelper.markTableItem(this.selectedRowIndex + 1, e, t)); } this.tableUtils.removeDesignViewModelFieldInColumns(t[this.selectedRowIndex].columns), t.splice(this.selectedRowIndex, 1), this.redraw({ clearPropertyPanel: !0 }), this.emitCanvasChanged(); } } function Et(n, t) { return n.map((e) => e === "-" ? { separator: !0 } : { id: e.id, label: e.title, disabled: !!e.disable, onClick: () => { e.handle && e.handle(), t(); } }); } function kt() { const n = L(!1); return Z(() => { n.value = !0; }), n; } const Mt = { visible: { type: Boolean, default: !1 }, position: { type: Object, default: () => ({ x: 0, y: 0 }) }, options: { type: Array, default: () => [] }, onClose: { type: Function, required: !0 } }, St = /* @__PURE__ */ D({ name: "FTableContextMenu", props: Mt, setup(n) { const t = L(), e = L(null), i = L({ x: 0, y: 0 }), o = kt(), r = () => { if (!t.value) return; const f = t.value.getBoundingClientRect(), l = window.innerWidth, a = window.innerHeight, h = 4; let { x: u, y: d } = n.position; u + f.width > l && (u = n.position.x - f.width), d + f.height > a && (d = n.position.y - f.height), u = Math.max(h, Math.min(u, l - f.width - h)), d = Math.max(h, Math.min(d, a - f.height - h)), (i.value.x !== u || i.value.y !== d) && (i.value = { x: u, y: d }); }, s = (c) => { c.key === "Escape" && n.onClose(); }, p = (c) => { c.disabled || (c.onClick(), n.onClose()); }, m = (c) => { c.stopPropagation(), c.preventDefault(), n.onClose(); }; return Z(() => { document.addEventListener("keydown", s); }), ue(() => { document.removeEventListener("keydown", s); }), Be(() => { r(); }), () => { if (!n.visible) return (i.value.x !== 0 || i.value.y !== 0) && (i.value = { x: 0, y: 0 }), null; const c = i.value.x === 0 && i.value.y === 0 ? n.position : i.value; return o.value ? T(Ne, { to: "body" }, { default: () => [T("div", { class: "context-menu-overlay no-drag", style: { position: "fixed", top: 0, left: 0, width: "100vw", height: "100vh", zIndex: 1e4 }, onClick: m, onContextmenu: (f) => { f.preventDefault(), f.stopPropagation(); } }, [T("div", { ref: t, class: "context-menu", style: { position: "absolute", left: `${c.x}px`, top: `${c.y}px`, background: "#fff", border: "1px solid #d4d6d9", borderRadius: "4px", boxShadow: "0 2px 8px rgba(0,0,0,0.15)", padding: "4px 0", minWidth: "160px", zIndex: 10001 }, onClick: (f) => f.stopPropagation() }, [n.options.map((f, l) => { if ("separator" in f) return T("div", { key: `sep-${l}`, class: "context-menu-separator", style: { height: "1px", margin: "4px 8px", background: "#e0e2e5" } }, null); const a = f; return T("div", { key: a.id, class: "context-menu-item", style: { padding: "6px 16px", cursor: a.disabled ? "not-allowed" : "pointer", fontSize: "13px", color: a.danger ? "#e02020" : a.disabled ? "#bbb" : "#2d2f33", whiteSpace: "nowrap", backgroundColor: e.value === a.id ? "#e8f0fe" : "transparent" }, onClick: () => p(a), onMouseenter: () => { e.value = a.id; }, onMouseleave: () => { e.value = null; } }, [a.icon && T("span", { class: "menu-item-icon" }, [a.icon]), T("span", { class: "menu-item-label" }, [a.label])]); })])])] }) : null; }; } }); function Pt(n) { const { formSchemaUtils: t, formStateMachineUtils: e } = n; function i(m, c = "") { return { path: c + m.code, field: m.id, fullPath: m.code }; } function o(m, c = "") { const f = t.getViewModelById(m); return f ? f.states.map((l) => i(l, c)) : []; } function r(m) { const c = t.getRootViewModelId(), f = o(m); if (m === c) return f; const l = o(c, "root-component."); return [...f, ...l]; } function s(m) { return m.binding && m.binding.path || m.id || ""; } function p() { return e && e.getRenderStates() || []; } return { getVariables: r, getControlName: s, getStateMachines: p }; } class Vt { constructor(t) { v(this, "sessionVariables", [ { key: "CurrentSysOrgName", name: "当前组织Name", description: "当前组织Name" }, // { // key: "CurrentSysOrgCode", // name: "当前组织Code", // description: "当前组织Code" // }, { key: "CurrentSysOrgId", name: "当前组织Id", description: "当前组织Id" }, { key: "CurrentUserName", name: "当前用户Name", description: "当前用户Name" }, { key: "CurrentUserCode", name: "当前用户Code", description: "当前用户Code" }, { key: "CurrentUserId", name: "当前用户Id", description: "当前用户Id" }, { key: "CurrentLanguage", name: "当前语言编号", description: "当前登录的语言编号,例如简体中文返回'zh-CHS',英文返回'en',繁体中文'zh-CHT'" } ]); v(this, "expressionNames", { compute: "计算表达式", dependency: "依赖表达式", validate: "验证表达式", dataPicking: "帮助前表达式", visible: "可见表达式", readonly: "只读表达式", required: "必填表达式" }); v(this, "getExpressionConverter", (t, e) => ({ convertFrom: (i, o, r, s) => { const p = r.getExpressionRuleValue(t, e || o); return p && p.value || ""; }, convertTo: (i, o, r, s, p) => { var m; if (o === "dataPicking" && (r != null && r.target)) { const c = `${r.target}_dataPicking`; ((m = r.rules) == null ? void 0 : m.some( (l) => l.id === c && l.value )) ? i.dictPickingExpressionId = c : delete i.dictPickingExpressionId; } s.updateExpression(r); } })); this.formSchemaService = t; } getExpressionRule(t, e) { const i = this.getExpressionData(); if (!i) return ""; const o = i.find((s) => s.target === t); if (!o) return ""; const r = o.rules.find((s) => s.type === e); return r || ""; } // 获取上下文表单变量 getContextFormVariables() { const { module: t } = this.formSchemaService.getFormSchema(); if (!t.viewmodels || t.viewmodels.length === 0) return []; const e = this.formSchemaService.getRootViewModelId(), i = this.formSchemaService.getViewModelById(e); if (!i || !i.states || i.states.length === 0) return []; const o = []; return i.states.filter((r) => r.category === "remote").forEach((r) => { o.push({ key: r.code, name: r.name, description: r.name, category: r.category }); }), o; } createTreeNode(t, e, i = "label") { return { id: t.id, name: t.name, bindingPath: t[i], parents: e, type: "field" }; } buildEntityFieldsTreeData(t = null, e) { const i = []; return t == null || t.forEach((o) => { var p; const r = this.createTreeNode(o, e); let s = []; (p = o.type) != null && p.fields && (s = this.buildEntityFieldsTreeData(o.type.fields, [...e, o.label])), i.push({ data: r, children: s, expanded: !0 }); }), i; } buildChildEntityTreeData(t = null, e) { const i = []; return t == null || t.forEach((o) => { var m, c; const r = this.createTreeNode(o, e); r.type = "entity"; const s = this.buildEntityFieldsTreeData((m = o.type) == null ? void 0 : m.fields, [...e, o.label]), p = this.buildChildEntityTreeData((c = o.type) == null ? void 0 : c.entities, [...e, o.label]); p != null && p.length && (s == null || s.push(...p)), i.push({ data: r, children: s || [], // 空值回退 expanded: !0 }); }), i; } getEntitiesTreeData() { const t = this.formSchemaService.getSchemaEntities(); if (!(t != null && t.length)) return []; const e = t[0]; if (!(e != null && e.type)) return []; const i = this.buildEntityFieldsTreeData(e.type.fields, [e.code]), o = this.buildChildEntityTreeData(e.type.entities, [e.code]); return o != null && o.length && (i == null || i.push(...o)), { entityCode: e.code, fields: [{ data: this.createTreeNode(e, [], "code"), children: i || [] }] }; } getEntitiesAndVariables() { return { entities: this.getEntitiesTreeData(), variables: { session: { name: "系统变量", items: this.sessionVariables, visible: !1 }, forms: { name: "表单变量", items: this.getContextFormVariables(), visible: !0 } } }; } onBeforeOpenExpression(t, e, i) { const o = i === "Field" ? t.binding.field : t.id, r = this.getExpressionRule(o, e), s = this.getEntitiesAndVariables(), p = { message: ["validate", "required", "dataPicking"].includes(e) && r ? r.message : "", ...s }; return r.messageType != null && (p.messageType = r.messageType), p; } buildRule(t, e, i, o) { const { expression: r, message: s, messageType: p } = e, m = { id: `${t}_${i}`, type: i, value: r }; return (i === "validate" || i === "dataPicking" || i === "required") && (m.message = s), i === "dataPicking" && (m.messageType = p), i === "validate" && o && (m.elementId = o), m; } getExpressionData() { const { expressions: t } = this.formSchemaService.getFormSchema().module; return t || []; } updateExpression(t, e, i, o) { const r = e === "Field" ? t.binding.field : t.id, s = this.buildRule(r, i, o, t.type === "form-group" ? t.id : ""); let m = this.getExpressionData().find((f) => f.targetType === e && f.target === r); const c = (f) => f.value.trim() === ""; if (m) { const f = m.rules.find((l) => l.id === s.id); if (f) c(s) ? m.rules = m.rules.filter((l) => l.id !== s.id) : (Object.assign(f, s), o === "validate" && t.type === "form-group" && (f.elementId = t.id)); else { if (c(s)) return null; m.rules = m.rules || [], m.rules.push(s); } } else { if (c(s)) return null; m = { target: `${r}`, rules: [s], targetType: e }; } return m; } getExpressionEditorOptions(t, e, i, o) { return i.reduce((r, s) => { var m, c; const p = e === "Field" ? (m = t == null ? void 0 : t.binding) == null ? void 0 : m.field : t.id; return r[s] = { hide: e === "Field" ? !!((c = t == null ? void 0 : t.binding) != null && c.field) : !1, description: "", title: this.expressionNames[s], type: "string", $converter: this.getExpressionConverter(p), refreshPanelAfterChanged: !0, editor: { type: "expression-editor", singleExpand: !1, dialogTitle: `${this.expressionNames[s]}编辑器`, showMessage: s === "validate" || s === "dataPicking" || s === "required", showMessageType: s === "dataPicking", beforeOpen: () => this.onBeforeOpenExpression(t, s, e), onSubmitModal: (f) => { const l = this.updateExpression(t, e, f, s); if (o) { const a = this.buildRule(p, f, s); o(a); } return l; } } }, r; }, {}); } getExpressionInfo(t, e, i) { const o = e === "Field" ? t.binding.field : t.id, r = this.getExpressionRule(o, i), s = { value: r && r.value, targetId: o, targetType: e, expressionType: i }; return r && r.message && (s.message = r.message), s; } getExpressionConfig(t, e, i = ["compute", "dependency", "validate"], o) { var r; return { description: "表达式", title: "表达式", hide: !(t.binding && ((r = t.binding) == null ? void 0 : r.type) === "Form"), properties: { ...this.getExpressionEditorOptions(t, e, i, o) } }; } getExpressionOptions(t, e, i) { const o = this.getExpressionInfo(t, e, i); return { dialogTitle: `${this.expressionNames[i] || "表达式"}编辑器`, singleExpand: !1, showMessage: i === "required", beforeOpen: () => this.onBeforeOpenExpression(t, i, e), expressionInfo: o }; } } class Ie { constructor(t, e) { v(this, "componentId"); v(this, "viewModelId"); v(this, "eventsEditorUtils"); v(this, "formSchemaUtils"); v(this, "formMetadataConverter"); v(this, "designViewModelUtils"); v(this, "designViewModelField"); v(this, "controlCreatorUtils"); v(this, "designerHostService"); v(this, "designerContext"); v(this, "modalService", null); /** 表单规则 */ v(this, "formRule", null); v(this, "schemaService", null); v(this, "metadataService", null); v(this, "propertyConfig", { type: "object", categories: {} }); v(this, "expressionProperty"); var i; this.componentId = t, this.designerHostService = e, this.eventsEditorUtils = e.eventsEditorUtils, this.formSchemaUtils = e.formSchemaUtils, this.formMetadataConverter = e.formMetadataConverter, this.viewModelId = ((i = this.formSchemaUtils) == null ? void 0 : i.getViewModelIdByComponentId(t)) || "", this.designViewModelUtils = e.designViewModelUtils, this.controlCreatorUtils = e.controlCreatorUtils, this.metadataService = e.metadataService, this.schemaService = e.schemaService, this.designerContext = e.designerContext, this.modalService = e.modalService, this.expressionProperty = new Vt(this.formSchemaUtils); } /** * 是否在响应式表单中 */ inResponsiveForm() { var t; return !!((t = this.designerContext) != null && t.responsiveForm); } getFormDesignerInstance() { var t, e; return (e = (t = this.designerContext) == null ? void 0 : t.instances) == null ? void 0 : e.formDesigner.value; } getTableInfo() { var t; return (t = this.schemaService) == null ? void 0 : t.getTableInfoByViewModelId(this.viewModelId); } setDesignViewModelField(t) { var i; const e = t.binding && t.binding.type === "Form" && t.binding.field; if (e) { if (!this.designViewModelField) { const o = this.designViewModelUtils.getDgViewModel(this.viewModelId); this.designViewModelField = o.fields.find((r) => r.id === e); } t.updateOn = (i = this.designViewModelField) == null ? void 0 : i.updateOn; } } getBasicPropConfig(t) { return { description: "Basic Information", title: "基本信息", properties: { id: { description: "组件标识", title: "标识", type: "string", readonly: !0 }, type: { description: "组件类型", title: "控件类型", type: "select", editor: { type: "combo-list", textField: "name", valueField: "value", idField: "value", editable: !1, data: [{ value: t.type, name: g[t.type] && g[t.type].name }] } } } }; } getAppearanceConfig(t = null, e = {}, i) { const o = { title: "外观", description: "Appearance" }, r = { class: { title: "class样式", type: "string", description: "组件的CSS样式", $converter: "/converter/appearance.converter", parentPropertyID: "appearance" }, style: { title: "style样式", type: "string", description: "组件的样式", $converter: "/converter/appearance.converter", parentPropertyID: "appearance" } }; for (const s in e) r[s] = Object.assign(r[s] || {}, e[s]); return { ...o, properties: { ...r }, setPropertyRelates(s, p) { if (s) { switch (s && s.propertyID) { case "class": case "style": { z.value++; break; } } i && i(s, t, p); } } }; } /** * * @param propertyData * @param propertyTypes * @param propertyName * @param constInfos * @param variableInfos * @param expressionType 指定表达式类型,存在属性和表达式类型不一致的情况 * @returns */ getPropertyEditorParams(t, e = [], i = "visible", o = {}, r = {}, s = "") { const { getVariables: p, getControlName: m, getStateMachines: c } = Pt(this.designerHostService), f = this.getRealTargetType(t), l = e && e.length > 0 ? e : ["Const", "Variable", "StateMachine", "Expression"], a = { type: "property-editor", propertyTypes: l }; return l.map((h) => { switch (h) { case "Const": Object.assign(a, { constType: "enum", constEnums: [{ id: !0, name: "是" }, { id: !1, name: "否" }] }, o); break; case "Expression": a.expressionConfig = this.getExpressionOptions(t, f, s || i); break; case "StateMachine": a.stateMachines = c(); break; case "Variable": Object.assign(a, { controlName: m(t), newVariablePrefix: "is", newVariableType: "Boolean", variables: p(this.viewModelId), parentComponentId: this.componentId === "root-component" ? "" : "root-component", onBeforeOpenVariables: (u) => { u.value = p(this.viewModelId); } }, r), this.designerContext.designerMode === "PC_RTC" && (a.newVariablePrefix = "ext_" + a.newVariablePrefix); break; } }), a; } getVisibleProperty(t, e = "") { var r; let i = ["Const", "Variable", "StateMachine", "Expression"]; return e === "gridFieldEditor" ? i = ["Const", "Expression"] : e === "form-group" && !((r = t.binding) != null && r.field) ? i = ["Const", "Variable", "StateMachine", "Custom"] : e === "dataGrid" || e === "treeGrid" || e === "wizard" ? i = ["Const", "Variable", "Expression"] : (t.type.indexOf("toolbar-item") > -1 || e === "form-group") && (i = ["Const", "Variable", "StateMachine", "Custom", "Expression"]), { visible: { title: "是否可见", type: "boolean", description: "运行时组件是否可见", editor: this.getPropertyEditorParams(t, i, "visible") } }; } /** * 获取行为 * @param propertyData * @param viewModelId * @returns */ getBehaviorConfig(t, e = "", i = {}, o) { const r = { title: "行为", description: "" }, s = this.getVisibleProperty(t, e); for (const m in i) s[m] = Object.assign(s[m] || {}, i[m]); const p = this; return { ...r, properties: { ...s }, setPropertyRelates(m, c) { if (m) { switch (m.propertyID) { case "disabled": case "readonly": case "visible": p.afterMutilEditorChanged(t, m); break; } o && o(m, c); } } }; } /** * 当多值编辑器变更时 * @param propertyData * @param changeObject */ afterMutilEditorChanged(t, e) { this.addNewVariableToViewModel(e, this.viewModelId), this.updateExpressionValue(e, t), this.clearExpression(e, t); } /** * * @param propertyId * @param componentInstance * @returns */ updateElementByParentContainer(t, e) { const i = e && e.parent && e.parent.schema; if (!i) return; const o = i.contents.findIndex((s) => s.id === t), r = J(i.contents[o]); i.contents.splice(o, 1), i.contents.splice(o, 0, r), Ge(); } /** * 属性编辑器,在编辑过程中会新增变量,此处需要将新增的变量追加到ViewModel中 * @param changeObject * @param viewModelId * @returns */ addNewVariableToViewModel(t, e) { const i = t.propertyValue; if (!(i && typeof i == "object") || !(i.type === "Variable" && i.isNewVariable)) return; const s = { id: i.field, category: "locale", code: i.fullPath, name: i.fullPath, type: i.newVariableType || "String", isRtcVariable: this.designerContext.designerMode === "PC_RTC" ? !0 : void 0 }; delete i.newVariableType, delete i.isNewVariable, this.formSchemaUtils.getVariableByCode(s.code) || this.formSchemaUtils.getViewModelById("root-viewmodel").states.push(s); } getExpressions() { let t = []; return this.formRule ? (this.formRule.expressions = this.formRule.expressions || [], t = this.formRule.expressions || []) : t = this.formSchemaUtils.getExpressions(), t; } /** * 更新表达式到expressions节点 * @param changeObject */ updateExpressionValue(t, e) { const i = t.propertyValue; if (!((i && i.type) === "Expression" && i.expressionInfo)) return; const { expressionId: s, expressionInfo: p } = i, { targetId: m, targetType: c, expressionType: f, value: l, message: a } = p, h = this.getExpressions(); let u = h.find((b) => b.target === m); u || (u = { target: m, rules: [], targetType: c }, h.push(u)); const d = u.rules.find((b) => b.type === f); if (d) d.id = s, d.value = l, d.message = a, (f === "minDate" || f === "maxDate" || f === "defaultTime") && (d.elementId = e.id); else { const b = { id: s, type: f, value: l, message: a, elementId: e.id }; u.rules.push(b); } delete i.expressionInfo; } /** * 属性类型切换为非表达式后,清除原表达式 * @param changeObject * @param propertyData * @returns */ clearExpression(t, e) { const i = t.propertyValue; if (i && i.type === "Expression") return; const r = t.propertyID, s = this.getExpressions(), p = e.binding ? e.binding.field : e.id, m = s.find((c) => c.target === p); !m || !m.rules || (m.rules = m.rules.filter((c) => c.type !== r)); } getExpressionOptions(t, e, i) { return this.expressionProperty.getExpressionOptions(t, e, i); } getRealTargetType(t) { return ["response-toolbar-item", "tab-toolbar-item", "section-toolbar-item", "drawer-toolbar-item"].indexOf(t.type) > -1 ? "Button" : t.binding && t.binding.field ? "Field" : "Container"; } createBaseEventProperty(t) { const e = {}; return e[this.viewModelId] = { type: "events-editor", editor: { initialData: t, viewSourceHandle: (i) => { var o; ((o = i.controller) == null ? void 0 : o.label.indexOf(this.formSchemaUtils.getModule().code)) >