UNPKG

@velis/dynamicforms

Version:

Data entry boilerplate components and a RESTful API consumer

1,488 lines 137 kB
var sn = Object.defineProperty, on = Object.defineProperties; var an = Object.getOwnPropertyDescriptors; var wt = Object.getOwnPropertySymbols; var ln = Object.prototype.hasOwnProperty, un = Object.prototype.propertyIsEnumerable; var ze = (n, e, t) => e in n ? sn(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, O = (n, e) => { for (var t in e || (e = {})) ln.call(e, t) && ze(n, t, e[t]); if (wt) for (var t of wt(e)) un.call(e, t) && ze(n, t, e[t]); return n; }, ye = (n, e) => on(n, an(e)); var a = (n, e, t) => ze(n, typeof e != "symbol" ? e + "" : e, t); var w = (n, e, t) => new Promise((r, s) => { var i = (d) => { try { l(t.next(d)); } catch (u) { s(u); } }, o = (d) => { try { l(t.throw(d)); } catch (u) { s(u); } }, l = (d) => d.done ? r(d.value) : Promise.resolve(d.value).then(i, o); l((t = t.apply(n, e)).next()); }); import { DfDateTime as cn, DfCheckbox as dn, DfRtfEditor as mn, DfColor as fn, DfFile as hn, DfInput as pn, DfSelect as gn, DfTextArea as yn, DynamicFormsInputs as wn, VuetifyComponents as bn } from "@dynamicforms/vuetify-inputs"; import vn, { notify as At } from "@kyvg/vue3-notification"; import { isString as we, isObjectLike as _n, isBoolean as Cn, upperFirst as Sn, camelCase as Dn, toLower as Ye, cloneDeep as Ue, findIndex as Ke, find as kn, size as On, includes as rt, map as $n, keys as Ln, filter as bt, clone as Rn, mapValues as Tn, debounce as Nn, sum as An } from "lodash-es"; import { inject as Y, provide as re, defineComponent as $, resolveComponent as K, createBlock as _, openBlock as h, withCtx as L, createElementVNode as T, normalizeClass as oe, createElementBlock as C, createCommentVNode as A, createVNode as N, renderSlot as me, reactive as le, h as Ce, ref as E, onMounted as Ee, onUnmounted as st, computed as g, mergeDefaults as it, unref as p, mergeProps as J, isRef as Q, watch as he, resolveDynamicComponent as fe, nextTick as je, onBeforeMount as En, normalizeProps as Et, guardReactiveProps as It, createTextVNode as be, toDisplayString as M, Fragment as W, renderList as ae, onUpdated as ot, withModifiers as De, normalizeStyle as ve, getCurrentInstance as Pt, toRef as In, onBeforeUpdate as Pn, toRefs as Vn, shallowRef as Hn } from "vue"; import { VIcon as Fn } from "vuetify/components/VIcon"; import xn, { Field as Un, ValidationErrorRenderContent as vt } from "@dynamicforms/vue-forms"; import jn, { AxiosError as Bn } from "axios"; import { VInput as at } from "vuetify/components/VInput"; import { VAlert as Vt } from "vuetify/components/VAlert"; import { VCol as lt, VRow as Ht, VContainer as Mn, VSpacer as qn } from "vuetify/components/VGrid"; import { format as Gn, parseISO as Wn } from "date-fns"; import { CachedIcon as zn } from "vue-cached-icon"; import { VBtn as Ft } from "vuetify/components/VBtn"; import { VCard as Ie, VCardTitle as Pe, VCardText as Ve, VCardActions as ut } from "vuetify/components/VCard"; import { VSwitch as Kn } from "vuetify/components/VSwitch"; import { VExpandTransition as xt } from "vuetify/components/transitions"; import { VForm as Qn } from "vuetify/components/VForm"; import { VLayout as Ze } from "vuetify/components/VLayout"; import { VDialog as Ut } from "vuetify/components/VDialog"; import Xn from "resize-observer-polyfill"; import { VCheckbox as Yn } from "vuetify/components/VCheckbox"; import { VColorPicker as Zn } from "vuetify/components/VColorPicker"; import { VFileInput as Jn } from "vuetify/components/VFileInput"; import { VList as er, VListItem as tr, VListItemTitle as nr } from "vuetify/components/VList"; import { VMain as rr } from "vuetify/components/VMain"; import { VMenu as sr } from "vuetify/components/VMenu"; import { VProgressLinear as ir } from "vuetify/components/VProgressLinear"; import { VProgressCircular as or } from "vuetify/components/VProgressCircular"; import { VTextarea as ar } from "vuetify/components/VTextarea"; import { VTextField as lr } from "vuetify/components/VTextField"; import { useRoute as ur } from "vue-router"; const j = (n) => window.gettext ? window.gettext(n) : n, pe = (n, e) => window.interpolate ? window.interpolate(n, e, !0) : n.replace(/%\(\w+\)s/g, (t) => String(e[t.slice(2, -2)])); function cr() { return { gettext: j, interpolate: pe }; } let dr = 0; const mr = [ "HEADER", "ROW_START", "ROW_END", "FIELD_START", "FIELD_END", "FORM_HEADER", "FORM_FOOTER", "ROW_CLICK", "ROW_RIGHT_CLICK", "VALUE_CHANGED" ]; function Fe(n, e, t) { const r = t == null ? void 0 : t.dialog; return r && r.resolvePromise && r.close && (r.resolvePromise({ action: n, payload: e, extraData: t, dialog: r }), r.close()), !0; } function ke(n) { return `action${Sn(Dn(Ye(n)))}`; } class z { constructor(e, t) { a(this, "name"); a(this, "uniqueId"); a(this, "position"); a(this, "fieldName"); a(this, "label"); a(this, "labelAvailable"); a(this, "icon"); a(this, "iconAvailable"); a(this, "displayStyle"); a(this, "payload"); a(this, "title"); a(this, "extra_data"); const r = ++dr, s = e.name, i = e.position; (!we(s) || !/^[a-zA-Z-_]+$/.test(s)) && console.warn( `Action name must be a valid string, matching [a-zA-Z-_]+. Got ${s}. Impossible to construct handler function name`, e ); const o = !we(e.label) || e.label.length === 0 ? null : e.label, l = !we(e.icon) || e.icon.length === 0 ? null : e.icon, d = ["asButton", "showLabel", "showIcon"]; function u(v) { if (v == null || !_n(v)) return null; const D = d.reduce((k, R) => (Cn(v[R]) && (k[R] = v[R]), k), {}); return Object.keys(D).length === 0 ? null : D; } function c(v, D) { if (e.displayStyle == null) return; const k = u(e.displayStyle[D]); k && (v[D] = k); } const m = u(e.displayStyle) || {}; c(m, "xl"), c(m, "lg"), c(m, "md"), c(m, "sm"), c(m, "xs"), mr.indexOf(i) === -1 && console.warn(`Action position ${i} not known`, e); const y = e instanceof z ? e.fieldName : e.field_name, b = !we(y) || y.length === 0 ? null : y, S = !we(e.title) || e.title.length === 0 ? null : e.title, f = ke(e.name); this[f] = e[f], Object.defineProperties(this, { name: { get() { return s; }, enumerable: !0 }, uniqueId: { get() { return r; }, enumerable: !1 }, position: { get() { return i; }, enumerable: !0 }, fieldName: { get() { return b; }, enumerable: !0 }, label: { get() { return o; }, enumerable: !0 }, labelAvailable: { get() { return o != null; }, enumerable: !0 }, icon: { get() { return l; }, enumerable: !0 }, iconAvailable: { get() { return l != null; }, enumerable: !0 }, displayStyle: { get() { return m; }, enumerable: !0 }, title: { get() { return S; }, enumerable: !0 }, extra_data: { get() { var v; return (v = e.extra_data) != null ? v : {}; }, enumerable: !0 }, payload: { get() { return t; }, enumerable: !0 } // elementType & bindAttrs, entire action.action concept: // action.py && actionsHandler.decorateActions, added by brontes, modified by velis // not sure this is necessary: I have only found one instance of action declaration in python and // it's just so a dialog can be shown. Doubt it even worked at any time. Also that same thing is now // solved via parent components declaring action handler methods }); } static closeAction(e = {}) { return new z(O({ name: "close", label: j("Close"), icon: "ion-close-outline", displayStyle: { asButton: !0, showLabel: !0, showIcon: !0 }, position: "FORM_FOOTER" }, e)); } static yesAction(e = {}) { return new z(O({ name: "yes", label: j("Yes"), icon: "ion-thumbs-up-outline", displayStyle: { asButton: !0, showLabel: !0, showIcon: !0 }, position: "FORM_FOOTER" }, e)); } static noAction(e = {}) { return new z(O({ name: "no", label: j("No"), icon: "ion-thumbs-down-outline", displayStyle: { asButton: !0, showLabel: !0, showIcon: !0 }, position: "FORM_FOOTER" }, e)); } } class V { constructor(e, t) { a(this, "actions"); a(this, "filterCache"); a(this, "payload"); this.actions = Object.values(e).reduce((r, s) => { if (s == null) return r; const i = s.name; return i == null ? (console.error("Action has no name and will not be added to the list", s), r) : (s instanceof z && (t === void 0 || s.payload === t) ? r[i] = s : r[i] = new z(s, t), r); }, {}), this.filterCache = {}, Object.defineProperties(this, { payload: { get() { return t; }, enumerable: !0 } }); } get actionsList() { return Object.values(this.actions); } get length() { return this.actionsList.length; } *[Symbol.iterator]() { for (const e of this.actionsList) yield e; } hasAction(e) { return this.actionsList.some((t) => t.uniqueId === e.uniqueId); } /** * filters actions to include only those rendering at given position * @param position * @param fieldName * @returns {FilteredActions} */ filter(e, t = null) { const r = e + (t ? `|${t}` : ""); return this.filterCache[r] === void 0 && (this.filterCache[r] = new V( Object.values(this.actions).filter((s) => s.position === e && (s.fieldName == null || s.fieldName === t)).reduce((s, i) => (s[i.name] = this.actions[i.name], s), {}) )), this.filterCache[r]; } get header() { return this.filter("HEADER"); } get rowStart() { return this.filter("ROW_START"); } get rowEnd() { return this.filter("ROW_END"); } get rowClick() { return this.filter("ROW_CLICK"); } get rowRightClick() { return this.filter("ROW_RIGHT_CLICK"); } fieldAll(e) { const t = this.filter("FIELD_START", e), r = this.filter("FIELD_END", e), s = [...t.actionsList, ...r.actionsList]; return new V(s); } fieldStart(e) { return this.filter("FIELD_START", e); } fieldEnd(e) { return this.filter("FIELD_END", e); } get formHeader() { return this.filter("FORM_HEADER"); } get formFooter() { return this.filter("FORM_FOOTER"); } get valueChanged() { return this.filter("VALUE_CHANGED"); } } class fr { } function ue(n, e = !0) { const t = Y("actionHandler", void 0), r = n != null ? n : Y("payload", {}); class s { constructor() { a(this, "handlers", new fr()); a(this, "register", (u, c) => (this.handlers[u] = c, this)); a(this, "call", (u, c) => w(this, null, function* () { const m = yield this.recursiveCall(u, r.value, c, e), y = yield this.resolveAction(u, c); return m || y; })); a(this, "recursiveCall", (u, c, m, y = !0) => w(this, null, function* () { var b, S; return y ? (yield this.executeHandler(u, c, m)) || ((b = yield t == null ? void 0 : t.recursiveCall(u, c, m, y)) != null ? b : !1) : ((S = yield t == null ? void 0 : t.recursiveCall(u, c, m, y)) != null ? S : !1) || (yield this.executeHandler(u, c, m)); })); a(this, "executeHandler", (u, c, m) => w(this, null, function* () { var b, S, f, v, D, k, R; if (u instanceof V) { for (const F of u) { const X = O(O({}, (b = F.payload) == null ? void 0 : b["$extra-data"]), m); if (yield (f = (S = this.handlers)[F.name]) == null ? void 0 : f.call(S, F, c, X)) return !0; } return !1; } const y = O(O({}, (v = u.payload) == null ? void 0 : v["$extra-data"]), m); return (R = (k = (D = this.handlers)[u.name]) == null ? void 0 : k.call(D, u, c, y)) != null ? R : !1; })); // eslint-disable-next-line class-methods-use-this a(this, "resolveAction", (u, c) => w(this, null, function* () { var y, b, S, f, v; if (u instanceof V) { for (const D of u) { const k = O(O({}, (y = D.payload) == null ? void 0 : y["$extra-data"]), c); if (yield (b = D == null ? void 0 : D[ke(D.name)]) == null ? void 0 : b.call(D, D, D.payload, k)) return !0; } return !1; } const m = O(O({}, (S = u.payload) == null ? void 0 : S["$extra-data"]), c); return (v = (f = u == null ? void 0 : u[ke(u.name)]) == null ? void 0 : f.call(u, u, u.payload, m)) != null ? v : !1; })); } } const i = new s(), o = i.call, l = i.register; return re("actionHandler", i), { registerHandler: l, callHandler: o, handler: i }; } var Oe = /* @__PURE__ */ ((n) => (n[n.SUPPRESS = 1] = "SUPPRESS", n[n.HIDDEN = 5] = "HIDDEN", n[n.INVISIBLE = 8] = "INVISIBLE", n[n.FULL = 10] = "FULL", n))(Oe || {}); const _t = 10; ((n) => { function e(s) { return s.toUpperCase() === "SUPPRESS" ? 1 : s.toUpperCase() === "HIDDEN" ? 5 : s.toUpperCase() === "INVISIBLE" ? 8 : _t; } n.fromString = e; function t(s) { const i = typeof s == "number" ? s : n.fromString(s); return Object.values(n).includes(i) ? i : _t; } n.fromAny = t; function r(s) { const i = typeof s == "number" ? s : n.fromString(s); return Object.values(n).includes(i); } n.isDefined = r; })(Oe || (Oe = {})); Object.freeze(Oe); const x = Oe, hr = ["onClick"], pr = { key: 0, style: { display: "inline-block", float: "right", "vertical-align": "middle" } }, gr = ["onClick"], yr = { style: { display: "inline-block", "max-width": "95%" }, class: "notification-title" }, wr = ["innerHTML"], br = { style: { display: "inline-block", "max-width": "95%" }, class: "notification-content" }, vr = ["innerHTML"], jt = /* @__PURE__ */ $({ __name: "df-notifications", props: { width: { default: 350 }, position: { default: "top center" } }, setup(n) { return (e, t) => { const r = K("notifications"); return h(), _(r, { width: e.width, position: e.position }, { body: L(({ item: s, close: i }) => [ T("div", { class: oe(["vue-notification", s.type]), onClick: (o) => s.data.onNotificationClose(s, i, !0) }, [ T("div", null, [ s.data.duration === -1 ? (h(), C("div", pr, [ T("button", { type: "button", class: "close", onClick: (o) => s.data.onNotificationClose(s, i) }, [ N(Fn, { icon: "mdi-window-close" }) ], 8, gr) ])) : A("", !0), T("div", yr, [ T("div", { innerHTML: s.title }, null, 8, wr) ]), T("div", br, [ T("div", { style: { "margin-left": "0.4em" }, innerHTML: s.text }, null, 8, vr) ]) ]) ], 10, hr) ]), _: 1 }, 8, ["width", "position"]); }; } }), _r = /* @__PURE__ */ $({ __name: "df-app", setup(n) { return (e, t) => { const r = K("ModalView"); return h(), C("div", null, [ N(jt), N(r), me(e.$slots, "default") ]); }; } }); var Be; ((n) => { function e(r) { return r.type === "group"; } n.isGroupTemplate = e; function t(r) { return "rows" in r; } n.isLayoutTemplate = t; })(Be || (Be = {})); var $e = /* @__PURE__ */ ((n) => (n[n.SMALL = 1] = "SMALL", n[n.MEDIUM = 2] = "MEDIUM", n[n.LARGE = 3] = "LARGE", n[n.X_LARGE = 4] = "X_LARGE", n[n.DEFAULT = 0] = "DEFAULT", n))($e || {}); const Ct = 0; ((n) => { const e = ["large", "lg", "modal-lg"], t = ["medium", "md", "modal-md"], r = ["small", "sm", "modal-sm"], s = ["x-large", "xl", "modal-xl"]; function i(l) { return l === void 0 ? Ct : e.includes(l) ? 3 : t.includes(l) ? 2 : r.includes(l) ? 1 : s.includes(l) ? 4 : Ct; } n.fromString = i; function o(l) { const d = typeof l == "number" ? l : n.fromString(l); return Object.values(n).includes(d); } n.isDefined = o; })($e || ($e = {})); Object.freeze($e); const U = $e; class Cr { constructor(e) { a(this, "inputType"); a(this, "fieldCSSClass"); a(this, "pattern"); a(this, "min"); a(this, "max"); a(this, "minLength"); a(this, "maxLength"); a(this, "step"); a(this, "size"); a(this, "formDateFormat"); a(this, "formTimeFormat"); a(this, "multiple"); a(this, "allowTags"); a(this, "formComponentDef"); var t, r; this.inputType = e.input_type, this.fieldCSSClass = e.field_class, this.pattern = e.pattern, this.min = e.min, this.max = e.max, this.minLength = (t = e.min_length) != null ? t : 0, this.maxLength = (r = e.max_length) != null ? r : 1e20, this.step = e.step, this.size = e.size, this.formDateFormat = e.form_date_format, this.formTimeFormat = e.form_time_format, this.multiple = e.multiple, this.allowTags = e.allow_tags, this.formComponentDef = e.form_component_def; } } class ct { constructor(e) { a(this, "uuid"); a(this, "name"); a(this, "label"); a(this, "placeholder"); a(this, "align"); a(this, "visibility"); a(this, "renderParams"); a(this, "readOnly"); a(this, "componentName"); a(this, "helpText"); a(this, "choices"); a(this, "ajax"); a(this, "widthClasses"); a(this, "allowNull"); a(this, "renderKey"); a(this, "conditionalVisibility"); this.renderKey = 0, Object.defineProperties(this, { fieldDef: { get() { return e; }, enumerable: !1 }, uuid: { get() { return e.uuid; }, enumerable: !0 }, name: { get() { return e.name; }, enumerable: !0 }, label: { get() { return e.label; }, enumerable: !0 }, placeholder: { get() { return e.placeholder; }, enumerable: !0 }, align: { get() { return e.alignment === "decimal" ? "right" : e.alignment; }, enumerable: !0 }, visibility: { get() { return x.fromAny(e.visibility.form); }, enumerable: !0 }, renderParams: { get() { return new Cr(e.render_params); }, enumerable: !0 }, readOnly: { get() { return e.read_only === !0; }, enumerable: !0 }, componentName: { get() { return e.render_params.form_component_name; }, enumerable: !0, configurable: !0 }, choices: { get() { return e.choices; }, enumerable: !0 }, ajax: { get() { return e.ajax; }, enumerable: !0 }, colspan: { get() { return e.colspan; }, enumerable: !0, configurable: !0 }, helpText: { get() { return e.help_text; }, enumerable: !0 }, allowNull: { get() { return e.allow_null; }, enumerable: !0 }, conditionalVisibility: { get() { return e.conditional_visibility; }, enumerable: !0 } }); } get isVisible() { return this.visibility !== x.SUPPRESS && this.visibility !== x.HIDDEN; } setVisibility(e) { let t; x.isDefined(e) ? t = x.fromAny(e) : e ? t = x.FULL : t = x.HIDDEN, t !== this.fieldDef.visibility.form && (this.fieldDef.visibility.form = t, this.renderKey++); } } let Bt; class Mt extends ct { constructor(t, r, s) { super(s); a(this, "layoutFieldComponentName"); a(this, "colspan"); let i = 0; Object.defineProperty(this, "layoutFieldComponentName", { get() { return r.component_name || "FormField"; }, enumerable: !0, configurable: !0 }), Object.defineProperty(this, "colspan", { get() { return r.colspan || 1; }, enumerable: !0, configurable: !0 }), Object.defineProperty(this, "renderKey", { get() { return i; }, set(o) { i = o, t.renderKey++; }, enumerable: !0 }); } } class qt extends Mt { constructor(t, r, s) { var e = (...fo) => (super(...fo), a(this, "title"), a(this, "layout"), this); if (s == null) { const i = { uuid: crypto.randomUUID(), name: null, label: "", placeholder: "", alignment: "left", visibility: { form: x.FULL, table: x.SUPPRESS }, render_params: { input_type: "", form_component_name: "df-form-layout" }, read_only: !0, choices: [], colspan: 1, help_text: "", allow_null: !1 }; e(t, r, i); } else e(t, r, s); Object.defineProperty(this, "layoutFieldComponentName", { get() { return r.component_name || "FormFieldGroup"; }, enumerable: !0, configurable: !0 }), Object.defineProperty(this, "title", { get() { return r.title; }, enumerable: !0 }), Object.defineProperty( this, "layout", { get() { return new Bt(r.layout); }, enumerable: !0 } ), Object.defineProperty( this, "componentName", { get() { return "FormFieldGroup"; }, enumerable: !0, configurable: !0 } ); } } function Sr(n, e, t) { switch (e.type) { case "column": return new Mt(n, e, t); case "group": return new qt(n, e, t); default: throw Error(`Unknown layout column type "${e.type}"`); } } class Dr { constructor(e, t, r) { a(this, "renderKey"); a(this, "columns"); a(this, "componentName"); this.columns = e.columns.map((s) => { const i = Sr(this, s, r[s.field]); return t[s.field] = i, i; }), this.renderKey = 0, Object.defineProperty(this, "componentName", { get() { return e.component_name; }, enumerable: !0 }); } get anyVisible() { return this.columns.reduce((e, t) => e || t.isVisible, !1); } } class dt { constructor(e) { a(this, "fields"); a(this, "rows"); a(this, "componentName"); a(this, "fieldName"); a(this, "size"); e === void 0 ? (this.fields = {}, this.rows = [], Object.defineProperty(this, "size", { get() { return U.DEFAULT; }, enumerable: !0 })) : (this.fields = {}, this.rows = e.rows.map((t) => new Dr(t, this.fields, e.fields)), Object.keys(e.fields).forEach((t) => { t in this.fields || (this.fields[t] = new ct(e.fields[t])); }), Object.defineProperty(this, "componentName", { get() { return e.component_name; }, enumerable: !0 }), Object.defineProperty(this, "size", { get() { return U.fromString(e.size); }, enumerable: !0 })); } } Bt = dt; function kr(n) { return n instanceof qt; } function Je(n) { const e = []; return n.fields && e.push(...Object.values(n.fields)), Be.isLayoutTemplate(n) && n.rows.forEach((t) => { var r; (r = t.columns) == null || r.forEach((s) => { Be.isGroupTemplate(s) && s.layout && s.field == null ? e.push(...Je(s.layout)) : kr(s) && s.layout && s.field == null && e.push(...Je(s.layout)); }); }), e; } class Z { constructor(e, t) { a(this, "$extra-data"); this.setData(e, t); } static create(e, t) { return le(new Z(e, t)); } addExtraData(e) { const t = O(O({}, this["$extra-data"]), e); Object.defineProperty(this, "$extra-data", { get() { return t; }, enumerable: !1, configurable: !0 }); } clear() { Object.getOwnPropertyNames(this).forEach((e) => { delete this[e]; }); } setData(e, t) { let r = {}, s = {}; return e == null || (e instanceof Z ? [r, s] = this.copyWithProperties(e) : t != null && t.fields && Je(t).forEach((i) => { if (i.visibility !== x.SUPPRESS) { if (i.readOnly && i.name != null && !i.name.endsWith("-display")) r[i.name] = { get() { return e[i.name]; }, enumerable: !1, configurable: !0 }; else if (i.name != null) { const o = this; o[i.name] = e[i.name], Object.defineProperty(o, `set${i.name}Value`, { get() { return function(d) { o[i.name] = d; }; }, enumerable: !1, configurable: !0 }); } } })), Object.defineProperty(this, "$extra-data", { get() { return s; }, enumerable: !1, configurable: !0 }), Object.defineProperties(this, r), Object.defineProperty(this, "_properties", { get() { return r; }, enumerable: !1, configurable: !0 }), this; } replaceData(e, t) { return this.clear(), this.setData(e, t); } copyWithProperties(e) { return Object.entries(e).forEach(([t, r]) => { this[t] = r; }), [ Ue(e._properties), // eslint-disable-line no-underscore-dangle Ue(e["$extra-data"]) ]; } } let Or = 0; class et { // Function to reject the promise constructor(e, t, r, s, i) { /* Base dialog definition */ a(this, "title"); a(this, "body"); a(this, "options"); a(this, "actions"); a(this, "actionHandlers"); a(this, "dialogId"); // Unique dialog ID a(this, "_topOfTheStack"); // true when this dialog is the first one /* API functions */ a(this, "close"); // API function to close this dialog from calling code /* Support declarations */ a(this, "promise"); // The promise which will be resolved when the dialog closes a(this, "resolvePromise"); // function to resolve the promise a(this, "rejectPromise"); this.title = e, this.body = t, this.options = r, this.actions = s, this.actionHandlers = i, this.dialogId = ++Or, this.close = () => null, this.promise = new Promise(() => { }), this.resolvePromise = () => null, this.rejectPromise = () => null; } get topOfTheStack() { return this._topOfTheStack || !1; } set topOfTheStack(e) { this._topOfTheStack = e; } } function Qe(n, e) { if (e == null) return null; if (typeof e == "string") return () => Ce("span", null, e); if (e instanceof V) return () => Ce(K("DfActions"), { slot: n, actions: e }); if (e && "componentName" in e && "props" in e) { const t = we(e.componentName) ? K(e.componentName) : e.componentName; return () => Ce(t, O({ slot: n }, e.props)); } return e; } const Gt = /* @__PURE__ */ $({ methods: { renderFunction(n, e, t, r, s, i) { return Ce( // Jure 16.3.2023 types don't match here, but the code works. Too green to be able to fix // @ts-ignore K("DfModalDialog"), { show: !0, options: s || {}, key: n, actionHandlers: i }, { title: Qe("title", e), body: Qe("body", t), actions: Qe("actions", r) } ); } } }); class $r { constructor() { a(this, "list"); a(this, "currentRef"); this.list = [], this.currentRef = E(null); } setCurrent() { const e = this.list.length ? this.list[this.list.length - 1] : null; this.currentRef.value !== e && (this.currentRef.value = e); } get current() { return this.currentRef.value; } push(e, t) { const r = Ke(this.list, { dialogId: t }); if (r !== -1) e.dialogId = t, this.list[r] = e, r === this.list.length - 1 && (e.topOfTheStack = !0); else { if (this.list.length && (this.list[this.list.length - 1].topOfTheStack = !1), e.actions instanceof V) { const i = Z.create(e.actions.payload || Z.create()); i.addExtraData({ dialog: e }), e.actions = new V(e.actions.actions, i); } this.list.push(e), e.topOfTheStack = !0; } const s = this; return e.close = () => s.pop(e.dialogId), e.promise = new Promise((i, o) => { e.resolvePromise = i, e.rejectPromise = o; }), this.setCurrent(), e.dialogId; } getDialogFromId(e) { const t = Ke(this.list, { dialogId: e }); return t !== -1 ? this.list[t] : null; } pop(e) { const t = Ke(this.list, { dialogId: e }); t !== -1 && (this.list.splice(t, 1), this.list.length && t === this.list.length && (this.list[this.list.length - 1].topOfTheStack = !0)), this.setCurrent(); } isCurrentDialogPromise(e) { var t; return ((t = this.current) == null ? void 0 : t.promise) === e; } getDialogDefFromPromise(e) { return kn(this.list, { promise: e }); } } const de = new $r(); let Lr = 0; const se = [], Rr = $({ name: "ModalView", mixins: [Gt], setup() { const n = ++Lr; return Ee(() => { se.push(n), se.length > 1 && se.indexOf(n) > 0 && console.warn("Multiple instances of ModalView placed in VDom. there should be only one!", se); }), st(() => { const e = se.indexOf(n); e > -1 && se.splice(e, 1); }), { uniqueId: n }; }, render() { const n = de.current, e = n == null ? void 0 : n.dialogId; return !n || se.indexOf(this.uniqueId) !== 0 ? Ce("div", { key: e }) : this.renderFunction( e, n.title, n.body, n.actions, n.options, n.actionHandlers ); } }), St = { size: U.DEFAULT }, ne = { get isInstalled() { return se.length > 0; }, getDialogDefinition(n) { return n instanceof Promise ? de.getDialogDefFromPromise(n) : de.getDialogFromId(n); }, fromRenderFunctions(n, e) { return de.push(e, n); }, fromFormDefinition(n) { const e = n.layout, t = n.payload, r = n.actions, s = n.actionHandlers, i = n.errors; return this.message( n.title, { componentName: n.layout.componentName, props: { layout: e, payload: t, actions: r, errors: i } }, r.formFooter, { size: e.size || U.DEFAULT }, s ); }, message(n, e, t, r, s) { if (t) for (const o of t) { const l = ke(o.name); o[l] || (o[l] = Fe); } const i = new et( n, e, r || St, t || new V({ close: z.closeAction({ actionClose: Fe }) }), s ); return de.push(i), i.promise; }, yesNo(n, e, t, r) { const s = new et( n, e, r || St, t || new V({ yes: z.yesAction({ actionYes: Fe }), no: z.noAction({ actionNo: Fe }) }) ); return de.push(s), s.promise; } }; var Le = /* @__PURE__ */ ((n) => (n[n.Label = 0] = "Label", n[n.Filter = 1] = "Filter", n[n.Data = 2] = "Data", n))(Le || {}); ((n) => { n.headerRows = [ 0, 1 /* Filter */ ]; function e(r) { return Object.values(n).includes(r); } n.isDefined = e; function t(r) { return n.headerRows.includes(r); } n.isTHead = t; })(Le || (Le = {})); Object.freeze(Le); const B = Le, mt = { showLabelOrHelpText: !0, handlers: void 0, dialogHandlers: void 0 }; function ee(n, e) { const t = g({ get() { return n.modelValue; }, set(u) { e("update:modelValue", u); } }), r = g(() => n.errors != null ? n.errors instanceof Array ? n.errors : [n.errors] : []), s = g(() => r.value.length), i = g(() => n.showLabelOrHelpText ? n.field.label : ""), o = g(() => n.showLabelOrHelpText ? n.field.helpText : ""), l = g(() => Un.create({ value: t.value, touched: !0, visibility: xn.DisplayMode.FULL, errors: (r.value || []).map( (u) => u instanceof vt ? u : new vt(u) ), enabled: !0 })); l.value.validate(); const d = g(() => ({ label: i.value, "error-messages": r.value, "error-count": s.value + 10, // +10 so that it can show "rules" error messages hint: o.value, "persistent-hint": !0, "hide-details": "auto", control: l.value, placeholder: n.field.placeholder, "persistent-placeholder": !!(n.field.placeholder && n.field.placeholder.length > 0), enabled: !n.field.readOnly })); return { value: t, errorsList: r, errorsDisplayCount: s, label: i, helpText: o, baseBinds: d }; } const Tr = /* @__PURE__ */ $({ __name: "date-time", props: /* @__PURE__ */ it({ field: {}, actions: {}, errors: {}, showLabelOrHelpText: { type: Boolean }, modelValue: {}, handlers: {}, dialogHandlers: {} }, mt), emits: ["onValueConfirmed", "update:modelValue"], setup(n, { emit: e }) { const t = n, r = e, { value: s, baseBinds: i } = ee(t, r), o = g(() => t.field.renderParams.inputType), l = g(() => t.field.renderParams.formDateFormat), d = g(() => t.field.renderParams.formTimeFormat); return (u, c) => (h(), _(p(cn), J({ modelValue: p(s), "onUpdate:modelValue": c[0] || (c[0] = (m) => Q(s) ? s.value = m : null), errors: p(i)["error-messages"], hint: p(i).hint, "persistent-hint": p(i)["persistent-hint"], clearable: !0, "input-type": o.value, "display-format-date": l.value, "display-format-time": d.value }, p(i)), null, 16, ["modelValue", "errors", "hint", "persistent-hint", "input-type", "display-format-date", "display-format-time"])); } }), Nr = /* @__PURE__ */ $({ __name: "df-checkbox", props: /* @__PURE__ */ it({ field: {}, actions: {}, errors: {}, showLabelOrHelpText: { type: Boolean }, modelValue: {}, handlers: {}, dialogHandlers: {} }, mt), emits: ["update:modelValue"], setup(n, { emit: e }) { const t = n, r = e, { value: s, baseBinds: i } = ee(t, r); return (o, l) => (h(), _(p(dn), J({ modelValue: p(s), "onUpdate:modelValue": l[0] || (l[0] = (d) => Q(s) ? s.value = d : null), "allow-null": t.field.allowNull, class: o.field.renderParams.fieldCSSClass, name: o.field.name, enabled: !o.field.readOnly }, p(i)), null, 16, ["modelValue", "allow-null", "class", "name", "enabled"])); } }), Ar = /* @__PURE__ */ $({ __name: "df-ckeditor", props: /* @__PURE__ */ it({ field: {}, actions: {}, errors: {}, showLabelOrHelpText: { type: Boolean }, modelValue: {}, handlers: {}, dialogHandlers: {} }, mt), emits: ["update:modelValue"], setup(n, { emit: e }) { const t = n, r = e, { baseBinds: s, value: i } = ee(t, r); return (o, l) => (h(), _(p(mn), J({ modelValue: p(i), "onUpdate:modelValue": l[0] || (l[0] = (d) => Q(i) ? i.value = d : null), errors: p(s)["error-messages"], hint: p(s).hint, "persistent-hint": p(s)["persistent-hint"], "hide-details": p(s)["hide-details"] }, p(s)), null, 16, ["modelValue", "errors", "hint", "persistent-hint", "hide-details"])); } }), Er = /* @__PURE__ */ $({ __name: "df-color", props: { field: {}, actions: {}, errors: {}, showLabelOrHelpText: { type: Boolean }, modelValue: {}, handlers: {}, dialogHandlers: {} }, emits: ["update:modelValue"], setup(n, { emit: e }) { const t = n, r = e, { value: s, baseBinds: i } = ee(t, r); return (o, l) => (h(), _(p(fn), J({ modelValue: p(s), "onUpdate:modelValue": l[0] || (l[0] = (d) => Q(s) ? s.value = d : null), class: o.field.renderParams.fieldCSSClass, name: o.field.name, errors: p(i)["error-messages"], enabled: !o.field.readOnly }, p(i)), null, 16, ["modelValue", "class", "name", "errors", "enabled"])); } }), Dt = 250, kt = new Promise(() => { }); class Ir { constructor() { a(this, "activeRequests"); a(this, "requestCounter"); a(this, "apiClient"); a(this, "dialogPromise"); this.activeRequests = {}, this.requestCounter = 0, this.dialogPromise = kt; } addRequest() { const e = ++this.requestCounter; return this.activeRequests[e] = (/* @__PURE__ */ new Date()).getTime(), { requestId: e, timestamp: this.activeRequests[e] }; } removeRequest(e) { e && (delete this.activeRequests[e], this.progressDialogCheck()); } loading() { return Object.keys(this.activeRequests).length; } get isShowingProgress() { return ne.getDialogDefinition(this.dialogPromise) != null; } oldestActiveRequest() { const e = this.activeRequests, t = Object.keys(e); if (t.length === 0) return { requestId: null, timestamp: null, age: null }; const r = Number(t[0]); return { requestId: r, timestamp: e[r], age: (/* @__PURE__ */ new Date()).getTime() - e[r] }; } progressDialogCheck() { return w(this, null, function* () { if (!ne.isInstalled) return; const e = this.oldestActiveRequest(), t = e.age ? e.age : -1; if (t >= Dt && !this.isShowingProgress) this.show(); else if (t >= Dt && this.isShowingProgress) { if (!this.apiClient) return; const r = yield this.apiClient.get( "/dynamicforms/progress/", { headers: { "x-df-timestamp": e.timestamp } } ); if (this.isShowingProgress) { const i = ne.getDialogDefinition(this.dialogPromise).body; i.props != null && (i.props.progress = Number(r.data.value), i.props.label = r.data.comment); } } else this.loading() === 0 && this.isShowingProgress && this.hide(); }); } show() { console.log( pe(j( // eslint-disable-next-line vue/max-len "Showing progress: We have %(active_requests)s active requests to server oldest is %(age)s old with timestamp %(timestamp)s" ), { active_requests: this.loading(), age: this.oldestActiveRequest().age, timestamp: this.oldestActiveRequest().timestamp }) ); const e = j("Performing operation"); this.dialogPromise = ne.message( e, { componentName: "LoadingIndicator", props: { loading: !0, label: null, progress: null } } ); } hide() { const e = ne.getDialogDefinition(this.dialogPromise); e != null && e.close(), this.dialogPromise = kt; } } const Re = new Ir(); window.setInterval(() => { Re.progressDialogCheck(); }, 250); const Pr = 2083, P = jn.create({ xsrfCookieName: "csrftoken", xsrfHeaderName: "X-CSRFToken" }); Re.apiClient = P; function ie(n) { let e = n.data; return typeof e == "string" && (e = new String(e)), e && Object.defineProperty( e, "$response-object", { get() { return n; }, enumerable: !1, configurable: !1 } ), e; } P.interceptors.request.use((n) => { var t, r, s; const e = (t = n.showProgress) != null ? t : !0; if (n.headers["x-df-axios"] = "axios", !((r = n.url) != null && r.includes("/dynamicforms/progress")) && !((s = n.url) != null && s.includes("unpkg.com")) && e) { const i = Re.addRequest(); n.sequence = i.requestId, n.headers["x-df-timestamp"] = i.timestamp; } if (Ye(n.method) === "get" && On(n.url) > Pr && rt($n(Ln(n.headers), (i) => Ye(i)), "x-viewmode")) { const i = "Your request exceeds maximum length"; console.error(i), new AbortController().abort(i); } return n; }); P.interceptors.response.use( (n) => (Re.removeRequest(n.config.sequence), n), (n) => (Re.removeRequest(n.config.sequence), Promise.reject(n)) ); const Vr = /* @__PURE__ */ $({ __name: "df-file", props: { field: {}, actions: {}, errors: {}, showLabelOrHelpText: { type: Boolean }, modelValue: {}, handlers: {}, dialogHandlers: {} }, emits: ["update:modelValue"], setup(n, { emit: e }) { const t = n, r = e, { value: s, baseBinds: i } = ee(t, r), o = { upload: (l, d) => w(this, null, function* () { const u = new FormData(); u.append("file", l, l.name); const c = yield P.post( "/dynamicforms/preupload-file/", u, { showProgress: !1, onUploadProgress: function(y) { var b; y.event.lengthComputable && d != null && d(y.loaded, (b = y.total) != null ? b : 0); } } ); return console.log(c.data.identifier), c.data.identifier; }), delete: (l) => w(this, null, function* () { return yield P.delete(`/dynamicforms/preupload-file/${encodeURIComponent(l)}/`), Promise.resolve(); }), touch: (l) => w(this, null, function* () { return console.log("Touching file:", l), Promise.resolve(); }) }; return (l, d) => (h(), _(p(hn), J({ modelValue: p(s), "onUpdate:modelValue": d[0] || (d[0] = (u) => Q(s) ? s.value = u : null), comms: o, class: l.field.renderParams.fieldCSSClass, name: l.field.name, errors: p(i)["error-messages"], enabled: !l.field.readOnly, hint: p(i).hint }, p(i)), null, 16, ["modelValue", "class", "name", "errors", "enabled", "hint"])); } }), Hr = /* @__PURE__ */ $({ __name: "df-input", props: { field: {}, actions: {}, errors: {}, showLabelOrHelpText: { type: Boolean }, modelValue: {}, handlers: {}, dialogHandlers: {} }, emits: ["update:modelValue"], setup(n, { emit: e }) { const t = n, r = e, { value: s, baseBinds: i } = ee(t, r), o = g(() => t.field.renderParams.inputType); return (l, d) => (h(), _(p(pn), J({ modelValue: p(s), "onUpdate:modelValue": d[0] || (d[0] = (u) => Q(s) ? s.value = u : null), class: l.field.renderParams.fieldCSSClass, name: l.field.name, errors: p(i)["error-messages"], enabled: !l.field.readOnly, "input-type": o.value, step: l.field.renderParams.step, min: l.field.renderParams.min, max: l.field.renderParams.max }, p(i)), null, 16, ["modelValue", "class", "name", "errors", "enabled", "input-type", "step", "min", "max"])); } }); var Te = /* @__PURE__ */ ((n) => (n[n.TABLE = 1] = "TABLE", n[n.FORM = 2] = "FORM", n[n.DIALOG = 3] = "DIALOG", n))(Te || {}); ((n) => { function e(r) { return r.toUpperCase() === "TABLE" ? 1 : r.toUpperCase() === "FORM" ? 2 : r.toUpperCase() === "DIALOG" ? 3 : 1; } n.fromString = e; function t(r) { const s = typeof r == "number" ? r : n.fromString(r); return Object.values(n).includes(s); } n.isDefined = t; })(Te || (Te = {})); Object.freeze(Te); const G = Te; function Wt(n) { if (n) return n.split(".").reduce((e, t) => { var r; return (r = e[t]) != null ? r : {}; }, window); } var Ne = /* @__PURE__ */ ((n) => (n[n.ASC = 1] = "ASC", n[n.DESC = 2] = "DESC", n[n.UNORDERED = 0] = "UNORDERED", n))(Ne || {}); ((n) => { function e(r) { return r.toLowerCase().includes("asc") ? 1 : r.toLowerCase().includes("desc") ? 2 : 0; } n.fromString = e; function t(r) { return Object.values(n).includes(r); } n.isDefined = t; })(Ne || (Ne = {})); Object.freeze(Ne); const I = Ne; class zt { /** * Column ordering management utility * * @param orderingString: e.g. ordering asc seg-1 * @param orderingArray: a common array (created in columns.js) containing all order segments * @param column: TableColumn reference to the column itself. Needed for error messages below */ constructor(e, t, r) { a(this, "direction"); a(this, "changeCounter"); // TODO: Jure 2.2023 not sure it's needed any more in Vue3? a(this, "column"); // TableColumn a(this, "orderingArray"); // reference to containing array a(this, "isOrderable"); a(this, "isOrdered"); a(this, "segment"); this.direction = I.fromString(e), this.changeCounter = 0; const s = /seg-(\d+)/.exec(e), i = s != null ? Number(s[1]) : 0; t.length = Math.max(t.length, i), i && t.splice(i - 1, 1, this), Object.defineProperties(this, { column: { get() { return r; }, enumerable: !1 }, orderingArray: { get() { return t; }, enumerable: !1 }, isOrderable: { get() { return e.includes("ordering"); }, enumerable: !0 }, isOrdered: { get() { return this.isOrderable && this.segment > 0 && this.direction !== I.UNORDERED; }, enumerable: !0 }, segment: { get() { return this.isOrderable && t.indexOf(this) + 1 || null; }, enumerable: !0 } }); } /** * cycles field ordering 'asc' -> 'desc' -> 'unsorted' */ cycleOrdering() { this.isOrdered ? this.direction === I.ASC ? this.direction = I.DESC : this.direction = I.UNORDERED : this.direction = I.ASC; } /** * sets column sort sequence and direction * @param direction: one of "asc", "desc" or "unsorted" * @param sequence: integer. if none is provided, existing sequence # will be used * or 1 if column was unsorted */ setSorted(e, t) { let r = t || (this.segment > 0 ? this.segment : 1); if (r > this.orderingArray.length + 1 && (r = this.orderingArray.length + 1), this.isOrderable) I.isDefined(e) ? (this.segment && this.orderingArray.splice(this.segment - 1, 1), e !== I.UNORDERED && this.orderingArray.splice(r - 1, 0, this), this.direction = e) : console.warn(`unknown sort direction "${e}" for the column ${this.column.name}. not doing anything`); else throw new Error(`column ${this.column.name} is not orderable, but you are trying to set its order direction.`); } handleColumnHeaderClick(e) { if (this.isOrderable) { if (!e.altKey) if (e.ctrlKey && e.shiftKey) this.setSorted(I.UNORDERED); else if (e.ctrlKey) this.setSorted(this.direction === I.ASC ? I.DESC : I.ASC, 1); else if (e.shiftKey) { const r = this.segment || this.orderingArray.length + 1, s = this.direction === I.ASC ? I.DESC : I.ASC; this.setSorted(s, r); } else this.cycleOrdering(), this.orderingArray.splice(0, this.orderingArray.length), this.setSorted(this.direction, 1); this.changeCounter++; } } calculateOrderingValue(e) { const t = this.orderingArray.map((r) => ({ name: r.column.name, direction: r.direction })); return e ? e(t) : t.map((r) => (r.direction === I.ASC ? "" : "-") + r.name); } calculateOrderingFunction(e) { const t = this.orderingArray.map((r) => ({ name: r.column.name, direction: r.direction })); return e ? e(t) : t; } } class Ge { constructor(e, t) { a(this, "name"); a(this, "label"); a(this, "align"); a(this, "visibility"); a(this, "renderParams"); a(this, "maxWidth"); a(this, "ordering"); a(this, "_maxWidth"); a(this, "layout"); a(this, "CSSClass"); a(this, "CSSClassHead"); a(this, "renderComponentName"); a(this, "renderDecoratorFunction"); a(this, "formFieldInstance"); var i; this._maxWidth = 0, e.ordering = e.ordering || "", this.ordering = new zt(e.ordering, t, this), this.layout = null; const r = ((i = e.render_params) == null ? void 0 : i.table) || ""; let s = this.renderDecoratorPlain; if (r && r.substring(0, 13) === "df-tablecell-") switch (r.substring(13)) { case "bool": s = this.renderDecoratorBool; break; case "link": s = this.renderDecoratorLink; break; case "email": s = this.renderDecoratorEmail; break; case "file": s = this.renderDecoratorFile; break; case "ipaddr": s = this.renderDecoratorIP; break; case "color": s = this.renderDecoratorColor; break; } else r && r.substring(0, 1) !== "#" && (s = Wt(r)); Object.defineProperties(this, { name: { get() { return e.name; }, enumerable: !0 }, label: { get() { return e.label; }, enumerable: !0 }, align: { get() { return e.alignment === "decimal" ? "right" : e.alignment; }, enumerable: !0 }, visibility: { get() { return x.fromAny(e.visibility.table); }, enumerable: !0 }, CSSClass: { get() { return e.table_classes || ""; }, enumerable: !0 }, CSSClassHead: { get() { return this.ordering.isOrderable && "ordering" || ""; }, enumerable: !0 }, renderParams: { get() { return e.render_params; }, enumerable: !0 }, renderComponentName: { get() { return r && r.substring(0, 1) === "#" ? r.substring(1) : ""; }, enumerable: !0 }, renderDecoratorFunction: { get() { return (o, l) => s.apply(this, [o, l]); }, enumerable: !0 }, maxWidth: { get() { return this._maxWidth; }, enumerable: !0 } }); } setLayout(e) { this.layout = e; } setMaxWidth(e) { e > this._maxWidth && (this._maxWidth = e); } /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ renderDecoratorPlain(e, t) { return e[this.name]; } renderDecoratorColor(e, t) { return t ? this.renderDecoratorPlain(e, t) : `<div style="display: inline-block; width: 1.25em; height: 1.25em; background-color: ${e[this.name]}"/>`; } renderDecoratorBool(e, t) { if (t) return this.renderDecoratorPlain(e, t); const r = e[this.name]; return r === null ? "null" : `<span style="color: ${r ? "green" : "red"};">${r ? "&#10004;" : "&#10008;"}</span>`; } renderDecoratorLink(e, t) { return t ? this.renderDecoratorPlain(e, t) : `<a href="${e[this.name]}">${e[this.name]}</a>`; } renderDecoratorEmail(e, t) { if (t) return this.renderDecoratorPlain(e, t); const r = e[this.name], s = r.includes("<") ? r.substring(0, r.indexOf("<")).trim() : r; return `<a href="mailto:${r}">${s}</a>`; } renderDecoratorFile(e, t) { if (t) return this.renderDecoratorPlain(e, t); const r = e[this.name]; if (r) { const s = `(function(e) { e.preventDefault(); e.stopPropagation(); window.open('${r.replace(/\/$/, "")}', '_blank'); })`.replace(/\s+/g, " "), i = r.replace(/^.*[\\/]/, ""); return `<a href="javascript:void(0)" onclick="${s}(event)">${i}</a>`; } return null; } renderDecoratorIP(e, t) { if (t) return this.renderDecoratorPlain(e, t); let r = e[this.name]; const s = r.split("."); return s.length === 4 && (r = s.map((i) => `${i.length < 3 ? `<span style="opacity: .5">${"000".slice(i.length - 3