@farris/ui-vue
Version:
Farris Vue, a Farris Design based Vue3 component library.
1,478 lines • 132 kB
JavaScript
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)) >