scrivito-pisasales-questionnaire-builder
Version:
Scrivito widgets for building PisaSales questionnaires
291 lines (290 loc) • 11.6 kB
JavaScript
import { jsx as k, jsxs as me } from "react/jsx-runtime";
import { isInPlaceEditingActive as N, useDataItem as ge, isUserLoggedIn as he, load as Ie } from "scrivito";
import * as l from "react";
import { useState as M, useRef as Se, useCallback as ve, useEffect as K, useMemo as we, createContext as Q, useContext as Y } from "react";
import { d as xe, i as L, g as Ee } from "./AnswersDataClass-IG1cx70G.js";
import { j as C, l as be, a0 as Ae, a1 as Te, E as z, K as J, U as $, Y as X, a2 as Pe, X as ye, a3 as Ce, R as ke, a4 as _e, J as De, a5 as Me, a6 as Fe, a7 as Ue, a8 as Oe, a9 as Ne, aa as Re, ab as Ve, Q as Le, ac as Qe, ad as Ye, ae as je } from "./scrivitoConfig-WST4rsmc.js";
const Be = "Warning:", f = "Editor's info:", Ge = {
creationPending: { prefix: f, content: "This questionnaire has not been created in the backend yet." },
invalid: { prefix: f, content: "Some attributes are invalid. Please review and correct them." },
offline: { prefix: Be, content: "The backend is not reachable. Please check your configuration or contact your administrator." },
pendingUpdate: { prefix: f, content: "This questionnaire has unsaved local changes. To ensure all modifications are reflected in the backend, please push the updates from the properties tab." },
inCreation: { prefix: f, content: "Creating the questionnaire in the backend. Please wait..." },
updating: { prefix: f, content: "Updating questionnaire data. Please wait..." },
void: { prefix: f, content: "The questionnaire is ready for use." },
unconfiguredUrl: { prefix: f, content: "The backend connection is not configured yet." },
noFormContext: { prefix: f, content: "This widget must be placed within a Questionnaire widget! " },
publicSiteEditMode: { prefix: f, content: "This questionnaire is ready for use but is placed on a public site. Only logged-in users or users with a valid access token can access it." },
publicSiteNoContext: { prefix: null, content: "No valid login or access token found." },
invalidToken: { prefix: null, content: "The access token is invalid or has expired." },
submittingPreview: { prefix: f, content: "Previewing the submitting message/content." },
submittedPreview: { prefix: f, content: "Previewing the submission success message/content." },
failedPreview: { prefix: f, content: "Previewing the submission failure message/content." },
fileUploadsDisabled: { prefix: f, content: "File uploads are disabled until you create or update the questionnaire." }
}, ot = ({ className: e, status: t }) => {
if (t == "void")
return null;
const s = ["fileUploadsDisabled", "unconfiguredUrl", "pendingUpdate", "creationPending", "invalid"];
if (!N() && s.includes(t))
return null;
const o = Ge[t], a = t == "publicSiteEditMode" ? "alert-success" : o.prefix == f ? "alert-warning" : "alert-error";
return /* @__PURE__ */ k("div", { className: "qst-message-block-container", children: /* @__PURE__ */ k("div", { className: `message-block alert fade show ${a} ${e || ""}`, children: /* @__PURE__ */ me("p", { className: "m-0", children: [
o.prefix && /* @__PURE__ */ k("strong", { children: o.prefix }),
" ",
o.content
] }) }) });
}, He = async () => {
const e = be();
if (C(e))
return null;
try {
return !!(await fetch(e + "/version")).ok;
} catch {
return !1;
}
}, Je = () => {
const [e, t] = M(!0), s = Se(!1), o = ve(async () => {
if (!s.current) {
s.current = !0;
try {
const a = await He();
t(a);
} catch (a) {
console.error("Failed to check Pisa connection status:", a), t(!1);
}
}
}, []);
return K(() => {
o();
}, [o]), { isOnline: e, refresh: o };
}, Z = Q(void 0), at = ({ children: e }) => {
const t = Je(), s = we(() => t, [t.isOnline]);
return /* @__PURE__ */ k(Z.Provider, { value: s, children: e });
}, $e = () => {
const e = Y(Z);
if (!e)
throw new Error("usePisaConnectionStatusContext must be used within a PisaStatusProvider");
return e;
}, Xe = (e) => {
const t = window.scrollY, s = Ke(e) - 95, o = 15;
e.scroll(0, 0), Math.abs(t - s) > o && window.scrollTo({
top: s,
behavior: "smooth"
});
};
function Ke(e) {
return e.getBoundingClientRect().top + window.pageYOffset;
}
const q = Q(void 0), W = () => Y(q), rt = ({ children: e }) => {
const [t, s] = M({}), [o, a] = M({}), [T, w] = M(null), u = (I, p) => {
s((i) => ({ ...i, [I]: !p }));
}, P = (I, p) => {
a((i) => ({
...i,
[I]: p
}));
}, x = (I, p) => {
let i = !0, m = !1;
const g = document.getElementById(I);
if (!g) return i;
const h = g.querySelector(`[data-step-number='${p}']`);
if (!h) return i;
const y = Array.from(h.querySelectorAll("input, select, textarea") || []), _ = /* @__PURE__ */ new Set();
for (const d of y) {
const S = d.name || "";
if (!(o[S] || !1)) {
u(S, !0);
continue;
}
if (d instanceof HTMLInputElement && d.type === "checkbox" && d.hasAttribute("data-group")) {
const E = d.getAttribute("data-group");
if (_.has(E)) continue;
y.filter((D) => D instanceof HTMLInputElement && D.getAttribute("data-group") === E).some((D) => D.checked) || (u(S, !1), i = !1), _.add(E);
} else d instanceof HTMLInputElement && d.type === "checkbox" && d.hasAttribute("data-tristate") ? d.getAttribute("data-tristate") === "unset" && (u(S, !1), i = !1) : d instanceof HTMLInputElement && (d.type === "checkbox" || d.type == "radio") ? h.querySelectorAll(`input[name='${S}']:checked`).length === 0 && (u(S, !1), i = !1) : d.value.trim() || (u(S, !1), i = !1);
!m && !i && (w(S), m = !0);
}
return i && w(null), i;
};
return /* @__PURE__ */ k(q.Provider, { value: { invalidFields: t, mandatoryFields: o, firstInvalidField: T, setFirstInvalidField: w, updateValidationState: u, registerField: P, validate: x }, children: e });
}, ee = Q(void 0), ze = () => {
const e = Y(ee);
if (!e)
throw new Error("useQuestionnaireStepsContext must be used within a QuestionnaireStepsProvider");
return e;
}, it = ({ children: e, qstContainerWidget: t }) => {
const s = t.get(Ae) || [], o = t.get(Te) === "single-step", [a, T] = M(1), w = a === s.length, u = s.length, P = t.get(z), { validate: x } = W(), I = () => x(P, a), p = (m) => {
let g = !1, h = 0;
return s.some((y, _) => y.id() === m ? (h = _ + 1, g = h === a, !0) : !1), { stepNumber: h, isActive: g, isSingleStep: o };
}, i = (m) => {
if (N()) {
console.log("Navigation buttons do not work in edit mode.");
return;
}
if (m && !I()) return;
const g = m ? Math.min(a + 1, u) : Math.max(a - 1, 1);
T(g), setTimeout(() => {
const h = document.getElementById(P);
Xe(h);
}, 0);
};
return /* @__PURE__ */ k(
ee.Provider,
{
value: { currentStep: a, stepsLength: u, isLastStep: w, isSingleStep: o, getStepInfo: p, onPageChange: i },
children: e
}
);
}, Ze = (e) => {
const t = ge(), s = e.get(J) || "", o = e.get($) || "", a = e.get(X) || "", [T, w] = M({
activityId: "",
contactId: "",
projectId: ""
});
return K(() => {
const u = (P, x, I) => P === "data-item" ? (t == null ? void 0 : t.get(I)) || "" : x;
w({
activityId: u(
e.get(De),
e.get(J),
e.get(_e)
),
contactId: u(
e.get(ke),
e.get($),
e.get(Ce)
),
projectId: u(
e.get(ye),
e.get(X),
e.get(Pe)
)
});
}, [s, a, o]), T;
}, qe = async (e) => {
const t = await xe(e);
return (t == null ? void 0 : t.get(Me)) || !1;
}, te = l.createContext(void 0), ct = () => l.useContext(te), lt = ({ children: e, qstContainerWidget: t }) => {
const s = t.get(Fe), o = t.get(Ue), a = t.get(Oe) || !1, T = t.get(Ne) || !1, w = t.get(Re) || !1, u = t.get(z), [P, x] = l.useState(!1), [I, p] = l.useState(!1), [i, m] = l.useState(!1), [g, h] = l.useState(
/* @__PURE__ */ new Map()
), [y, _] = l.useState({}), [d, S] = l.useState(0), { activityId: F, contactId: E, projectId: U } = Ze(t), { isOnline: R } = $e(), { currentStep: D } = ze(), { validate: ne } = W(), O = Ee();
l.useEffect(() => {
N() && (a ? j() : T ? B() : w ? G() : (x(!1), m(!1), p(!1)));
}, [w, T, a]);
const j = l.useCallback(() => {
x(!0), p(!1), m(!1);
}, []), B = l.useCallback(() => {
x(!1), p(!0), m(!1);
}, []), G = l.useCallback(() => {
x(!1), p(!1), m(!0);
}, []), se = l.useCallback((n = 1) => {
S((r) => r + Math.max(0, n));
}, []), oe = l.useCallback((n = 1) => {
S((r) => Math.max(0, r - Math.max(0, n)));
}, []), H = d > 0;
l.useEffect(() => {
(async () => {
if (C(s) || !O || !R || o == Ve)
return;
const r = !C(F) || !C(E) || !C(U);
if (!L() && (!he() || !r) || await qe(s))
return;
const b = await Ie(() => {
const A = O.all(), v = { limit: 999 };
return L() || (v.filters = {
questionnaireId: {
operator: "equals",
value: s
},
activityId: {
operator: "equals",
value: F
},
projectId: {
operator: "equals",
value: U
},
contactId: {
operator: "equals",
value: E
}
}), A.transform(v).take();
});
re(b);
})();
}, [R, F, E, U]);
const ae = (n) => {
const r = n.get(Le), c = n.get(Qe) || [""], b = n.get(Ye) || [""], A = n.get(je) || (/* @__PURE__ */ new Date()).toISOString();
return { questionId: r, value: c, valueIdentifier: b, updatedAt: A };
}, re = (n) => {
const r = /* @__PURE__ */ new Map();
for (const c of n) {
const { questionId: b, value: A, valueIdentifier: v, updatedAt: V } = ae(c);
b && r.set(b, { value: A, valueIdentifier: v, updatedAt: V });
}
h(r);
}, ie = (n, r, c = [""]) => {
if (ue(n, r, c), C(n))
return;
const b = (/* @__PURE__ */ new Date()).toISOString();
h((A) => {
const v = new Map(A);
return v.set(n, { value: r, valueIdentifier: c, updatedAt: b }), v;
});
}, ce = l.useCallback((n) => g.get(n), [g]), le = (n, r) => {
_((c) => ({
...c,
[n]: r
}));
}, ue = (n, r, c) => {
if (!N()) {
if (C(n))
throw new Error("Question ID cannot be empty.");
if (!Array.isArray(r) || !Array.isArray(c))
throw new Error("Value and Value Identifier must be arrays.");
}
}, de = async (n) => {
if (n.preventDefault(), !(H || !ne(u, D)))
try {
j();
const c = Array.from(g.entries()).map(([v, { value: V, valueIdentifier: fe, updatedAt: pe }]) => ({
questionId: v,
updatedAt: pe,
value: y[v] ? [""] : V,
valueIdentifier: y[v] ? [""] : fe
})), A = !L() ? {
keys: { activityId: F, contactId: E, projectId: U },
data: c
} : {
data: c
};
await (O == null ? void 0 : O.create(A)), B();
} catch (c) {
console.error(c), G();
}
};
return /* @__PURE__ */ k(te.Provider, { value: {
answers: g,
onChange: ie,
onSubmit: de,
isSubmitting: P,
successfullySent: I,
submissionFailed: i,
getAnswer: ce,
setExcludedFromSubmit: le,
beginUpload: se,
finishUpload: oe,
hasPendingUploads: H
}, children: e });
};
export {
lt as F,
at as P,
ot as Q,
rt as V,
ze as a,
W as b,
$e as c,
it as d,
ct as u
};
//# sourceMappingURL=FormContext-CyyAThXO.js.map