UNPKG

@farris/ui-vue

Version:

Farris Vue, a Farris Design based Vue3 component library.

748 lines (747 loc) 25.1 kB
var ae = Object.defineProperty; var se = (e, t, i) => t in e ? ae(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i; var U = (e, t, i) => se(e, typeof t != "symbol" ? t + "" : t, i); import { defineComponent as A, ref as b, computed as P, watch as re, createVNode as d, Fragment as Z, reactive as de, createApp as ce, onUnmounted as ue, onMounted as ne, Transition as fe, mergeProps as me, onBeforeMount as pe, createTextVNode as G } from "vue"; import ye from "../button-edit/index.esm.js"; import ge from "../tree-grid/index.esm.js"; import he from "../radio-group/index.esm.js"; import { FormSchemaEntityField$Type as oe } from "../common/index.esm.js"; import { createPropsResolver as be } from "../dynamic-resolver/index.esm.js"; import { FormBindingType as L, SchemaDOMMapping as ve } from "../property-panel/index.esm.js"; import { merge as D } from "lodash-es"; import { FNotifyService as Fe } from "../notify/index.esm.js"; const Se = "https://json-schema.org/draft/2020-12/schema", Te = "https://farris-design.gitee.io/binding-selector.schema.json", we = "binding-selector", Ce = "字段绑定选择器", Ne = "object", Pe = { disabled: { description: "", type: "boolean", default: !1 }, readonly: { description: "", type: "boolean", default: !1 }, bindingType: { description: "", type: "object", default: {} }, idField: { description: "", type: "string", default: "id" }, title: { description: "", type: "string", default: "字段选择器" }, modalWidth: { description: "", type: "number", default: 800 }, modalHeight: { description: "", type: "number", default: 600 }, separator: { description: "", type: "string", default: "," }, bindingData: { description: "", type: "array", default: [] }, textField: { description: "", type: "string", default: "code" }, editorParams: { description: "", type: "object", default: {} } }, Ve = { $schema: Se, $id: Te, title: we, description: Ce, type: Ne, properties: Pe }, ee = [ { field: "name", title: "名称" }, { field: "bindingField", title: "绑定字段" }, { field: "fieldType", title: "字段类型" } ], te = [ { field: "name", title: "名称" }, { field: "code", title: "编号" }, { field: "displayTypeName", title: "变量类型" } ], xe = [ { value: "Form", text: "绑定字段" }, { value: "LocaleVariable", text: "绑定组件变量" }, { value: "RemoteVariable", text: "绑定表单变量" } ], Y = { disabled: { type: Boolean, default: !1 }, readonly: { type: Boolean, default: !1 }, modelValue: { type: Object, default: null }, bindingType: { type: Object, default: { enable: !0, value: "Form", textField: "text", valueField: "value" } }, data: { type: Array, default: [] }, idField: { type: String, default: "id" }, title: { type: String, default: "字段选择器" }, modalWidth: { type: Number, default: 800 }, modalHeight: { type: Number, default: 600 }, multiSelect: { type: Boolean, default: !1 }, /** * 可选,分隔符 * 默认`,` */ separator: { type: String, default: "," }, bindingData: { type: Array, default: [] }, textField: { type: String, default: "code" }, beforeOpenDialog: { type: Function, default: null }, editorParams: { type: Object, default: null }, onFieldSelected: { type: Function, default: null }, /** 是否显示自定义的底部按钮区域 */ showCustomFooter: { type: Boolean, default: !1 } }, Be = be(Y, Ve), Ie = { showCloseButton: { type: Boolean, default: !0 }, position: { type: String, default: "top-center" }, timeout: { type: Number, default: 3e3 }, theme: { type: String, default: "bootstrap" }, left: { type: Number }, right: { type: Number }, top: { type: Number }, bottom: { type: Number }, id: { type: String }, animate: { type: String, default: "fadeIn" }, options: { type: Object }, safeHtml: { type: Boolean, default: !0 } }, Oe = { showCloseButton: { type: Boolean, default: !0 }, animate: { type: String, default: "fadeIn" }, options: { type: Object } }, W = /* @__PURE__ */ A({ name: "Toast", props: Oe, emits: ["close", "click"], setup: (e, t) => { const i = b(e.animate), a = "fadeOut", o = P(() => e.options), c = b(!1), u = P(() => { const y = { animated: c.value, toast: !0 }; return y[e.animate] = !1, y[a] = c.value, y[o.value.type] = !0, o.value.theme && (y[o.value.theme] = !0), y; }), m = P(() => { const B = `f-icon-${o.value && o.value.type ? o.value.type.replace("toasty-type-", "") : "default"}`, T = { "f-icon": !0 }; return T[B] = !0, T; }), g = P(() => o.value.title || o.value.message), v = P(() => o.value.title && o.value.message), w = P(() => !o.value.title && o.value.message), C = P(() => e.showCloseButton), h = P(() => !!o.value.buttons || !!t.slots.default); function x(y) { y.stopPropagation(), y.preventDefault(), c.value = !1, setTimeout(() => { t.emit("close", o.value); }, 200); } function N(y, V) { } function $(y) { return `f-preten-link ${y.customClass ? y.customClass : ""}`; } re(i, () => { i.value; }); const R = () => { var y; return d(Z, null, [d("div", { class: "after-toast-msg text-right" }, [!t.slots.default && ((y = o.value.buttons) == null ? void 0 : y.map((V) => d("span", { class: $(V), onClick: (B) => void 0 }, [V.text]))), t.slots.default && t.slots.default()])]); }; return () => d("div", { class: u.value, style: "min-height:44px" }, [C.value && d("button", { title: "关闭", class: "toast-close f-btn-icon f-bare", onClick: x }, [d("span", { class: "f-icon modal_close" }, null)]), g.value && d("section", { class: "modal-tips" }, [d("div", { class: "float-left modal-tips-iconwrap" }, [d("span", { class: m.value }, null)]), d("div", { class: "modal-tips-content" }, [v.value && d(Z, null, [d("h5", { class: "toast-title modal-tips-title", innerHTML: o.value.title }, null), d("p", { class: "toast-msg", innerHTML: o.value.message }, null), h.value && R()]), w.value && (o.value.buttons ? d("div", { class: "toast-title-btns-wrapper d-flex" }, [d("h5", { class: "toast-title modal-tips-title only-toast-msg", innerHTML: o.value.message }, null), d("div", { class: "after-toast-title text-right ml-auto" }, [R()])]) : d("h5", { class: "toast-title modal-tips-title only-toast-msg", innerHTML: o.value.message }, null))])])]); } }), _ = /* @__PURE__ */ A({ name: "Notify", props: Ie, emits: ["close", "empty"], setup(e, t) { const i = P(() => ({ "farris-notify": !0 })), a = { left: 12, right: 12, top: 20, bottom: 12 }, o = b(), c = b(e.options), u = b(e.showCloseButton), m = P(() => e.position || "bottom-right"), g = P(() => e.timeout != null ? e.timeout : 3e3), v = P(() => { const h = e.bottom ? e.bottom : a.bottom, x = e.top ? e.top : a.top, N = { transition: "all 0.2s ease", left: m.value.indexOf("left") > -1 ? `${e.left ? e.left : a.left}px` : "", right: m.value.indexOf("right") > -1 ? `${e.right ? e.right : a.right}px` : "", top: m.value.indexOf("top") > -1 ? `${x}px` : "", bottom: m.value.indexOf("bottom") > -1 ? `${h}px` : "" }; return m.value.indexOf("center") > -1 && (N.left = "50%", N.marginLeft = "calc(-24rem / 2)", m.value === "center-center" && (N.top = "50%", N.transform = "translate(-50%, -50%)")), N; }); function w(h) { t.emit("close"); } g.value && setTimeout(() => { w(); }, g.value), t.expose({ closeToast: w, container: o, notifyPosition: m }); function C(h, x) { w(); } return () => d("div", { class: i.value, style: v.value, ref: o }, [d(W, { options: c.value, showCloseButton: u.value, animate: e.animate, onClose: (h) => C(h, c.value) }, null)]); } }); class ie { constructor() { U(this, "notifyRefs", []); U(this, "globalConfig", de({})); } escapeAllHtml(t) { if (typeof t != "string" || !t) return ""; const i = document.createElement("div"); return i.textContent = t || "", i.innerHTML.replace(/ /g, "&nbsp;").replace(/\\n/g, "<br>").replace(/\\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;").replace(/\\r/g, ""); } createNotifyInstance(t) { const i = this, o = Object.assign({ timeout: 3e3, position: "bottom-right", showCloseButton: !0, safeHtml: !0 }, this.globalConfig, { ...t }), c = document.createElement("div"); c.style.display = "contents"; const u = ce({ setup() { var v; const m = b(); function g() { m.value.container.style.transform = "scale(0)", setTimeout(() => { i.updateNotifyPositionForClose(o, m), u.unmount(); }, 220); } if (o.position.indexOf("top") > -1) { const w = i.getNotifyInstances(o.position), C = w[w.length - 1]; if (C) { const h = C.value.container.getBoundingClientRect(); o.top = h.bottom; } } return o.safeHtml && ((v = o.options) != null && v.message) && (o.options.message = i.escapeAllHtml(o.options.message)), ue(() => { document.body.removeChild(c); }), ne(() => { i.updateNotifyPositionForCreate(o, m); }), () => d(fe, { mode: "out-in", name: "fade", appear: !0 }, { default: () => [d(_, me({ ref: m }, o, { onClose: g }), null)] }); } }); return u.provide("NotifyService", this), document.body.appendChild(c), u.mount(c), u; } getNotifyInstances(t) { return this.notifyRefs.filter((i) => i.value.notifyPosition === t); } updateNotifyPositionForCreate(t, i) { if (this.notifyRefs && this.notifyRefs.length) { const a = window.innerHeight; t.position.indexOf("bottom") > -1 && this.getNotifyInstances(t.position).forEach((o) => { const c = o.value.container.getBoundingClientRect(); o.value.container.style.bottom = c.height + a - c.bottom + "px"; }); } this.notifyRefs = [...this.notifyRefs, i]; } updateNotifyPositionForClose(t, i) { const a = this.notifyRefs.indexOf(i); if (t.position.indexOf("top") > -1) { const o = this.getNotifyInstances(t.position), c = o.indexOf(i); o.slice(c + 1).forEach((u) => { u.value.container.style.top = u.value.container.offsetTop - u.value.container.offsetHeight + "px"; }); } a > -1 && this.notifyRefs.splice(a, 1); } show(t) { return this.createNotifyInstance(t); } buildNotifyProps(t, i) { let a = "", o = "", c, u, m; typeof i == "string" ? a = i : i && (a = i.message || "", o = i.title || "", u = i.position || null, m = i.showCloseButton != null ? i.showCloseButton : null, c = i.timeout != null ? i.timeout : null); const v = { options: { type: t, message: a, title: o } }; return u != null && (v.position = u), m != null && (v.showCloseButton = m), c != null && (v.timeout = c), v; } info(t) { const i = this.buildNotifyProps("info", t); return this.show(i); } success(t) { const i = this.buildNotifyProps("success", t); return this.show(i); } warning(t) { const i = this.buildNotifyProps("warning", t); return this.show(i); } error(t) { const i = this.buildNotifyProps("error", t); return this.show(i); } close(t) { t && t.unmount(); } closeAll() { this.notifyRefs.forEach((t) => { t == null || t.value.closeToast(); }), this.notifyRefs.length = 0; } } const Me = Symbol("NOTIFY_SERVICE_TOKEN"); _.install = (e) => { e.component(_.name, _), e.component(W.name, W); const t = new ie(); e.provide(Me, t), e.provide("FNotifyService", t); }; function le(e) { const { designViewModelUtils: t, schemaService: i, formSchemaUtils: a } = e.editorParams.designerHostService, { viewModelId: o } = e.editorParams; let c = [], u = [], m = []; const g = new ie(); g.globalConfig = { position: "top-center" }; function v(l) { switch (l) { case "LocaleVariable": return u; case "RemoteVariable": return m; default: return c; } } function w() { c = t.getAllFields2TreeByVMId(o); } function C() { const l = a.getViewModelById(o); if (l.parent) { const n = a.getLocaleVariablesByViewModelId(l.parent); n && n.length && (n[0].data.name = "根组件", u = u.concat(n)); } const s = a.getLocaleVariablesByViewModelId(o); u = u.concat(s); } function h() { m = a.getRemoteVariables(); } function x(l) { var f, p, F; const s = D({}, l.rawData, { groupId: null, groupName: null }), n = (f = e.editorParams.componentSchema) == null ? void 0 : f.binding, r = t.getDgViewModel(o); if (n != null && n.field) { const S = r.fields.find((E) => E.id === n.field); if (r.removeField([n.field]), S) { const { groupId: E, groupName: I, editor: O } = S; D(s, { editor: O, groupId: E, groupName: I }); } } r.addField(s), (F = (p = e.editorParams.componentSchema) == null ? void 0 : p.editor) != null && F.type && r.changeField(s.id, { editor: e.editorParams.componentSchema.editor.type }); } function N(l) { var f; const s = (f = e.editorParams.componentSchema) == null ? void 0 : f.binding, n = t.getDgViewModel(o), r = { type: "Variable", id: l.id, fieldName: l.code, groupId: "", groupName: "" }; if (s != null && s.field) { const p = a.getViewModelById(o), F = p == null ? void 0 : p.fields.find((S) => S.id === (s == null ? void 0 : s.field)); F && (r.groupName = F.groupName, r.groupId = F.groupId), n.removeField([s == null ? void 0 : s.field]); } a.addViewModelField(o, r); } function $(l, s) { if (!e.editorParams.needSyncToViewModel || !e.editorParams.viewModelId || !e.editorParams.designerHostService) return; const n = e.editorParams.componentSchema.binding; n && n.field === l.id || (s === "Form" ? x(l) : N(l)); } function R(l) { if (!e.editorParams.needSyncToViewModel || !e.editorParams.viewModelId || !e.editorParams.designerHostService) return; const s = e.editorParams.componentSchema.binding; if (!(s && s.field === l.id) && a.expressions && a.expressions.length) { const { propertyData: n } = e.editorParams, r = a.expressions.findIndex((f) => f.target === s.field); r > -1 && (a.expressions.splice(r, 1), g.warning("切换绑定后,请重新配置表达式"), Object.keys(n).forEach((f) => { n[f] && n[f].type === "Expression" && (n[f].expressionId = ""); })); } } function y(l, s) { if (e.editorParams.componentSchema) { switch (e.editorParams.componentSchema.binding || (e.editorParams.componentSchema.binding = {}), s) { case "Form": { e.editorParams.componentSchema.binding.path = l.bindingField, e.editorParams.componentSchema.binding.field = l.id, e.editorParams.componentSchema.binding.fullPath = l.path; break; } case "LocaleVariable": { e.editorParams.componentSchema.binding.path = l.viewModelId === o ? l.code : "root-component." + l.code, e.editorParams.componentSchema.binding.field = l.id, e.editorParams.componentSchema.binding.fullPath = l.code; break; } case "RemoteVariable": { e.editorParams.componentSchema.binding.path = "root-component." + l.code, e.editorParams.componentSchema.binding.field = l.id, e.editorParams.componentSchema.binding.fullPath = l.code; break; } } return e.editorParams.componentSchema.binding.type = s, e.editorParams.componentSchema.path = l.bindingPath, e.editorParams.componentSchema.binding; } } function V(l) { const s = l == null ? void 0 : l.field, n = /* @__PURE__ */ new Set(), r = a.getFormSchema().module, f = a.getViewModelById(o); let F = r.components.find((S) => S.viewModel === o).componentType; return (F === "frame" || F === "table") && (F = "form"), r.viewmodels.forEach((S) => { if (!S.fields || S.fields.length === 0) return; const E = r.components.find((O) => O.viewModel === S.id); let { componentType: I } = E; (I === "frame" || I === "table") && (I = "form"), !(I !== F || S.bindTo !== f.bindTo) && S.fields.forEach((O) => { O.id !== s && n.add(O.id); }); }), n; } function B(l) { if (!l) return []; const s = {}, { fieldControlTypeMapping: n } = ve; for (const r in n) { const f = n[r]; !f || !f.length || f.forEach((p) => { s[p.key] = s[p.key] || [], s[p.key].push(r); }); } return s[l]; } function T() { w(), C(), h(); } function k(l, s) { if (l.multiLanguage) return { fieldType: "multiLanguage", fieldTypeName: "多语言" }; const n = s === L.Form ? l.type.name : l.type, r = s === L.Form ? l.type.displayName : l.displayTypeName; return { fieldType: n, fieldTypeName: r }; } function j(l, s) { var q, J, Q, X; if (!(l != null && l.length)) return g.warning({ message: "请先选择数据" }), !1; let n = !0; const r = (q = e.editorParams) == null ? void 0 : q.componentSchema, f = r == null ? void 0 : r.binding; if (!f) return !0; let p, F = !1; if (f.type === L.Form) { const M = i.getFieldByID(f.field); M && (p = k(M, L.Form).fieldType, M.$type === oe.ComplexField && (F = !0)); } else { const M = a.getVariableById(f.field); M && (p = M.type); } const S = l[0], { fieldType: E, fieldTypeName: I } = k(S, s), O = "不可以切换成", z = "类型字段,请重新选择!"; if (F || !p) { const M = B((X = (Q = (J = e.editorParams) == null ? void 0 : J.componentSchema) == null ? void 0 : Q.editor) == null ? void 0 : X.type); return M && !M.includes(E) && (g.warning(`${O}${I}${z}`), n = !1), n; } return p && p !== E ? e.editorParams.canChangeFieldType ? !0 : (g.warning(`${O}${I}${z}`), !1) : n; } return { initTreeData: T, getTreeDataSource: v, updateViewModel: $, updateComponentSchema: y, resolveOccupiedFields: V, resolveFieldTypesByEditorType: B, checkFieldValiation: j, clearExpresssionConfig: R }; } const K = /* @__PURE__ */ A({ name: "FBindingSelectorContainer", props: Y, emits: ["selected", "bindingTypeChange", "cancel", "submit"], setup(e, t) { var j, l, s; const i = b(e.data), a = b(((j = e.modelValue) == null ? void 0 : j.type) || "Form"), o = b(e.bindingData), c = b(), u = b(), m = b(), { getTreeDataSource: g, initTreeData: v, resolveOccupiedFields: w, resolveFieldTypesByEditorType: C } = le(e), h = b([]); pe(() => { var n, r, f, p, F, S; v(), i.value = g(a.value), (n = e.editorParams) != null && n.disableOccupiedFields && (u.value = w((f = (r = e.editorParams) == null ? void 0 : r.componentSchema) == null ? void 0 : f.binding)), m.value = C((S = (F = (p = e.editorParams) == null ? void 0 : p.componentSchema) == null ? void 0 : F.editor) == null ? void 0 : S.type), h.value = a.value === "Form" ? ee : te; }), ne(() => { var r, f, p; const n = (p = (f = (r = e.editorParams) == null ? void 0 : r.componentSchema) == null ? void 0 : f.binding) == null ? void 0 : p.field; n && c.value.selectItemById(n); }); const x = { "f-utils-fill": !0, "m-2": (l = e.bindingType) == null ? void 0 : l.enable, "mx-2": !((s = e.bindingType) != null && s.enable), border: !0 }; function N(n) { h.value = n === "Form" ? ee : te, c.value.updateColumns(h.value), i.value = g(n), c.value.updateDataSource(i.value), c.value.clearSelection(), o.value = [], t.emit("selected", []), t.emit("bindingTypeChange", n); } function $(n) { o.value = n, t.emit("selected", n); } function R() { return d("div", { class: "px-3" }, [d(he, { name: "bindingType", textField: e.bindingType.textField || "text", valueField: e.bindingType.valueField || "value", data: xe, modelValue: a.value, "onUpdate:modelValue": (n) => a.value = n, onChangeValue: N }, null)]); } const y = { customRowStatus: (n) => { var f; if (n.raw.$type && n.raw.$type !== oe.SimpleField || u.value && u.value.has(n.raw.id)) return n.disabled = !0, n; const r = a.value === "Form" ? (f = n.raw.type) == null ? void 0 : f.name : n.raw.type; return r && m.value && !m.value.includes(r) ? (n.disabled = !0, n) : (n.disabled = !1, n); } }; function V() { return d(ge, { ref: c, fit: !0, data: i.value, idField: e.idField, columns: h.value, rowNumber: { enable: !1 }, columnOption: { fitColumns: !0 }, onSelectionChange: $, "row-option": y }, null); } function B() { t.emit("cancel"); } function T() { if (!o.value || !o.value.length) { const n = new Fe(); return n.globalConfig = { position: "top-center" }, n.warning({ message: "请先选择数据" }), !1; } return !0; } function k() { T() && t.emit("submit", { selectedData: o.value[0], bindingType: a.value }); } return () => d("div", { class: "h-100 d-flex flex-column" }, [e.bindingType.enable && R(), d("div", { class: x, style: "position:relative;border-radius:10px;" }, [G(" "), V()]), e.showCustomFooter ? d("div", { class: "modal-footer" }, [d("button", { type: "button", class: "btn btn-secondary", onClick: B }, [G("取消")]), d("button", { type: "button", class: "btn btn-primary", onClick: k }, [G("确定")])]) : ""]); } }), H = /* @__PURE__ */ A({ name: "FBindingSelector", props: Y, emits: ["selected", "bindingTypeChanged"], setup(e, t) { var V, B; const i = '<i class="f-icon f-icon-lookup"></i>', a = b(e.bindingData), o = b(e.data), c = b(), u = b(((V = e.modelValue) == null ? void 0 : V.type) || "Form"), m = b((B = e.modelValue) == null ? void 0 : B.path), { updateViewModel: g, updateComponentSchema: v, checkFieldValiation: w, clearExpresssionConfig: C } = le(e); function h(T) { a.value = T; } function x(T) { u.value = T; } function N(T) { m.value = T.path; } function $() { return d(K, { ref: c, data: o.value, onSelected: h, modelValue: e.modelValue, idField: e.idField, bindingData: a.value, onBindingTypeChange: x, editorParams: e.editorParams, bindingType: e.bindingType, showCustomFooter: !1 }, null); } function R() { return !!w(a.value, u.value); } const y = { title: e.title, fitContent: !1, height: e.modalHeight, width: e.modalWidth, buttons: [{ name: "cancel", text: "取消", class: "btn btn-secondary", handle: (T) => (a.value = [], !0) }, { name: "accept", text: "确定", class: "btn btn-primary", handle: (T) => { if (!R()) return !1; g(a.value[0], u.value); const k = v(a.value[0], u.value); return N(k), C(a.value[0]), e.onFieldSelected && typeof e.onFieldSelected == "function" && e.onFieldSelected(k, void 0, a.value[0]), !0; } }], resizeable: !1, draggable: !0 }; return () => d(ye, { modelValue: m.value, "onUpdate:modelValue": (T) => m.value = T, editable: !1, disabled: e.disabled, readonly: e.readonly, inputType: "text", enableClear: !1, buttonContent: i, buttonBehavior: "Modal", modalOptions: y }, { default: () => [d("div", { class: "h-100 d-flex flex-column" }, [$()])] }); } }); H.install = (e) => { e.component(H.name, H), e.component(K.name, K); }; H.register = (e, t, i, a) => { e["binding-selector"] = H, t["binding-selector"] = Be; }; export { H as BindingSelector, K as FBindingSelectorContainer, Y as bindingSelectorProps, xe as bindingTypes, H as default, ee as fieldColumns, Be as propsResolver, te as variableColumns };