@duffcloudservices/site-forms 0.4.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -3
- package/dist/composables/readExpectedJson.d.ts +158 -0
- package/dist/composables/useFormSubmission.d.ts +5 -1
- package/dist/composables/useSitePhiPosture.d.ts +71 -0
- package/dist/fields/DcsFormDate.vue.d.ts +2 -2
- package/dist/fields/DcsFormSelect.vue.d.ts +2 -2
- package/dist/fields/DcsFormText.vue.d.ts +2 -2
- package/dist/fields/DcsFormTextarea.vue.d.ts +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1014 -486
- package/dist/index.js.map +1 -1
- package/dist/site-forms.css +1 -1
- package/dist/types.d.ts +16 -0
- package/package.json +1 -1
- package/src/DcsForm.vue +98 -14
- package/src/__tests__/missing-form-error-surfacing.test.ts +124 -0
- package/src/__tests__/non-json-response.test.ts +282 -0
- package/src/__tests__/phi-guidance.test.ts +239 -0
- package/src/__tests__/receipt-validation.test.ts +425 -0
- package/src/__tests__/submission.test.ts +46 -5
- package/src/__tests__/visible-if.test.ts +17 -4
- package/src/composables/readExpectedJson.ts +360 -0
- package/src/composables/useFormSubmission.ts +66 -13
- package/src/composables/useSitePhiPosture.ts +123 -0
- package/src/index.ts +29 -0
- package/src/style.css +25 -0
- package/src/types.ts +16 -0
package/dist/index.js
CHANGED
|
@@ -1,305 +1,790 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
1
|
+
import { ref as E, watch as ee, computed as m, reactive as Ee, defineComponent as M, createElementBlock as f, openBlock as c, normalizeClass as Oe, renderSlot as V, createCommentVNode as T, createTextVNode as W, toDisplayString as w, createBlock as _, withCtx as j, createElementVNode as v, Fragment as K, renderList as G, onBeforeUnmount as Re, onMounted as pe, unref as g, resolveDynamicComponent as De } from "vue";
|
|
2
|
+
import je from "ajv";
|
|
3
|
+
import _e from "ajv-formats";
|
|
4
|
+
import $e from "js-yaml";
|
|
5
|
+
const ce = "dcs.sound", xe = {
|
|
6
|
+
enabled: !1,
|
|
7
|
+
userSet: !1,
|
|
8
|
+
prmOverride: !1,
|
|
9
|
+
volume: 0.3,
|
|
10
|
+
categories: {
|
|
11
|
+
interaction: !0,
|
|
12
|
+
overlay: !0,
|
|
13
|
+
navigation: !0,
|
|
14
|
+
notification: !0,
|
|
15
|
+
hero: !1
|
|
16
|
+
},
|
|
17
|
+
hintShown: !1
|
|
18
|
+
};
|
|
19
|
+
function Be(e) {
|
|
20
|
+
const t = typeof e == "number" && Number.isFinite(e) ? e : xe.volume;
|
|
21
|
+
return Math.min(0.8, Math.max(0, t));
|
|
22
|
+
}
|
|
23
|
+
function me(e) {
|
|
24
|
+
const t = xe, n = e?.categories ?? {};
|
|
25
|
+
return {
|
|
26
|
+
enabled: typeof e?.enabled == "boolean" ? e.enabled : t.enabled,
|
|
27
|
+
userSet: typeof e?.userSet == "boolean" ? e.userSet : t.userSet,
|
|
28
|
+
prmOverride: typeof e?.prmOverride == "boolean" ? e.prmOverride : t.prmOverride,
|
|
29
|
+
volume: Be(e?.volume),
|
|
30
|
+
categories: {
|
|
31
|
+
interaction: n.interaction ?? t.categories.interaction,
|
|
32
|
+
overlay: n.overlay ?? t.categories.overlay,
|
|
33
|
+
navigation: n.navigation ?? t.categories.navigation,
|
|
34
|
+
notification: n.notification ?? t.categories.notification,
|
|
35
|
+
hero: n.hero ?? t.categories.hero
|
|
36
|
+
},
|
|
37
|
+
hintShown: typeof e?.hintShown == "boolean" ? e.hintShown : t.hintShown
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function Ne() {
|
|
41
|
+
if (typeof window > "u" || !window.localStorage)
|
|
42
|
+
return null;
|
|
43
|
+
try {
|
|
44
|
+
const e = window.localStorage.getItem(ce);
|
|
45
|
+
return e ? me(JSON.parse(e)) : null;
|
|
46
|
+
} catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const ke = Ne(), I = E(ke ?? me(null));
|
|
51
|
+
let Pe = ke !== null;
|
|
52
|
+
function ze(e) {
|
|
53
|
+
if (!(typeof window > "u" || !window.localStorage))
|
|
54
|
+
try {
|
|
55
|
+
window.localStorage.setItem(ce, JSON.stringify(e)), Pe = !0;
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
ee(I, (e) => ze(e), { deep: !0 });
|
|
60
|
+
typeof window < "u" && window.addEventListener && window.addEventListener("storage", (e) => {
|
|
61
|
+
if (e.key === ce && e.newValue)
|
|
62
|
+
try {
|
|
63
|
+
I.value = me(JSON.parse(e.newValue)), Pe = !0;
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const te = 0.02, qe = 1e-4;
|
|
68
|
+
function k(e, t, n, i) {
|
|
69
|
+
const { freq: o, type: a = "sine", dur: d = 0.15, gain: s = 0.2, attack: l = 0.01, glideTo: u } = n, r = e.createOscillator(), b = e.createGain();
|
|
70
|
+
r.type = a, r.frequency.setValueAtTime(o, i), u && r.frequency.exponentialRampToValueAtTime(u, i + d), b.gain.setValueAtTime(qe, i), b.gain.exponentialRampToValueAtTime(s, i + l), b.gain.exponentialRampToValueAtTime(1e-3, i + d), r.connect(b).connect(t), r.start(i), r.stop(i + d + te), r.onended = () => {
|
|
71
|
+
try {
|
|
72
|
+
r.disconnect(), b.disconnect();
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function Ke(e, t, n, i) {
|
|
78
|
+
const { freq: o, ratio: a = 2, index: d = 120, dur: s = 0.4, gain: l = 0.2 } = n, u = e.createOscillator(), r = e.createOscillator(), b = e.createGain(), F = e.createGain();
|
|
79
|
+
u.type = "sine", r.type = "sine", u.frequency.setValueAtTime(o, i), r.frequency.setValueAtTime(o * a, i), b.gain.setValueAtTime(d, i), b.gain.exponentialRampToValueAtTime(1, i + s), F.gain.setValueAtTime(qe, i), F.gain.exponentialRampToValueAtTime(l, i + 0.012), F.gain.exponentialRampToValueAtTime(1e-3, i + s), r.connect(b).connect(u.frequency), u.connect(F).connect(t), r.start(i), u.start(i), r.stop(i + s + te), u.stop(i + s + te), u.onended = () => {
|
|
80
|
+
try {
|
|
81
|
+
u.disconnect(), r.disconnect(), b.disconnect(), F.disconnect();
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function Q(e, t, n, i) {
|
|
87
|
+
const { dur: o = 0.08, gain: a = 0.2, cutoff: d = 2e3, q: s = 1, sweepTo: l } = n, u = Math.max(1, Math.floor(e.sampleRate * o)), r = e.createBuffer(1, u, e.sampleRate), b = r.getChannelData(0);
|
|
88
|
+
for (let P = 0; P < u; P++)
|
|
89
|
+
b[P] = Math.random() * 2 - 1;
|
|
90
|
+
const F = e.createBufferSource();
|
|
91
|
+
F.buffer = r;
|
|
92
|
+
const L = e.createBiquadFilter();
|
|
93
|
+
L.type = "bandpass", L.frequency.setValueAtTime(d, i), L.Q.value = Math.min(s, 10), l && L.frequency.exponentialRampToValueAtTime(l, i + o);
|
|
94
|
+
const S = e.createGain();
|
|
95
|
+
S.gain.setValueAtTime(a, i), S.gain.exponentialRampToValueAtTime(1e-3, i + o), F.connect(L).connect(S).connect(t), F.start(i), F.stop(i + o + te), F.onended = () => {
|
|
96
|
+
try {
|
|
97
|
+
F.disconnect(), L.disconnect(), S.disconnect();
|
|
98
|
+
} catch {
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const U = 523.25, he = 587.33, z = 659.25, X = 783.99, Ue = 1046.5, He = 392, oe = 440, We = 293.66, Ie = {
|
|
103
|
+
// ── interaction ────────────────────────────────────────────────────────
|
|
104
|
+
"interaction.tap": {
|
|
105
|
+
category: "interaction",
|
|
106
|
+
gain: 0.25,
|
|
107
|
+
duration: 0.06,
|
|
108
|
+
render: (e, t, n, i) => Q(e, t, { dur: 0.05, gain: i, cutoff: 1800, q: 1 }, n)
|
|
109
|
+
},
|
|
110
|
+
"interaction.subtle": {
|
|
111
|
+
category: "interaction",
|
|
112
|
+
gain: 0.12,
|
|
113
|
+
duration: 0.04,
|
|
114
|
+
render: (e, t, n, i) => Q(e, t, { dur: 0.035, gain: i, cutoff: 2400, q: 0.7 }, n)
|
|
115
|
+
},
|
|
116
|
+
"interaction.toggle": {
|
|
117
|
+
category: "interaction",
|
|
118
|
+
gain: 0.2,
|
|
119
|
+
duration: 0.07,
|
|
120
|
+
render: (e, t, n, i) => k(e, t, { freq: z, type: "triangle", dur: 0.07, gain: i, attack: 5e-3 }, n)
|
|
121
|
+
},
|
|
122
|
+
"interaction.confirm": {
|
|
123
|
+
category: "interaction",
|
|
124
|
+
gain: 0.3,
|
|
125
|
+
duration: 0.09,
|
|
126
|
+
render: (e, t, n, i) => k(e, t, { freq: U, type: "sine", dur: 0.09, gain: i, attack: 8e-3 }, n)
|
|
127
|
+
},
|
|
128
|
+
// ── overlay ────────────────────────────────────────────────────────────
|
|
129
|
+
"overlay.open": {
|
|
130
|
+
category: "overlay",
|
|
131
|
+
gain: 0.18,
|
|
132
|
+
duration: 0.18,
|
|
133
|
+
render: (e, t, n, i) => Q(e, t, { dur: 0.18, gain: i, cutoff: 700, q: 0.8, sweepTo: 2200 }, n)
|
|
134
|
+
},
|
|
135
|
+
"overlay.close": {
|
|
136
|
+
category: "overlay",
|
|
137
|
+
gain: 0.18,
|
|
138
|
+
duration: 0.18,
|
|
139
|
+
render: (e, t, n, i) => Q(e, t, { dur: 0.18, gain: i, cutoff: 2200, q: 0.8, sweepTo: 600 }, n)
|
|
140
|
+
},
|
|
141
|
+
"overlay.expand": {
|
|
142
|
+
category: "overlay",
|
|
143
|
+
gain: 0.16,
|
|
144
|
+
duration: 0.16,
|
|
145
|
+
render: (e, t, n, i) => k(e, t, { freq: U, type: "sine", dur: 0.16, gain: i, glideTo: z }, n)
|
|
146
|
+
},
|
|
147
|
+
"overlay.collapse": {
|
|
148
|
+
category: "overlay",
|
|
149
|
+
gain: 0.16,
|
|
150
|
+
duration: 0.16,
|
|
151
|
+
render: (e, t, n, i) => k(e, t, { freq: z, type: "sine", dur: 0.16, gain: i, glideTo: U }, n)
|
|
152
|
+
},
|
|
153
|
+
// ── navigation ─────────────────────────────────────────────────────────
|
|
154
|
+
"navigation.forward": {
|
|
155
|
+
category: "navigation",
|
|
156
|
+
gain: 0.2,
|
|
157
|
+
duration: 0.14,
|
|
158
|
+
render: (e, t, n, i) => k(e, t, { freq: he, type: "sine", dur: 0.13, gain: i, glideTo: X }, n)
|
|
159
|
+
},
|
|
160
|
+
"navigation.backward": {
|
|
161
|
+
category: "navigation",
|
|
162
|
+
gain: 0.2,
|
|
163
|
+
duration: 0.14,
|
|
164
|
+
render: (e, t, n, i) => k(e, t, { freq: X, type: "sine", dur: 0.13, gain: i, glideTo: he }, n)
|
|
165
|
+
},
|
|
166
|
+
"navigation.tab": {
|
|
167
|
+
category: "navigation",
|
|
168
|
+
gain: 0.18,
|
|
169
|
+
duration: 0.1,
|
|
170
|
+
render: (e, t, n, i) => k(e, t, { freq: oe, type: "triangle", dur: 0.09, gain: i, attack: 5e-3 }, n)
|
|
171
|
+
},
|
|
172
|
+
// ── notification ─────────────────────────────────────────────────────────
|
|
173
|
+
"notification.info": {
|
|
174
|
+
category: "notification",
|
|
175
|
+
gain: 0.15,
|
|
176
|
+
duration: 0.4,
|
|
177
|
+
render: (e, t, n, i) => Ke(e, t, { freq: z, ratio: 2, index: 90, dur: 0.42, gain: i }, n)
|
|
178
|
+
},
|
|
179
|
+
"notification.success": {
|
|
180
|
+
// Ascending major third (C5 → E5) — unmistakably "up" vs the error contour.
|
|
181
|
+
category: "notification",
|
|
182
|
+
gain: 0.2,
|
|
183
|
+
duration: 0.34,
|
|
184
|
+
render: (e, t, n, i) => {
|
|
185
|
+
k(e, t, { freq: U, type: "sine", dur: 0.14, gain: i, attack: 8e-3 }, n), k(e, t, { freq: z, type: "sine", dur: 0.2, gain: i, attack: 8e-3 }, n + 0.11);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"notification.warning": {
|
|
189
|
+
// Double pulse on one note — attention without alarm.
|
|
190
|
+
category: "notification",
|
|
191
|
+
gain: 0.24,
|
|
192
|
+
duration: 0.3,
|
|
193
|
+
render: (e, t, n, i) => {
|
|
194
|
+
k(e, t, { freq: oe, type: "triangle", dur: 0.1, gain: i, attack: 6e-3 }, n), k(e, t, { freq: oe, type: "triangle", dur: 0.1, gain: i, attack: 6e-3 }, n + 0.16);
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
"notification.error": {
|
|
198
|
+
// Descending, darker (G4 → D4, triangle) — never a harsh klaxon.
|
|
199
|
+
category: "notification",
|
|
200
|
+
gain: 0.28,
|
|
201
|
+
duration: 0.42,
|
|
202
|
+
render: (e, t, n, i) => {
|
|
203
|
+
k(e, t, { freq: He, type: "triangle", dur: 0.16, gain: i, attack: 8e-3 }, n), k(e, t, { freq: We, type: "triangle", dur: 0.26, gain: i, attack: 8e-3 }, n + 0.13);
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
// ── hero (disabled by default even when sound is on) ──────────────────────
|
|
207
|
+
"hero.complete": {
|
|
208
|
+
category: "hero",
|
|
209
|
+
gain: 0.4,
|
|
210
|
+
duration: 0.9,
|
|
211
|
+
render: (e, t, n, i) => {
|
|
212
|
+
k(e, t, { freq: U, type: "sine", dur: 0.2, gain: i, attack: 0.01 }, n), k(e, t, { freq: z, type: "sine", dur: 0.2, gain: i, attack: 0.01 }, n + 0.16), k(e, t, { freq: X, type: "sine", dur: 0.4, gain: i, attack: 0.01 }, n + 0.32);
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"hero.milestone": {
|
|
216
|
+
category: "hero",
|
|
217
|
+
gain: 0.5,
|
|
218
|
+
duration: 1.3,
|
|
219
|
+
render: (e, t, n, i) => {
|
|
220
|
+
k(e, t, { freq: U, type: "sine", dur: 0.22, gain: i, attack: 0.01 }, n), k(e, t, { freq: z, type: "sine", dur: 0.22, gain: i, attack: 0.01 }, n + 0.18), k(e, t, { freq: X, type: "sine", dur: 0.22, gain: i, attack: 0.01 }, n + 0.36), k(e, t, { freq: Ue, type: "sine", dur: 0.55, gain: i, attack: 0.01 }, n + 0.54);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}, Ge = 120;
|
|
224
|
+
let B = null, H = null, ye = !1, Le = !1;
|
|
225
|
+
const Te = /* @__PURE__ */ new Map(), se = /* @__PURE__ */ new Set();
|
|
226
|
+
function Je() {
|
|
227
|
+
if (typeof window > "u")
|
|
228
|
+
return !0;
|
|
229
|
+
try {
|
|
230
|
+
if (window.frameElement !== null)
|
|
231
|
+
return !0;
|
|
232
|
+
} catch {
|
|
233
|
+
return !0;
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
return window.self !== window.top;
|
|
237
|
+
} catch {
|
|
238
|
+
return !0;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function Ce() {
|
|
242
|
+
return typeof window > "u" || !window.matchMedia ? !1 : window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
243
|
+
}
|
|
244
|
+
function Ae() {
|
|
245
|
+
if (typeof window > "u")
|
|
246
|
+
return null;
|
|
247
|
+
if (B)
|
|
248
|
+
return B;
|
|
249
|
+
const e = window.AudioContext ?? window.webkitAudioContext;
|
|
250
|
+
if (!e)
|
|
251
|
+
return null;
|
|
252
|
+
try {
|
|
253
|
+
B = new e(), H = B.createGain(), H.gain.value = 1, H.connect(B.destination);
|
|
254
|
+
} catch {
|
|
255
|
+
B = null, H = null;
|
|
256
|
+
}
|
|
257
|
+
return B;
|
|
258
|
+
}
|
|
259
|
+
function Ye() {
|
|
260
|
+
if (ye || typeof window > "u")
|
|
261
|
+
return;
|
|
262
|
+
ye = !0;
|
|
263
|
+
const e = ["pointerdown", "keydown", "touchstart"], t = () => {
|
|
264
|
+
Le = !0;
|
|
265
|
+
const n = Ae();
|
|
266
|
+
n && n.state === "suspended" && n.resume().catch(() => {
|
|
267
|
+
}), n && n.state !== "suspended" && e.forEach((i) => window.removeEventListener(i, t));
|
|
268
|
+
};
|
|
269
|
+
e.forEach((n) => window.addEventListener(n, t, { passive: !0 }));
|
|
270
|
+
}
|
|
271
|
+
function Qe(e) {
|
|
272
|
+
return se.add(e), () => se.delete(e);
|
|
273
|
+
}
|
|
274
|
+
function Xe(e, t) {
|
|
275
|
+
if (typeof document > "u")
|
|
276
|
+
return !1;
|
|
277
|
+
const n = Ie[e];
|
|
278
|
+
if (!n || Je())
|
|
279
|
+
return !1;
|
|
280
|
+
const i = I.value;
|
|
281
|
+
if (!i.enabled || Ce() && !i.prmOverride)
|
|
282
|
+
return !1;
|
|
283
|
+
const o = n.category;
|
|
284
|
+
if (!i.categories[o] || document.hidden && o !== "notification")
|
|
285
|
+
return !1;
|
|
286
|
+
if (!t?.force) {
|
|
287
|
+
const a = Te.get(e) ?? 0;
|
|
288
|
+
if (performance.now() - a < Ge)
|
|
289
|
+
return !1;
|
|
290
|
+
}
|
|
291
|
+
return !0;
|
|
292
|
+
}
|
|
293
|
+
function Ze(e, t) {
|
|
294
|
+
if (!Xe(e, t) || !B && !Le)
|
|
295
|
+
return !1;
|
|
296
|
+
const n = Ae();
|
|
297
|
+
if (!n || !H)
|
|
298
|
+
return !1;
|
|
299
|
+
if (n.state === "suspended")
|
|
300
|
+
return n.resume().catch(() => {
|
|
301
|
+
}), !1;
|
|
302
|
+
const i = Ie[e];
|
|
303
|
+
Te.set(e, performance.now());
|
|
304
|
+
const o = n.currentTime, a = Math.min(0.8, i.gain * I.value.volume);
|
|
305
|
+
try {
|
|
306
|
+
i.render(n, H, o, a);
|
|
307
|
+
} catch {
|
|
308
|
+
return !1;
|
|
309
|
+
}
|
|
310
|
+
return se.forEach((d) => {
|
|
311
|
+
try {
|
|
312
|
+
d();
|
|
313
|
+
} catch {
|
|
314
|
+
}
|
|
315
|
+
}), !0;
|
|
316
|
+
}
|
|
317
|
+
const le = E(!1);
|
|
318
|
+
if (typeof window < "u" && typeof window.matchMedia == "function")
|
|
319
|
+
try {
|
|
320
|
+
const e = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
321
|
+
le.value = e.matches, e.addEventListener?.("change", (t) => {
|
|
322
|
+
le.value = t.matches;
|
|
323
|
+
});
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
function ae(e) {
|
|
327
|
+
I.value.enabled = e, I.value.userSet = !0, e ? Ce() && (I.value.prmOverride = !0) : I.value.prmOverride = !1;
|
|
328
|
+
}
|
|
329
|
+
function et() {
|
|
330
|
+
Ye();
|
|
331
|
+
const e = m({
|
|
332
|
+
get: () => I.value.enabled,
|
|
333
|
+
set: (o) => ae(o)
|
|
334
|
+
}), t = m({
|
|
335
|
+
get: () => I.value.volume,
|
|
336
|
+
set: (o) => {
|
|
337
|
+
I.value.volume = Math.min(0.8, Math.max(0, o));
|
|
338
|
+
}
|
|
339
|
+
}), n = m(() => I.value.hintShown), i = m(
|
|
340
|
+
() => le.value && !I.value.prmOverride
|
|
341
|
+
);
|
|
342
|
+
return {
|
|
343
|
+
play: Ze,
|
|
344
|
+
enabled: e,
|
|
345
|
+
volume: t,
|
|
346
|
+
hintShown: n,
|
|
347
|
+
mutedByReducedMotion: i,
|
|
348
|
+
toggleMute: () => ae(!I.value.enabled),
|
|
349
|
+
setEnabled: (o) => ae(o),
|
|
350
|
+
setVolume: (o) => {
|
|
351
|
+
I.value.volume = Math.min(0.8, Math.max(0, o));
|
|
352
|
+
},
|
|
353
|
+
isCategoryEnabled: (o) => I.value.categories[o],
|
|
354
|
+
setCategory: (o, a) => {
|
|
355
|
+
I.value.categories[o] = a, I.value.userSet = !0;
|
|
356
|
+
},
|
|
357
|
+
markHintShown: () => {
|
|
358
|
+
I.value.hintShown = !0;
|
|
359
|
+
},
|
|
360
|
+
onDidPlay: Qe
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
function de(e, t) {
|
|
6
364
|
return e.visibleIf ? t[e.visibleIf.fieldId] === e.visibleIf.equals : !0;
|
|
7
365
|
}
|
|
8
|
-
function
|
|
366
|
+
function tt(e, t, n) {
|
|
9
367
|
if (e.type === "section-heading" || e.type === "html-block" || e.type === "hidden")
|
|
10
368
|
return;
|
|
11
|
-
const i = typeof t == "string" ? t.trim() : t,
|
|
12
|
-
if (e.required &&
|
|
369
|
+
const i = typeof t == "string" ? t.trim() : t, o = t == null || i === "" || Array.isArray(t) && t.length === 0;
|
|
370
|
+
if (e.required && o)
|
|
13
371
|
return `${e.label} is required`;
|
|
14
|
-
if (
|
|
372
|
+
if (o) return;
|
|
15
373
|
if (e.type === "email" && typeof i == "string" && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i))
|
|
16
374
|
return `${e.label} must be a valid email address`;
|
|
17
|
-
const
|
|
375
|
+
const a = e.validation ?? {};
|
|
18
376
|
if (typeof i == "string") {
|
|
19
|
-
if (
|
|
20
|
-
return `${e.label} must be at least ${
|
|
21
|
-
if (
|
|
22
|
-
return `${e.label} must be at most ${
|
|
23
|
-
if (
|
|
377
|
+
if (a.minLength != null && i.length < a.minLength)
|
|
378
|
+
return `${e.label} must be at least ${a.minLength} characters`;
|
|
379
|
+
if (a.maxLength != null && i.length > a.maxLength)
|
|
380
|
+
return `${e.label} must be at most ${a.maxLength} characters`;
|
|
381
|
+
if (a.regex)
|
|
24
382
|
try {
|
|
25
|
-
if (!new RegExp(
|
|
383
|
+
if (!new RegExp(a.regex).test(i))
|
|
26
384
|
return `${e.label} is invalid`;
|
|
27
385
|
} catch {
|
|
28
386
|
}
|
|
29
387
|
}
|
|
30
388
|
if (typeof t == "number") {
|
|
31
|
-
if (
|
|
32
|
-
return `${e.label} must be at least ${
|
|
33
|
-
if (
|
|
34
|
-
return `${e.label} must be at most ${
|
|
389
|
+
if (a.min != null && t < a.min)
|
|
390
|
+
return `${e.label} must be at least ${a.min}`;
|
|
391
|
+
if (a.max != null && t > a.max)
|
|
392
|
+
return `${e.label} must be at most ${a.max}`;
|
|
35
393
|
}
|
|
36
394
|
if (e.type === "file") {
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
return `${e.label} accepts up to ${
|
|
395
|
+
const d = rt(t), s = n?.maxFiles, l = n?.maxFileSizeBytes, u = a.accept && a.accept.length > 0 ? a.accept : n?.accept;
|
|
396
|
+
if (s != null && d.length > s)
|
|
397
|
+
return `${e.label} accepts up to ${s} file${s === 1 ? "" : "s"}`;
|
|
40
398
|
if (l != null) {
|
|
41
|
-
const r =
|
|
399
|
+
const r = d.find((b) => b.size > l);
|
|
42
400
|
if (r)
|
|
43
|
-
return `${r.name} exceeds the ${
|
|
401
|
+
return `${r.name} exceeds the ${at(l)} limit`;
|
|
44
402
|
}
|
|
45
|
-
if (
|
|
46
|
-
const r =
|
|
403
|
+
if (u && u.length > 0) {
|
|
404
|
+
const r = d.find((b) => !ot(b, u));
|
|
47
405
|
if (r)
|
|
48
|
-
return `${r.name} must be one of: ${
|
|
406
|
+
return `${r.name} must be one of: ${u.join(", ")}`;
|
|
49
407
|
}
|
|
50
408
|
}
|
|
51
409
|
}
|
|
52
|
-
function
|
|
53
|
-
const i = {},
|
|
54
|
-
for (const
|
|
55
|
-
if (
|
|
56
|
-
const
|
|
57
|
-
|
|
410
|
+
function it(e, t, n) {
|
|
411
|
+
const i = {}, o = n ? new Set(n) : null;
|
|
412
|
+
for (const a of e.fields) {
|
|
413
|
+
if (o && !o.has(a.id) || !de(a, t)) continue;
|
|
414
|
+
const d = tt(a, t[a.id], e.attachmentPolicy);
|
|
415
|
+
d && (i[a.id] = d);
|
|
58
416
|
}
|
|
59
417
|
return i;
|
|
60
418
|
}
|
|
61
|
-
function
|
|
419
|
+
function nt(e) {
|
|
62
420
|
return Object.values(e).some((t) => !!t);
|
|
63
421
|
}
|
|
64
|
-
function
|
|
422
|
+
function rt(e) {
|
|
65
423
|
return typeof File > "u" ? [] : e instanceof File ? [e] : Array.isArray(e) ? e.filter((t) => t instanceof File) : [];
|
|
66
424
|
}
|
|
67
|
-
function
|
|
425
|
+
function ot(e, t) {
|
|
68
426
|
const n = e.name.toLowerCase(), i = e.type.toLowerCase();
|
|
69
|
-
return t.some((
|
|
70
|
-
const
|
|
71
|
-
return
|
|
427
|
+
return t.some((o) => {
|
|
428
|
+
const a = o.trim().toLowerCase();
|
|
429
|
+
return a === "" ? !1 : a.startsWith(".") ? n.endsWith(a) : a.endsWith("/*") ? i.startsWith(a.slice(0, -1)) : i === a;
|
|
72
430
|
});
|
|
73
431
|
}
|
|
74
|
-
function
|
|
432
|
+
function at(e) {
|
|
75
433
|
return e < 1024 ? `${e} B` : e < 1024 * 1024 ? `${Math.round(e / 1024)} KB` : `${Math.round(e / (1024 * 1024))} MB`;
|
|
76
434
|
}
|
|
77
|
-
function
|
|
435
|
+
function ge(e) {
|
|
78
436
|
const t = {};
|
|
79
437
|
for (const n of e.fields)
|
|
80
438
|
n.defaultValue !== void 0 ? t[n.id] = n.defaultValue : n.type === "checkbox" ? t[n.id] = !1 : n.type === "multiselect" || n.type === "checkbox-group" ? t[n.id] = [] : t[n.id] = "";
|
|
81
439
|
return t;
|
|
82
440
|
}
|
|
83
|
-
function
|
|
84
|
-
const { definition: t } = e, n =
|
|
441
|
+
function st(e) {
|
|
442
|
+
const { definition: t } = e, n = Ee(ge(t)), i = E({}), o = E({}), a = E(!1), d = E(!1), s = E(null), l = E(0), u = m(() => t.fields), r = m(
|
|
85
443
|
() => t.steps && t.steps.length > 0 ? t.steps : null
|
|
86
|
-
),
|
|
444
|
+
), b = m(() => {
|
|
87
445
|
const y = r.value;
|
|
88
446
|
return y ? y[l.value] ?? null : null;
|
|
89
|
-
}),
|
|
90
|
-
const y =
|
|
447
|
+
}), F = m(() => {
|
|
448
|
+
const y = b.value;
|
|
91
449
|
if (!y) return t.fields;
|
|
92
|
-
const
|
|
93
|
-
return t.fields.filter((
|
|
94
|
-
}),
|
|
450
|
+
const x = new Set(y.fieldIds);
|
|
451
|
+
return t.fields.filter((Y) => x.has(Y.id));
|
|
452
|
+
}), L = m(() => l.value === 0), S = m(() => {
|
|
95
453
|
const y = r.value;
|
|
96
454
|
return !y || l.value >= y.length - 1;
|
|
97
|
-
}),
|
|
98
|
-
() =>
|
|
455
|
+
}), P = m(
|
|
456
|
+
() => F.value.filter((y) => de(y, n))
|
|
99
457
|
);
|
|
100
|
-
function
|
|
101
|
-
n[y] =
|
|
458
|
+
function O(y, x) {
|
|
459
|
+
n[y] = x, i.value[y] && (i.value = { ...i.value, [y]: void 0 });
|
|
102
460
|
}
|
|
103
|
-
function
|
|
104
|
-
|
|
461
|
+
function R(y) {
|
|
462
|
+
o.value = { ...o.value, [y]: !0 };
|
|
105
463
|
}
|
|
106
|
-
function
|
|
107
|
-
const
|
|
464
|
+
function D(y) {
|
|
465
|
+
const x = it(t, n, y);
|
|
108
466
|
if (y) {
|
|
109
|
-
const
|
|
110
|
-
for (const
|
|
111
|
-
|
|
112
|
-
i.value =
|
|
467
|
+
const Y = { ...i.value };
|
|
468
|
+
for (const fe of y)
|
|
469
|
+
Y[fe] = x[fe];
|
|
470
|
+
i.value = Y;
|
|
113
471
|
} else
|
|
114
|
-
i.value =
|
|
115
|
-
return !
|
|
472
|
+
i.value = x;
|
|
473
|
+
return !nt(i.value);
|
|
116
474
|
}
|
|
117
|
-
function
|
|
118
|
-
const y =
|
|
119
|
-
return
|
|
475
|
+
function p() {
|
|
476
|
+
const y = b.value?.fieldIds;
|
|
477
|
+
return D(y);
|
|
120
478
|
}
|
|
121
|
-
function
|
|
122
|
-
return
|
|
479
|
+
function $() {
|
|
480
|
+
return D();
|
|
123
481
|
}
|
|
124
|
-
function
|
|
125
|
-
return !r.value || !
|
|
482
|
+
function q() {
|
|
483
|
+
return !r.value || !p() ? !1 : l.value < r.value.length - 1 ? (l.value++, !0) : !1;
|
|
126
484
|
}
|
|
127
|
-
function
|
|
485
|
+
function h() {
|
|
128
486
|
l.value > 0 && l.value--;
|
|
129
487
|
}
|
|
130
|
-
function
|
|
131
|
-
const y =
|
|
132
|
-
for (const
|
|
133
|
-
delete n[
|
|
134
|
-
Object.assign(n, y), i.value = {},
|
|
488
|
+
function C() {
|
|
489
|
+
const y = ge(t);
|
|
490
|
+
for (const x of Object.keys(n))
|
|
491
|
+
delete n[x];
|
|
492
|
+
Object.assign(n, y), i.value = {}, o.value = {}, a.value = !1, d.value = !1, s.value = null, l.value = 0;
|
|
135
493
|
}
|
|
136
|
-
function
|
|
494
|
+
function A() {
|
|
137
495
|
const y = {};
|
|
138
|
-
for (const
|
|
139
|
-
|
|
496
|
+
for (const x of t.fields)
|
|
497
|
+
x.type === "section-heading" || x.type === "html-block" || de(x, n) && (y[x.id] = n[x.id]);
|
|
140
498
|
return y;
|
|
141
499
|
}
|
|
142
500
|
return {
|
|
143
501
|
values: n,
|
|
144
502
|
errors: i,
|
|
145
|
-
touched:
|
|
146
|
-
submitting:
|
|
147
|
-
submitted:
|
|
148
|
-
submitError:
|
|
149
|
-
fields:
|
|
503
|
+
touched: o,
|
|
504
|
+
submitting: a,
|
|
505
|
+
submitted: d,
|
|
506
|
+
submitError: s,
|
|
507
|
+
fields: u,
|
|
150
508
|
steps: r,
|
|
151
509
|
currentStepIndex: l,
|
|
152
|
-
currentStep:
|
|
153
|
-
currentStepFields:
|
|
154
|
-
isFirstStep:
|
|
155
|
-
isLastStep:
|
|
156
|
-
visibleFields:
|
|
157
|
-
setValue:
|
|
158
|
-
touch:
|
|
159
|
-
validateCurrentScope:
|
|
160
|
-
validateAll:
|
|
161
|
-
next:
|
|
162
|
-
prev:
|
|
163
|
-
reset:
|
|
164
|
-
collectSubmissionValues:
|
|
510
|
+
currentStep: b,
|
|
511
|
+
currentStepFields: F,
|
|
512
|
+
isFirstStep: L,
|
|
513
|
+
isLastStep: S,
|
|
514
|
+
visibleFields: P,
|
|
515
|
+
setValue: O,
|
|
516
|
+
touch: R,
|
|
517
|
+
validateCurrentScope: p,
|
|
518
|
+
validateAll: $,
|
|
519
|
+
next: q,
|
|
520
|
+
prev: h,
|
|
521
|
+
reset: C,
|
|
522
|
+
collectSubmissionValues: A
|
|
165
523
|
};
|
|
166
524
|
}
|
|
167
|
-
async function
|
|
168
|
-
|
|
169
|
-
n
|
|
170
|
-
)}/forms/${encodeURIComponent(i.formId)}/submissions`, a = Object.values(i.values).some(pe);
|
|
171
|
-
let l, h;
|
|
172
|
-
for (let r = 0; r <= s; r++)
|
|
525
|
+
async function lt(e, t = Ve) {
|
|
526
|
+
if (typeof e.text != "function")
|
|
173
527
|
try {
|
|
174
|
-
|
|
528
|
+
return await e.json();
|
|
529
|
+
} catch {
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
const n = ft(e);
|
|
533
|
+
let i;
|
|
534
|
+
try {
|
|
535
|
+
i = (await e.text()).trim();
|
|
536
|
+
} catch (o) {
|
|
537
|
+
throw ht(t, e.status, o);
|
|
538
|
+
}
|
|
539
|
+
if (i === "")
|
|
540
|
+
throw yt(t, e.status);
|
|
541
|
+
if (n && !n.includes("json"))
|
|
542
|
+
throw be(t, e.status, n, i);
|
|
543
|
+
try {
|
|
544
|
+
return JSON.parse(i);
|
|
545
|
+
} catch {
|
|
546
|
+
throw be(t, e.status, n, i);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
async function dt(e, t, n = {}) {
|
|
550
|
+
const i = n.label ?? Ve, o = await lt(e, i);
|
|
551
|
+
if (t(o)) return o;
|
|
552
|
+
throw gt(i, e.status, n.receiptName ?? "submission", o);
|
|
553
|
+
}
|
|
554
|
+
const ut = ["submitted", "accepted", "queued"];
|
|
555
|
+
function ct(e) {
|
|
556
|
+
return J(e) && ne(e.id) && Me(e.status, ut) && pt(e.submittedAt);
|
|
557
|
+
}
|
|
558
|
+
const mt = ["submitted", "processing", "responded"];
|
|
559
|
+
function Wi(e) {
|
|
560
|
+
return J(e) && ne(e.id) && Me(e.status, mt);
|
|
561
|
+
}
|
|
562
|
+
function Gi(e) {
|
|
563
|
+
return J(e) && ne(e.id);
|
|
564
|
+
}
|
|
565
|
+
function Ji(e) {
|
|
566
|
+
return J(e) && e.success === !0;
|
|
567
|
+
}
|
|
568
|
+
function Yi(e) {
|
|
569
|
+
return J(e) && e.success === !0;
|
|
570
|
+
}
|
|
571
|
+
const Ve = "[@duffcloudservices/site-forms]", ie = "We could not confirm your message was received. Please try again, or contact us directly.";
|
|
572
|
+
function ft(e) {
|
|
573
|
+
return typeof e.headers?.get != "function" ? "" : (e.headers.get("content-type") ?? "").toLowerCase();
|
|
574
|
+
}
|
|
575
|
+
function J(e) {
|
|
576
|
+
return typeof e == "object" && e !== null && !Array.isArray(e);
|
|
577
|
+
}
|
|
578
|
+
function ne(e) {
|
|
579
|
+
return typeof e == "string" && e.trim().length > 0;
|
|
580
|
+
}
|
|
581
|
+
function Me(e, t) {
|
|
582
|
+
return typeof e == "string" && t.includes(e);
|
|
583
|
+
}
|
|
584
|
+
function pt(e) {
|
|
585
|
+
return ne(e) && Number.isFinite(Date.parse(e));
|
|
586
|
+
}
|
|
587
|
+
function re(e, t) {
|
|
588
|
+
const n = new Error(e);
|
|
589
|
+
return n.receiptRejected = t, n;
|
|
590
|
+
}
|
|
591
|
+
function ht(e, t, n) {
|
|
592
|
+
const i = n instanceof Error ? n.message : String(n);
|
|
593
|
+
return console.error(
|
|
594
|
+
`${e} Submission could not be confirmed: the server answered ${t} but the response body could not be read (${i}). The submission may or may not have been stored, so it is reported as a failure rather than risk telling the visitor it was sent.`
|
|
595
|
+
), re(ie, !1);
|
|
596
|
+
}
|
|
597
|
+
function yt(e, t) {
|
|
598
|
+
return console.error(
|
|
599
|
+
`${e} Submission NOT confirmed: the server answered ${t} with an empty body. EVERY DCS submission endpoint returns a JSON receipt — including on 204, which is why the old 204 exemption was removed (C-310) — so an empty body means the request was answered by something other than the DCS API (a misrouted POST).`
|
|
600
|
+
), re(ie, !1);
|
|
601
|
+
}
|
|
602
|
+
function be(e, t, n, i) {
|
|
603
|
+
const o = n.includes("html") || /^\s*<(?:!doctype|html)/i.test(i);
|
|
604
|
+
return console.error(
|
|
605
|
+
`${e} Submission NOT stored: the server answered ${t} with a ${n || "bodyless/unknown"} body instead of JSON` + (o ? " — this is an HTML page, so the POST did not reach the DCS API (check the resolved api-base and the host routing for /api/v1/*)." : ".") + ` First 200 bytes: ${i.slice(0, 200)}`
|
|
606
|
+
), re(ie, !1);
|
|
607
|
+
}
|
|
608
|
+
function gt(e, t, n, i) {
|
|
609
|
+
return console.error(
|
|
610
|
+
`${e} Submission NOT confirmed: the server answered ${t} with JSON that is not a valid ${n} receipt. A 2xx and parseable JSON prove only that SOMETHING answered; only the endpoint's receipt proves a row was stored. Received: ${bt(i).slice(0, 200)}`
|
|
611
|
+
), re(ie, !0);
|
|
612
|
+
}
|
|
613
|
+
function bt(e) {
|
|
614
|
+
try {
|
|
615
|
+
return JSON.stringify(e) ?? String(e);
|
|
616
|
+
} catch {
|
|
617
|
+
return String(e);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
async function vt(e) {
|
|
621
|
+
const { apiBase: t, siteSlug: n, payload: i } = e, o = e.retries ?? 1, a = e.fetchImpl ?? fetch, d = t.replace(/\/$/, ""), s = `forms/${encodeURIComponent(i.formId)}/submissions`, l = n.trim(), u = l ? `${d}/sites/${encodeURIComponent(l)}/${s}` : `${d}/${s}`, r = Object.values(i.values).some(Ft);
|
|
622
|
+
let b, F;
|
|
623
|
+
for (let L = 0; L <= o; L++)
|
|
624
|
+
try {
|
|
625
|
+
const S = r ? { method: "POST", redirect: ve, body: wt(i) } : {
|
|
175
626
|
method: "POST",
|
|
627
|
+
redirect: ve,
|
|
176
628
|
headers: { "Content-Type": "application/json" },
|
|
177
629
|
body: JSON.stringify(i)
|
|
178
|
-
},
|
|
179
|
-
if (
|
|
180
|
-
|
|
181
|
-
|
|
630
|
+
}, P = await a(u, S);
|
|
631
|
+
if (F = P.status, P.ok) {
|
|
632
|
+
let O;
|
|
633
|
+
try {
|
|
634
|
+
O = await dt(P, ct, {
|
|
635
|
+
receiptName: "managed-form submission"
|
|
636
|
+
});
|
|
637
|
+
} catch (R) {
|
|
638
|
+
const D = !!R?.receiptRejected;
|
|
639
|
+
throw {
|
|
640
|
+
payload: i,
|
|
641
|
+
status: P.status,
|
|
642
|
+
error: R,
|
|
643
|
+
// `nonJsonResponse` keeps its original literal meaning (the body was
|
|
644
|
+
// not JSON at all); a JSON body that failed the receipt predicate is
|
|
645
|
+
// reported through the additive `unconfirmedReceipt` flag instead.
|
|
646
|
+
nonJsonResponse: !D,
|
|
647
|
+
unconfirmedReceipt: D
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
return { payload: i, response: O };
|
|
182
651
|
}
|
|
183
|
-
if (
|
|
184
|
-
const
|
|
652
|
+
if (P.status < 500) {
|
|
653
|
+
const O = await St(P);
|
|
185
654
|
throw {
|
|
186
655
|
payload: i,
|
|
187
|
-
status:
|
|
188
|
-
error: new Error(`Submission failed (${
|
|
656
|
+
status: P.status,
|
|
657
|
+
error: new Error(`Submission failed (${P.status}): ${O}`)
|
|
189
658
|
};
|
|
190
659
|
}
|
|
191
|
-
|
|
192
|
-
} catch (
|
|
193
|
-
if (
|
|
194
|
-
throw
|
|
195
|
-
|
|
660
|
+
b = new Error(`Server error ${P.status}`);
|
|
661
|
+
} catch (S) {
|
|
662
|
+
if (S && typeof S == "object" && "payload" in S && "error" in S)
|
|
663
|
+
throw S;
|
|
664
|
+
b = S;
|
|
196
665
|
}
|
|
197
666
|
throw {
|
|
198
667
|
payload: i,
|
|
199
|
-
status:
|
|
200
|
-
error:
|
|
668
|
+
status: F,
|
|
669
|
+
error: b ?? new Error("Submission failed")
|
|
201
670
|
};
|
|
202
671
|
}
|
|
203
|
-
function
|
|
672
|
+
function wt(e) {
|
|
204
673
|
const t = new FormData();
|
|
205
674
|
t.append("formId", e.formId), e.captchaToken && t.append("captchaToken", e.captchaToken);
|
|
206
675
|
for (const [n, i] of Object.entries(e.values))
|
|
207
676
|
if (i != null)
|
|
208
677
|
if (typeof File < "u" && i instanceof File)
|
|
209
678
|
t.append(`values[${n}]`, i);
|
|
210
|
-
else if (Array.isArray(i) && i.some((
|
|
211
|
-
for (const
|
|
212
|
-
typeof File < "u" &&
|
|
679
|
+
else if (Array.isArray(i) && i.some((o) => typeof File < "u" && o instanceof File))
|
|
680
|
+
for (const o of i)
|
|
681
|
+
typeof File < "u" && o instanceof File && t.append(`values[${n}][]`, o);
|
|
213
682
|
else if (Array.isArray(i))
|
|
214
|
-
for (const
|
|
683
|
+
for (const o of i) t.append(`values[${n}][]`, String(o));
|
|
215
684
|
else
|
|
216
685
|
t.append(`values[${n}]`, String(i));
|
|
217
686
|
return t;
|
|
218
687
|
}
|
|
219
|
-
function
|
|
688
|
+
function Ft(e) {
|
|
220
689
|
return typeof File > "u" ? !1 : e instanceof File ? !0 : Array.isArray(e) && e.some((t) => t instanceof File);
|
|
221
690
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return await e.json();
|
|
225
|
-
} catch {
|
|
226
|
-
return null;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
async function ye(e) {
|
|
691
|
+
const ve = "error";
|
|
692
|
+
async function St(e) {
|
|
230
693
|
try {
|
|
231
694
|
return await e.text();
|
|
232
695
|
} catch {
|
|
233
696
|
return "";
|
|
234
697
|
}
|
|
235
698
|
}
|
|
236
|
-
const be = "http://json-schema.org/draft-07/schema#", ge = "https://duffcloudservices.com/schemas/form-definition.schema.json", ve = "PortalFormDefinition", Fe = "object", xe = "Portable form definition. This schema is the source of truth for\nboth the portal CRUD APIs and the `.dcs/forms/<formId>.yaml`\nfiles consumed by customer-site builds via `<DcsForm/>`.\n", $e = ["formId", "submission", "fields"], we = { formId: { type: "string", description: "Kebab-case identifier, unique per site.", pattern: "^[a-z0-9][a-z0-9-]*$", minLength: 1, maxLength: 80, example: "contact" }, formKind: { $ref: "#/definitions/PortalFormKind" }, submitLabel: { type: "string", description: 'Label for the submit button. Defaults to "Send" client-side.', maxLength: 80, example: "Send message" }, successMessage: { type: "string", description: "Confirmation message shown after a successful submission.", maxLength: 2e3, example: "Thanks — we'll be in touch shortly." }, submission: { $ref: "#/definitions/PortalFormSubmissionConfig" }, attachmentPolicy: { $ref: "#/definitions/PortalFormAttachmentPolicy" }, steps: { type: "array", description: "Optional multi-step grouping. When omitted, fields render as a single page.", items: { $ref: "#/definitions/PortalFormStep" } }, fields: { type: "array", description: "Flat list of all fields in the form. When `steps` is present,\nevery field referenced from a step's `fieldIds` must exist here.\n", items: { $ref: "#/definitions/PortalFormField" } }, version: { type: "integer", minimum: 1, description: "Monotonically increasing version, bumped on each save." }, createdAt: { type: "string", format: "date-time", description: "Form creation timestamp." }, updatedAt: { type: "string", format: "date-time", description: "Last modification timestamp." } }, ke = /* @__PURE__ */ JSON.parse('{"PortalFormKind":{"type":"string","description":"High-level form kind used by the visual page editor and submission\\npipeline. `freeform` preserves fully editable questionnaires; the\\nstandard values provide predictable field roles and routing for common\\nsite forms.\\n","enum":["freeform","contact","revenue-contractor","resume-submission"],"default":"freeform"},"PortalFormFieldRole":{"type":"string","description":"Semantic role for a field inside a standard form. Free-form forms may\\nomit roles or use `custom`; standard forms use roles so submissions can\\nbe surfaced consistently as contact messages, notifications, revenue\\ncontractor inquiries, or resume submissions without locking the editor\\nout of label/help-text changes.\\n","enum":["contact-name","contact-email","contact-phone","contact-company","subject","message","summary","image-attachments","resume","consent","custom"]},"PortalFormAttachmentPolicy":{"type":"object","description":"Attachment expectations for standard forms. For\\n`revenue-contractor`, image attachments are expected so contractors can\\ninclude project photos. For `resume-submission`, the resume field\\nshould accept document uploads. Free-form questionnaires can omit this.\\n","properties":{"expected":{"type":"boolean","default":false,"description":"Whether the standard flow should prompt for attachments."},"required":{"type":"boolean","default":false,"description":"Whether at least one attachment is required."},"maxFiles":{"type":"integer","minimum":1,"maximum":20,"description":"Maximum number of files accepted.","example":5},"maxFileSizeBytes":{"type":"integer","minimum":1,"description":"Maximum size per file in bytes.","example":10485760},"accept":{"type":"array","description":"Accepted MIME types or extensions (for example `image/*`).","items":{"type":"string"}}}},"PublicSiteFormContact":{"type":"object","description":"Normalized contact identity supplied with a public form submission.","properties":{"name":{"type":"string","maxLength":160},"email":{"type":"string","format":"email","maxLength":255},"phone":{"type":"string","maxLength":32},"company":{"type":"string","maxLength":160}}},"PublicSiteFormAttachment":{"type":"object","description":"Metadata for an attachment associated with a public form submission.","required":["fileName"],"properties":{"fileName":{"type":"string","maxLength":255},"contentType":{"type":"string","maxLength":120},"sizeBytes":{"type":"integer","minimum":0},"storageUrl":{"type":"string","format":"uri","description":"Internal or pre-uploaded storage URL when the binary was uploaded separately."}}},"PublicSiteFormSubmissionRequest":{"type":"object","description":"JSON request for public managed-form submissions.","required":["values"],"properties":{"formKind":{"$ref":"#/definitions/PortalFormKind"},"pageSlug":{"type":"string","description":"Optional visual-editor page slug where the form was rendered."},"contact":{"$ref":"#/definitions/PublicSiteFormContact"},"subject":{"type":"string","maxLength":200,"description":"Contact subject or inquiry title."},"summary":{"type":"string","maxLength":4000,"description":"Project, request, or applicant summary for standard flows."},"message":{"type":"string","maxLength":4000,"description":"Free-text message supplied by the submitter."},"values":{"type":"object","additionalProperties":true,"description":"Field id to submitted value map for the attached PortalFormDefinition."},"attachments":{"type":"array","description":"Attachment metadata for JSON submissions.","items":{"$ref":"#/definitions/PublicSiteFormAttachment"}},"source":{"type":"string","maxLength":120,"description":"Capture source such as `site-contact-page` or `visual-page-editor`."},"consent":{"type":"boolean","description":"Whether the submitter consented to follow-up."}}},"PublicSiteFormMultipartSubmissionRequest":{"type":"object","description":"Multipart request for public managed-form submissions with binary uploads.","properties":{"formKind":{"$ref":"#/definitions/PortalFormKind"},"pageSlug":{"type":"string"},"values":{"type":"string","description":"JSON-encoded field id to submitted value map."},"name":{"type":"string","maxLength":160},"email":{"type":"string","format":"email","maxLength":255},"phone":{"type":"string","maxLength":32},"company":{"type":"string","maxLength":160},"subject":{"type":"string","maxLength":200},"summary":{"type":"string","maxLength":4000},"message":{"type":"string","maxLength":4000},"attachments":{"type":"array","description":"Image or supporting files for standard form submissions.","items":{"type":"string","format":"binary"}},"resume":{"type":"string","format":"binary","description":"Resume document for `resume-submission` standard forms."},"source":{"type":"string","maxLength":120},"consent":{"type":"boolean"}}},"PublicSiteFormSubmissionResponse":{"type":"object","required":["id","status","submittedAt"],"properties":{"id":{"type":"string","description":"Unique submission identifier."},"status":{"type":"string","enum":["submitted","accepted","queued"]},"submittedAt":{"type":"string","format":"date-time"},"message":{"type":"string","description":"Friendly acknowledgement shown to the submitter."},"contactMessageId":{"type":"string","nullable":true,"description":"Future portal contact-message identifier when surfaced in the portal."},"notificationQueued":{"type":"boolean","description":"Whether a portal notification/contact-message handoff was queued."}}},"PortalFormFieldType":{"type":"string","description":"Field type controlling input rendering and validation. Includes\\nlayout-only types (`section-heading`, `html-block`) that render\\ndecorative content rather than capturing values, and `hidden`\\nfor prefilled values not displayed to the user.\\n","enum":["text","email","tel","textarea","select","multiselect","radio","checkbox","checkbox-group","date","file","hidden","section-heading","html-block"]},"PortalFormFieldWidth":{"type":"string","description":"Layout hint for the field within its row.","enum":["full","half","third"]},"PortalFormFieldOption":{"type":"object","description":"A single option for select / radio / checkbox-group fields.","required":["value","label"],"properties":{"value":{"type":"string","description":"Submitted value for this option."},"label":{"type":"string","description":"Human-readable label shown to the user."}}},"PortalFormFieldValidation":{"type":"object","description":"Optional validation rules applied to a field\'s value.","properties":{"regex":{"type":"string","description":"ECMAScript-compatible pattern the value must match."},"minLength":{"type":"integer","minimum":0,"description":"Minimum string length (text-like fields only)."},"maxLength":{"type":"integer","minimum":0,"description":"Maximum string length (text-like fields only)."},"min":{"type":"number","description":"Minimum numeric / date value."},"max":{"type":"number","description":"Maximum numeric / date value."},"accept":{"type":"array","description":"Accepted MIME types or file extensions for `file` fields.","items":{"type":"string"}}}},"PortalFormFieldVisibleIf":{"type":"object","description":"Single-predicate visibility rule. The field is shown only when\\nthe referenced sibling field\'s value equals `equals`. Future\\nrevisions may extend this with AND / OR composition; clients\\nshould treat unknown extra properties as opaque.\\n","required":["fieldId","equals"],"properties":{"fieldId":{"type":"string","description":"ID of the sibling field whose value gates visibility."},"equals":{"description":"Value (string, number, or boolean) the sibling field must equal.","oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}}},"PortalFormField":{"type":"object","description":"A single field within a form definition.","required":["id","type","label"],"properties":{"id":{"type":"string","description":"Kebab-case identifier, unique within the form.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80},"type":{"$ref":"#/definitions/PortalFormFieldType"},"role":{"$ref":"#/definitions/PortalFormFieldRole"},"label":{"type":"string","description":"Human-readable label rendered above the input.","minLength":1,"maxLength":200},"helpText":{"type":"string","description":"Optional helper / description text shown beneath the label.","maxLength":500},"placeholder":{"type":"string","description":"Optional placeholder shown inside empty inputs.","maxLength":200},"defaultValue":{"description":"Optional default value (string, number, boolean, or array of strings).","oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":"string"}}]},"required":{"type":"boolean","default":false,"description":"Whether the field must be supplied to submit the form."},"width":{"allOf":[{"$ref":"#/definitions/PortalFormFieldWidth"}],"default":"full"},"options":{"type":"array","description":"Options for `select`, `multiselect`, `radio`, `checkbox-group` fields.","items":{"$ref":"#/definitions/PortalFormFieldOption"}},"validation":{"$ref":"#/definitions/PortalFormFieldValidation"},"visibleIf":{"$ref":"#/definitions/PortalFormFieldVisibleIf"},"phi":{"type":"boolean","default":false,"description":"Marks the field as collecting Protected Health Information.\\nWhen true the value must never appear in notification emails\\nor logs and the owning site must be in the Medical category\\n(see `compliance.instructions.md`).\\n"},"html":{"type":"string","description":"Sanitized HTML body for `html-block` fields. Ignored for\\nother field types.\\n","maxLength":10000}}},"PortalFormStep":{"type":"object","description":"Optional grouping for multi-step (wizard-style) forms such as\\nthe KT Braun estate-planning questionnaires. When `steps` is\\nomitted on a form, all fields render as a single page.\\n","required":["id","title","fieldIds"],"properties":{"id":{"type":"string","description":"Kebab-case step identifier, unique within the form.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80},"title":{"type":"string","description":"Step title shown in the wizard header.","minLength":1,"maxLength":200},"description":{"type":"string","description":"Optional descriptive text shown below the step title.","maxLength":1000},"fieldIds":{"type":"array","description":"Ordered list of field IDs that belong to this step.","items":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$"}}}},"PortalFormSubmissionLeadConfig":{"type":"object","required":["kind"],"description":"Routes submissions into the existing PortalLeads pipeline.","properties":{"kind":{"type":"string","enum":["lead"]},"category":{"type":"string","description":"Service category id used to route the lead."}}},"PortalFormSubmissionEmailConfig":{"type":"object","required":["kind","to"],"description":"Routes submissions as a notification email to the listed recipients.","properties":{"kind":{"type":"string","enum":["email"]},"to":{"type":"array","minItems":1,"items":{"type":"string","format":"email"},"description":"Recipient email addresses."},"subjectTemplate":{"type":"string","description":"Optional subject-line template. Submitted values are intentionally\\nnot interpolated into the subject line for compliance reasons.\\n","maxLength":200}}},"PortalFormSubmissionWebhookConfig":{"type":"object","required":["kind","url"],"description":"Posts the submission JSON to a third-party webhook.","properties":{"kind":{"type":"string","enum":["webhook"]},"url":{"type":"string","format":"uri","description":"HTTPS endpoint receiving the signed POST."},"signingSecretRef":{"type":"string","description":"Name of the Key Vault secret used to HMAC-sign the request.\\nThe secret value is never returned in API responses.\\n"}}},"PortalFormSubmissionConfig":{"description":"Discriminated union of submission destinations. Exactly one of\\n`lead`, `email`, or `webhook` shapes is used based on `kind`.\\n","oneOf":[{"$ref":"#/definitions/PortalFormSubmissionLeadConfig"},{"$ref":"#/definitions/PortalFormSubmissionEmailConfig"},{"$ref":"#/definitions/PortalFormSubmissionWebhookConfig"}],"discriminator":{"propertyName":"kind","mapping":{"lead":"#/definitions/PortalFormSubmissionLeadConfig","email":"#/definitions/PortalFormSubmissionEmailConfig","webhook":"#/definitions/PortalFormSubmissionWebhookConfig"}}},"PortalFormSummary":{"type":"object","description":"List-row projection of a form definition.","required":["formId","fieldCount"],"properties":{"formId":{"type":"string","description":"Kebab-case identifier.","pattern":"^[a-z0-9][a-z0-9-]*$","example":"contact"},"formKind":{"$ref":"#/definitions/PortalFormKind"},"fieldCount":{"type":"integer","minimum":0,"description":"Number of input-bearing fields in the form.","example":4},"attachedPageSlugs":{"type":"array","description":"Slugs of pages that currently reference this form via `formId`.","items":{"type":"string"}},"submissionKind":{"type":"string","enum":["lead","email","webhook"],"description":"Submission destination kind."},"lastUpdated":{"type":"string","format":"date-time","description":"Last modification timestamp."}}},"PortalCreateFormRequest":{"type":"object","description":"Payload for creating a new form definition.","required":["formId","submission","fields"],"properties":{"formId":{"type":"string","description":"Kebab-case identifier, unique per site.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submitLabel":{"type":"string","maxLength":80},"successMessage":{"type":"string","maxLength":2000},"submission":{"$ref":"#/definitions/PortalFormSubmissionConfig"},"attachmentPolicy":{"$ref":"#/definitions/PortalFormAttachmentPolicy"},"steps":{"type":"array","items":{"$ref":"#/definitions/PortalFormStep"}},"fields":{"type":"array","items":{"$ref":"#/definitions/PortalFormField"}}}},"PortalUpdateFormRequest":{"type":"object","description":"Payload for updating an existing form definition. The `formId`\\nis taken from the URL; supplying it in the body is optional and,\\nif present, must match the path.\\n","properties":{"formId":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80,"description":"Optional echo of the path formId; must match if provided."},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submitLabel":{"type":"string","maxLength":80},"successMessage":{"type":"string","maxLength":2000},"submission":{"$ref":"#/definitions/PortalFormSubmissionConfig"},"attachmentPolicy":{"$ref":"#/definitions/PortalFormAttachmentPolicy"},"steps":{"type":"array","items":{"$ref":"#/definitions/PortalFormStep"}},"fields":{"type":"array","items":{"$ref":"#/definitions/PortalFormField"}},"expectedVersion":{"type":"integer","minimum":1,"description":"Optional optimistic-concurrency token. When supplied, the\\nupdate is rejected with 409 if the stored form\'s `version`\\nno longer matches.\\n"}}},"PortalDuplicateFormRequest":{"type":"object","description":"Payload for cloning an existing form under a new formId.","required":["formId"],"properties":{"formId":{"type":"string","description":"Target kebab-case formId for the cloned form.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80}}},"PortalFormResponse":{"type":"object","description":"Full form definition response.","required":["form"],"properties":{"form":{"$ref":"#/definitions/PortalFormDefinition"},"attachedPageSlugs":{"type":"array","description":"Slugs of pages that currently reference this form via `formId`.","items":{"type":"string"}}}},"PortalFormListResponse":{"type":"object","required":["forms","totalCount"],"properties":{"forms":{"type":"array","items":{"$ref":"#/definitions/PortalFormSummary"}},"totalCount":{"type":"integer","minimum":0,"description":"Total number of forms matching the query.","example":3}}},"PortalFormSubmission":{"type":"object","description":"A single recorded submission against a managed form. PHI fields are\\nreplaced with `[REDACTED]` for Medical-category sites, in which case\\n`redactedForPhi` is true.\\n","required":["id","formId","siteSlug","submittedAt","source","values","redactedForPhi"],"properties":{"id":{"type":"string","description":"Unique submission row key (reverse-chronological)."},"formId":{"type":"string"},"siteSlug":{"type":"string"},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submittedAt":{"type":"string","format":"date-time"},"source":{"type":"string","description":"Capture channel (e.g. `web`, `import`)."},"values":{"type":"object","additionalProperties":true,"description":"Field id → submitted value map. PHI values are redacted."},"attachments":{"type":"array","description":"Attachment metadata captured with the submission.","items":{"$ref":"#/definitions/PublicSiteFormAttachment"}},"leadId":{"type":"string","nullable":true,"description":"Cross-reference to the lead row created by the legacy capture flow."},"contactMessageId":{"type":"string","nullable":true,"description":"Future portal contact-message identifier when surfaced in the portal."},"redactedForPhi":{"type":"boolean","description":"True when one or more values were replaced with the PHI placeholder."},"remoteIp":{"type":"string","nullable":true},"userAgent":{"type":"string","nullable":true}}},"PortalFormSubmissionSummary":{"type":"object","description":"List-view representation of a submission.","required":["id","formId","submittedAt","redactedForPhi","summary"],"properties":{"id":{"type":"string"},"formId":{"type":"string"},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submittedAt":{"type":"string","format":"date-time"},"redactedForPhi":{"type":"boolean"},"summary":{"type":"string","description":"Short single-line preview suitable for the portal list view."}}},"PortalFormSubmissionListResponse":{"type":"object","required":["submissions"],"properties":{"submissions":{"type":"array","items":{"$ref":"#/definitions/PortalFormSubmissionSummary"}}}}}'), Se = {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
699
|
+
const ue = /* @__PURE__ */ new Map();
|
|
700
|
+
function Qi() {
|
|
701
|
+
ue.clear();
|
|
702
|
+
}
|
|
703
|
+
async function $t(e) {
|
|
704
|
+
const t = (e.apiBase ?? "").replace(/\/$/, ""), n = (e.siteSlug ?? "").trim(), i = n ? `${t}/sites/${encodeURIComponent(n)}/forms/compliance` : `${t}/forms/compliance`, o = `${t}|${n}`, a = ue.get(o);
|
|
705
|
+
if (a) return a;
|
|
706
|
+
const d = e.fetchImpl ?? (typeof fetch == "function" ? fetch : void 0);
|
|
707
|
+
if (!d) return !1;
|
|
708
|
+
const s = (async () => {
|
|
709
|
+
try {
|
|
710
|
+
const l = await d(i, { method: "GET" });
|
|
711
|
+
return l.ok ? (await l.json())?.siteHandlesPhi === !0 : !1;
|
|
712
|
+
} catch {
|
|
713
|
+
return !1;
|
|
714
|
+
}
|
|
715
|
+
})();
|
|
716
|
+
return ue.set(o, s), s;
|
|
717
|
+
}
|
|
718
|
+
const we = {
|
|
719
|
+
lead: "Please don't include personal health details.",
|
|
720
|
+
detail: "A general description of what you need is enough — we'll go over anything specific with you directly."
|
|
721
|
+
}, xt = "http://json-schema.org/draft-07/schema#", kt = "https://duffcloudservices.com/schemas/form-definition.schema.json", Pt = "PortalFormDefinition", qt = "object", It = "Portable form definition. This schema is the source of truth for\nboth the portal CRUD APIs and the `.dcs/forms/<formId>.yaml`\nfiles consumed by customer-site builds via `<DcsForm/>`.\n", Lt = ["formId", "submission", "fields"], Tt = { formId: { type: "string", description: "Kebab-case identifier, unique per site.", pattern: "^[a-z0-9][a-z0-9-]*$", minLength: 1, maxLength: 80, example: "contact" }, formKind: { $ref: "#/definitions/PortalFormKind" }, submitLabel: { type: "string", description: 'Label for the submit button. Defaults to "Send" client-side.', maxLength: 80, example: "Send message" }, successMessage: { type: "string", description: "Confirmation message shown after a successful submission.", maxLength: 2e3, example: "Thanks — we'll be in touch shortly." }, submission: { $ref: "#/definitions/PortalFormSubmissionConfig" }, attachmentPolicy: { $ref: "#/definitions/PortalFormAttachmentPolicy" }, steps: { type: "array", description: "Optional multi-step grouping. When omitted, fields render as a single page.", items: { $ref: "#/definitions/PortalFormStep" } }, fields: { type: "array", description: "Flat list of all fields in the form. When `steps` is present,\nevery field referenced from a step's `fieldIds` must exist here.\n", items: { $ref: "#/definitions/PortalFormField" } }, version: { type: "integer", minimum: 1, description: "Monotonically increasing version, bumped on each save." }, createdAt: { type: "string", format: "date-time", description: "Form creation timestamp." }, updatedAt: { type: "string", format: "date-time", description: "Last modification timestamp." } }, Ct = /* @__PURE__ */ JSON.parse('{"PortalFormKind":{"type":"string","description":"High-level form kind used by the visual page editor and submission\\npipeline. `freeform` preserves fully editable questionnaires; the\\nstandard values provide predictable field roles and routing for common\\nsite forms.\\n","enum":["freeform","contact","revenue-contractor","resume-submission"],"default":"freeform"},"PortalFormFieldRole":{"type":"string","description":"Semantic role for a field inside a standard form. Free-form forms may\\nomit roles or use `custom`; standard forms use roles so submissions can\\nbe surfaced consistently as contact messages, notifications, revenue\\ncontractor inquiries, or resume submissions without locking the editor\\nout of label/help-text changes.\\n","enum":["contact-name","contact-email","contact-phone","contact-company","subject","message","summary","image-attachments","resume","consent","custom"]},"PortalFormAttachmentPolicy":{"type":"object","description":"Attachment expectations for standard forms. For\\n`revenue-contractor`, image attachments are expected so contractors can\\ninclude project photos. For `resume-submission`, the resume field\\nshould accept document uploads. Free-form questionnaires can omit this.\\n","properties":{"expected":{"type":"boolean","default":false,"description":"Whether the standard flow should prompt for attachments."},"required":{"type":"boolean","default":false,"description":"Whether at least one attachment is required."},"maxFiles":{"type":"integer","minimum":1,"maximum":20,"description":"Maximum number of files accepted.","example":5},"maxFileSizeBytes":{"type":"integer","minimum":1,"description":"Maximum size per file in bytes.","example":10485760},"accept":{"type":"array","description":"Accepted MIME types or extensions (for example `image/*`).","items":{"type":"string"}}}},"PublicSiteFormContact":{"type":"object","description":"Normalized contact identity supplied with a public form submission.","properties":{"name":{"type":"string","maxLength":160},"email":{"type":"string","format":"email","maxLength":255},"phone":{"type":"string","maxLength":32},"company":{"type":"string","maxLength":160}}},"PublicSiteFormAttachment":{"type":"object","description":"Metadata for an attachment associated with a public form submission.","required":["fileName"],"properties":{"fileName":{"type":"string","maxLength":255},"contentType":{"type":"string","maxLength":120},"sizeBytes":{"type":"integer","minimum":0},"storageUrl":{"type":"string","format":"uri","description":"Internal or pre-uploaded storage URL when the binary was uploaded separately."}}},"PublicSiteFormSubmissionRequest":{"type":"object","description":"JSON request for public managed-form submissions.","required":["values"],"properties":{"formKind":{"$ref":"#/definitions/PortalFormKind"},"pageSlug":{"type":"string","description":"Optional visual-editor page slug where the form was rendered."},"contact":{"$ref":"#/definitions/PublicSiteFormContact"},"subject":{"type":"string","maxLength":200,"description":"Contact subject or inquiry title."},"summary":{"type":"string","maxLength":4000,"description":"Project, request, or applicant summary for standard flows."},"message":{"type":"string","maxLength":4000,"description":"Free-text message supplied by the submitter."},"values":{"type":"object","additionalProperties":true,"description":"Field id to submitted value map for the attached PortalFormDefinition."},"attachments":{"type":"array","description":"Attachment metadata for JSON submissions.","items":{"$ref":"#/definitions/PublicSiteFormAttachment"}},"source":{"type":"string","maxLength":120,"description":"Capture source such as `site-contact-page` or `visual-page-editor`."},"consent":{"type":"boolean","description":"Whether the submitter consented to follow-up."}}},"PublicSiteFormMultipartSubmissionRequest":{"type":"object","description":"Multipart request for public managed-form submissions with binary uploads.","properties":{"formKind":{"$ref":"#/definitions/PortalFormKind"},"pageSlug":{"type":"string"},"values":{"type":"string","description":"JSON-encoded field id to submitted value map."},"name":{"type":"string","maxLength":160},"email":{"type":"string","format":"email","maxLength":255},"phone":{"type":"string","maxLength":32},"company":{"type":"string","maxLength":160},"subject":{"type":"string","maxLength":200},"summary":{"type":"string","maxLength":4000},"message":{"type":"string","maxLength":4000},"attachments":{"type":"array","description":"Image or supporting files for standard form submissions.","items":{"type":"string","format":"binary"}},"resume":{"type":"string","format":"binary","description":"Resume document for `resume-submission` standard forms."},"source":{"type":"string","maxLength":120},"consent":{"type":"boolean"}}},"PublicSiteFormSubmissionResponse":{"type":"object","required":["id","status","submittedAt"],"properties":{"id":{"type":"string","description":"Unique submission identifier."},"status":{"type":"string","enum":["submitted","accepted","queued"]},"submittedAt":{"type":"string","format":"date-time"},"message":{"type":"string","description":"Friendly acknowledgement shown to the submitter."},"contactMessageId":{"type":"string","nullable":true,"description":"Future portal contact-message identifier when surfaced in the portal."},"notificationQueued":{"type":"boolean","description":"Whether a portal notification/contact-message handoff was queued."}}},"PortalFormFieldType":{"type":"string","description":"Field type controlling input rendering and validation. Includes\\nlayout-only types (`section-heading`, `html-block`) that render\\ndecorative content rather than capturing values, and `hidden`\\nfor prefilled values not displayed to the user.\\n","enum":["text","email","tel","textarea","select","multiselect","radio","checkbox","checkbox-group","date","file","hidden","section-heading","html-block"]},"PortalFormFieldWidth":{"type":"string","description":"Layout hint for the field within its row.","enum":["full","half","third"]},"PortalFormFieldOption":{"type":"object","description":"A single option for select / radio / checkbox-group fields.","required":["value","label"],"properties":{"value":{"type":"string","description":"Submitted value for this option."},"label":{"type":"string","description":"Human-readable label shown to the user."}}},"PortalFormFieldValidation":{"type":"object","description":"Optional validation rules applied to a field\'s value.","properties":{"regex":{"type":"string","description":"ECMAScript-compatible pattern the value must match."},"minLength":{"type":"integer","minimum":0,"description":"Minimum string length (text-like fields only)."},"maxLength":{"type":"integer","minimum":0,"description":"Maximum string length (text-like fields only)."},"min":{"type":"number","description":"Minimum numeric / date value."},"max":{"type":"number","description":"Maximum numeric / date value."},"accept":{"type":"array","description":"Accepted MIME types or file extensions for `file` fields.","items":{"type":"string"}}}},"PortalFormFieldVisibleIf":{"type":"object","description":"Single-predicate visibility rule. The field is shown only when\\nthe referenced sibling field\'s value equals `equals`. Future\\nrevisions may extend this with AND / OR composition; clients\\nshould treat unknown extra properties as opaque.\\n","required":["fieldId","equals"],"properties":{"fieldId":{"type":"string","description":"ID of the sibling field whose value gates visibility."},"equals":{"description":"Value (string, number, or boolean) the sibling field must equal.","oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"}]}}},"PortalFormField":{"type":"object","description":"A single field within a form definition.","required":["id","type","label"],"properties":{"id":{"type":"string","description":"Kebab-case identifier, unique within the form.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80},"type":{"$ref":"#/definitions/PortalFormFieldType"},"role":{"$ref":"#/definitions/PortalFormFieldRole"},"label":{"type":"string","description":"Human-readable label rendered above the input.","minLength":1,"maxLength":200},"helpText":{"type":"string","description":"Optional helper / description text shown beneath the label.","maxLength":500},"placeholder":{"type":"string","description":"Optional placeholder shown inside empty inputs.","maxLength":200},"defaultValue":{"description":"Optional default value (string, number, boolean, or array of strings).","oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":"string"}}]},"required":{"type":"boolean","default":false,"description":"Whether the field must be supplied to submit the form."},"width":{"allOf":[{"$ref":"#/definitions/PortalFormFieldWidth"}],"default":"full"},"options":{"type":"array","description":"Options for `select`, `multiselect`, `radio`, `checkbox-group` fields.","items":{"$ref":"#/definitions/PortalFormFieldOption"}},"validation":{"$ref":"#/definitions/PortalFormFieldValidation"},"visibleIf":{"$ref":"#/definitions/PortalFormFieldVisibleIf"},"phi":{"type":"boolean","default":false,"description":"Marks the field as collecting Protected Health Information.\\nWhen true the value must never appear in notification emails\\nor logs and the owning site must be in the Medical category\\n(see `compliance.instructions.md`).\\n"},"html":{"type":"string","description":"Sanitized HTML body for `html-block` fields. Ignored for\\nother field types.\\n","maxLength":10000}}},"PortalFormStep":{"type":"object","description":"Optional grouping for multi-step (wizard-style) forms such as\\nthe KT Braun estate-planning questionnaires. When `steps` is\\nomitted on a form, all fields render as a single page.\\n","required":["id","title","fieldIds"],"properties":{"id":{"type":"string","description":"Kebab-case step identifier, unique within the form.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80},"title":{"type":"string","description":"Step title shown in the wizard header.","minLength":1,"maxLength":200},"description":{"type":"string","description":"Optional descriptive text shown below the step title.","maxLength":1000},"fieldIds":{"type":"array","description":"Ordered list of field IDs that belong to this step.","items":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$"}}}},"PortalFormSubmissionLeadConfig":{"type":"object","required":["kind"],"description":"Routes submissions into the existing PortalLeads pipeline.","properties":{"kind":{"type":"string","enum":["lead"]},"category":{"type":"string","description":"Service category id used to route the lead."}}},"PortalFormSubmissionEmailConfig":{"type":"object","required":["kind","to"],"description":"Routes submissions as a notification email to the listed recipients.","properties":{"kind":{"type":"string","enum":["email"]},"to":{"type":"array","minItems":1,"items":{"type":"string","format":"email"},"description":"Recipient email addresses."},"subjectTemplate":{"type":"string","description":"Optional subject-line template. Submitted values are intentionally\\nnot interpolated into the subject line for compliance reasons.\\n","maxLength":200}}},"PortalFormSubmissionWebhookConfig":{"type":"object","required":["kind","url"],"description":"Posts the submission JSON to a third-party webhook.","properties":{"kind":{"type":"string","enum":["webhook"]},"url":{"type":"string","format":"uri","description":"HTTPS endpoint receiving the signed POST."},"signingSecretRef":{"type":"string","description":"Name of the Key Vault secret used to HMAC-sign the request.\\nThe secret value is never returned in API responses.\\n"}}},"PortalFormSubmissionConfig":{"description":"Discriminated union of submission destinations. Exactly one of\\n`lead`, `email`, or `webhook` shapes is used based on `kind`.\\n","oneOf":[{"$ref":"#/definitions/PortalFormSubmissionLeadConfig"},{"$ref":"#/definitions/PortalFormSubmissionEmailConfig"},{"$ref":"#/definitions/PortalFormSubmissionWebhookConfig"}],"discriminator":{"propertyName":"kind","mapping":{"lead":"#/definitions/PortalFormSubmissionLeadConfig","email":"#/definitions/PortalFormSubmissionEmailConfig","webhook":"#/definitions/PortalFormSubmissionWebhookConfig"}}},"PortalFormSummary":{"type":"object","description":"List-row projection of a form definition.","required":["formId","fieldCount"],"properties":{"formId":{"type":"string","description":"Kebab-case identifier.","pattern":"^[a-z0-9][a-z0-9-]*$","example":"contact"},"formKind":{"$ref":"#/definitions/PortalFormKind"},"fieldCount":{"type":"integer","minimum":0,"description":"Number of input-bearing fields in the form.","example":4},"attachedPageSlugs":{"type":"array","description":"Slugs of pages that currently reference this form via `formId`.","items":{"type":"string"}},"submissionKind":{"type":"string","enum":["lead","email","webhook"],"description":"Submission destination kind."},"lastUpdated":{"type":"string","format":"date-time","description":"Last modification timestamp."}}},"PortalCreateFormRequest":{"type":"object","description":"Payload for creating a new form definition.","required":["formId","submission","fields"],"properties":{"formId":{"type":"string","description":"Kebab-case identifier, unique per site.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submitLabel":{"type":"string","maxLength":80},"successMessage":{"type":"string","maxLength":2000},"submission":{"$ref":"#/definitions/PortalFormSubmissionConfig"},"attachmentPolicy":{"$ref":"#/definitions/PortalFormAttachmentPolicy"},"steps":{"type":"array","items":{"$ref":"#/definitions/PortalFormStep"}},"fields":{"type":"array","items":{"$ref":"#/definitions/PortalFormField"}}}},"PortalUpdateFormRequest":{"type":"object","description":"Payload for updating an existing form definition. The `formId`\\nis taken from the URL; supplying it in the body is optional and,\\nif present, must match the path.\\n","properties":{"formId":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80,"description":"Optional echo of the path formId; must match if provided."},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submitLabel":{"type":"string","maxLength":80},"successMessage":{"type":"string","maxLength":2000},"submission":{"$ref":"#/definitions/PortalFormSubmissionConfig"},"attachmentPolicy":{"$ref":"#/definitions/PortalFormAttachmentPolicy"},"steps":{"type":"array","items":{"$ref":"#/definitions/PortalFormStep"}},"fields":{"type":"array","items":{"$ref":"#/definitions/PortalFormField"}},"expectedVersion":{"type":"integer","minimum":1,"description":"Optional optimistic-concurrency token. When supplied, the\\nupdate is rejected with 409 if the stored form\'s `version`\\nno longer matches.\\n"}}},"PortalDuplicateFormRequest":{"type":"object","description":"Payload for cloning an existing form under a new formId.","required":["formId"],"properties":{"formId":{"type":"string","description":"Target kebab-case formId for the cloned form.","pattern":"^[a-z0-9][a-z0-9-]*$","minLength":1,"maxLength":80}}},"PortalFormResponse":{"type":"object","description":"Full form definition response.","required":["form"],"properties":{"form":{"$ref":"#/definitions/PortalFormDefinition"},"attachedPageSlugs":{"type":"array","description":"Slugs of pages that currently reference this form via `formId`.","items":{"type":"string"}}}},"PortalFormListResponse":{"type":"object","required":["forms","totalCount"],"properties":{"forms":{"type":"array","items":{"$ref":"#/definitions/PortalFormSummary"}},"totalCount":{"type":"integer","minimum":0,"description":"Total number of forms matching the query.","example":3}}},"PortalFormSubmission":{"type":"object","description":"A single recorded submission against a managed form. PHI fields are\\nreplaced with `[REDACTED]` for Medical-category sites, in which case\\n`redactedForPhi` is true.\\n","required":["id","formId","siteSlug","submittedAt","source","values","redactedForPhi"],"properties":{"id":{"type":"string","description":"Unique submission row key (reverse-chronological)."},"formId":{"type":"string"},"siteSlug":{"type":"string"},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submittedAt":{"type":"string","format":"date-time"},"source":{"type":"string","description":"Capture channel (e.g. `web`, `import`)."},"values":{"type":"object","additionalProperties":true,"description":"Field id → submitted value map. PHI values are redacted."},"attachments":{"type":"array","description":"Attachment metadata captured with the submission.","items":{"$ref":"#/definitions/PublicSiteFormAttachment"}},"leadId":{"type":"string","nullable":true,"description":"Cross-reference to the lead row created by the legacy capture flow."},"contactMessageId":{"type":"string","nullable":true,"description":"Future portal contact-message identifier when surfaced in the portal."},"redactedForPhi":{"type":"boolean","description":"True when one or more values were replaced with the PHI placeholder."},"remoteIp":{"type":"string","nullable":true},"userAgent":{"type":"string","nullable":true}}},"PortalFormSubmissionSummary":{"type":"object","description":"List-view representation of a submission.","required":["id","formId","submittedAt","redactedForPhi","summary"],"properties":{"id":{"type":"string"},"formId":{"type":"string"},"formKind":{"$ref":"#/definitions/PortalFormKind"},"submittedAt":{"type":"string","format":"date-time"},"redactedForPhi":{"type":"boolean"},"summary":{"type":"string","description":"Short single-line preview suitable for the portal list view."}}},"PortalFormSubmissionListResponse":{"type":"object","required":["submissions"],"properties":{"submissions":{"type":"array","items":{"$ref":"#/definitions/PortalFormSubmissionSummary"}}}}}'), At = {
|
|
722
|
+
$schema: xt,
|
|
723
|
+
$id: kt,
|
|
724
|
+
title: Pt,
|
|
725
|
+
type: qt,
|
|
726
|
+
description: It,
|
|
727
|
+
required: Lt,
|
|
728
|
+
properties: Tt,
|
|
729
|
+
definitions: Ct
|
|
245
730
|
};
|
|
246
|
-
let
|
|
247
|
-
function
|
|
248
|
-
if (
|
|
249
|
-
const e = new
|
|
731
|
+
let Z = null;
|
|
732
|
+
function Vt() {
|
|
733
|
+
if (Z) return Z;
|
|
734
|
+
const e = new je({
|
|
250
735
|
allErrors: !0,
|
|
251
736
|
strict: !1,
|
|
252
737
|
discriminator: !1
|
|
253
738
|
});
|
|
254
|
-
return
|
|
739
|
+
return _e(e), Z = e.compile(At), Z;
|
|
255
740
|
}
|
|
256
|
-
function
|
|
257
|
-
const t =
|
|
741
|
+
function Mt(e) {
|
|
742
|
+
const t = Vt(), n = t(e);
|
|
258
743
|
return { valid: n, errors: n ? [] : t.errors ?? [] };
|
|
259
744
|
}
|
|
260
|
-
function
|
|
261
|
-
const i =
|
|
745
|
+
function Et(e, t, n) {
|
|
746
|
+
const i = Mt(t);
|
|
262
747
|
return !i.valid && n && console.warn(
|
|
263
748
|
`[@duffcloudservices/site-forms] Form "${e}" failed schema validation:`,
|
|
264
749
|
i.errors
|
|
265
750
|
), i;
|
|
266
751
|
}
|
|
267
|
-
function
|
|
752
|
+
function Ot(e) {
|
|
268
753
|
const t = {};
|
|
269
754
|
for (const [n, i] of Object.entries(e)) {
|
|
270
|
-
const
|
|
271
|
-
|
|
755
|
+
const o = Rt(n), a = Dt(i);
|
|
756
|
+
a && (t[a.formId ?? o] = a);
|
|
272
757
|
}
|
|
273
758
|
return t;
|
|
274
759
|
}
|
|
275
|
-
function
|
|
760
|
+
function Rt(e) {
|
|
276
761
|
return (e.split("/").pop() ?? e).replace(/\.ya?ml$/i, "");
|
|
277
762
|
}
|
|
278
|
-
function
|
|
763
|
+
function Dt(e) {
|
|
279
764
|
if (!e) return null;
|
|
280
765
|
if (typeof e == "string")
|
|
281
|
-
return
|
|
766
|
+
return $e.load(e);
|
|
282
767
|
if (typeof e == "object") {
|
|
283
768
|
const t = e.default;
|
|
284
769
|
return t && typeof t == "object" ? t : e;
|
|
285
770
|
}
|
|
286
771
|
return null;
|
|
287
772
|
}
|
|
288
|
-
function
|
|
289
|
-
return
|
|
773
|
+
function Xi(e) {
|
|
774
|
+
return $e.load(e);
|
|
290
775
|
}
|
|
291
|
-
const
|
|
776
|
+
const jt = ["data-form-field-key"], _t = ["for"], Bt = {
|
|
292
777
|
key: 0,
|
|
293
778
|
"aria-hidden": "true",
|
|
294
779
|
class: "dcs-form-field__required"
|
|
295
|
-
},
|
|
780
|
+
}, Nt = {
|
|
296
781
|
key: 0,
|
|
297
782
|
class: "dcs-form-field__help"
|
|
298
|
-
},
|
|
783
|
+
}, zt = {
|
|
299
784
|
key: 0,
|
|
300
785
|
class: "dcs-form-field__error",
|
|
301
786
|
role: "alert"
|
|
302
|
-
},
|
|
787
|
+
}, N = /* @__PURE__ */ M({
|
|
303
788
|
__name: "DcsFormFieldWrapper",
|
|
304
789
|
props: {
|
|
305
790
|
field: {},
|
|
@@ -307,30 +792,30 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
307
792
|
inputId: {}
|
|
308
793
|
},
|
|
309
794
|
setup(e) {
|
|
310
|
-
return (t, n) => (
|
|
311
|
-
class:
|
|
795
|
+
return (t, n) => (c(), f("div", {
|
|
796
|
+
class: Oe(["dcs-form-field", [`dcs-form-field--${e.field.type}`, `dcs-form-field--width-${e.field.width ?? "full"}`]]),
|
|
312
797
|
"data-form-field-key": e.field.id
|
|
313
798
|
}, [
|
|
314
|
-
|
|
315
|
-
e.field.type !== "checkbox" && e.field.type !== "hidden" && e.field.type !== "section-heading" && e.field.type !== "html-block" ? (
|
|
799
|
+
V(t.$slots, "label", {}, () => [
|
|
800
|
+
e.field.type !== "checkbox" && e.field.type !== "hidden" && e.field.type !== "section-heading" && e.field.type !== "html-block" ? (c(), f("label", {
|
|
316
801
|
key: 0,
|
|
317
802
|
for: e.inputId ?? `field-${e.field.id}`,
|
|
318
803
|
class: "dcs-form-field__label"
|
|
319
804
|
}, [
|
|
320
|
-
|
|
321
|
-
e.field.required ? (
|
|
322
|
-
], 8,
|
|
805
|
+
W(w(e.field.label) + " ", 1),
|
|
806
|
+
e.field.required ? (c(), f("span", Bt, "*")) : T("", !0)
|
|
807
|
+
], 8, _t)) : T("", !0)
|
|
323
808
|
]),
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
e.field.helpText ? (
|
|
809
|
+
V(t.$slots, "default"),
|
|
810
|
+
V(t.$slots, "help", {}, () => [
|
|
811
|
+
e.field.helpText ? (c(), f("p", Nt, w(e.field.helpText), 1)) : T("", !0)
|
|
327
812
|
]),
|
|
328
|
-
|
|
329
|
-
e.error ? (
|
|
813
|
+
V(t.$slots, "error", {}, () => [
|
|
814
|
+
e.error ? (c(), f("p", zt, w(e.error), 1)) : T("", !0)
|
|
330
815
|
])
|
|
331
|
-
], 10,
|
|
816
|
+
], 10, jt));
|
|
332
817
|
}
|
|
333
|
-
}),
|
|
818
|
+
}), Kt = ["id", "type", "name", "value", "placeholder", "required", "aria-invalid", "aria-describedby"], Fe = /* @__PURE__ */ M({
|
|
334
819
|
__name: "DcsFormText",
|
|
335
820
|
props: {
|
|
336
821
|
field: {},
|
|
@@ -339,7 +824,7 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
339
824
|
},
|
|
340
825
|
emits: ["update:modelValue", "blur"],
|
|
341
826
|
setup(e, { emit: t }) {
|
|
342
|
-
const n = e, i = t,
|
|
827
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`), a = m(() => {
|
|
343
828
|
switch (n.field.type) {
|
|
344
829
|
case "email":
|
|
345
830
|
return "email";
|
|
@@ -349,37 +834,37 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
349
834
|
return "text";
|
|
350
835
|
}
|
|
351
836
|
});
|
|
352
|
-
return (
|
|
837
|
+
return (d, s) => (c(), _(N, {
|
|
353
838
|
field: e.field,
|
|
354
839
|
error: e.error,
|
|
355
|
-
"input-id":
|
|
840
|
+
"input-id": o.value
|
|
356
841
|
}, {
|
|
357
842
|
default: j(() => [
|
|
358
|
-
|
|
359
|
-
id:
|
|
843
|
+
V(d.$slots, "input", {
|
|
844
|
+
id: o.value,
|
|
360
845
|
value: e.modelValue,
|
|
361
846
|
onInput: (l) => i("update:modelValue", l.target.value),
|
|
362
847
|
onBlur: () => i("blur")
|
|
363
848
|
}, () => [
|
|
364
|
-
|
|
365
|
-
id:
|
|
849
|
+
v("input", {
|
|
850
|
+
id: o.value,
|
|
366
851
|
class: "dcs-form-input",
|
|
367
|
-
type:
|
|
852
|
+
type: a.value,
|
|
368
853
|
name: e.field.id,
|
|
369
854
|
value: e.modelValue ?? "",
|
|
370
855
|
placeholder: e.field.placeholder,
|
|
371
856
|
required: e.field.required,
|
|
372
857
|
"aria-invalid": !!e.error,
|
|
373
|
-
"aria-describedby": e.error ? `${
|
|
374
|
-
onInput:
|
|
375
|
-
onBlur:
|
|
376
|
-
}, null, 40,
|
|
858
|
+
"aria-describedby": e.error ? `${o.value}-error` : void 0,
|
|
859
|
+
onInput: s[0] || (s[0] = (l) => i("update:modelValue", l.target.value)),
|
|
860
|
+
onBlur: s[1] || (s[1] = (l) => i("blur"))
|
|
861
|
+
}, null, 40, Kt)
|
|
377
862
|
])
|
|
378
863
|
]),
|
|
379
864
|
_: 3
|
|
380
865
|
}, 8, ["field", "error", "input-id"]));
|
|
381
866
|
}
|
|
382
|
-
}),
|
|
867
|
+
}), Ut = ["id", "name", "placeholder", "required", "aria-invalid", "value"], Ht = /* @__PURE__ */ M({
|
|
383
868
|
__name: "DcsFormTextarea",
|
|
384
869
|
props: {
|
|
385
870
|
field: {},
|
|
@@ -388,21 +873,21 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
388
873
|
},
|
|
389
874
|
emits: ["update:modelValue", "blur"],
|
|
390
875
|
setup(e, { emit: t }) {
|
|
391
|
-
const n = e, i = t,
|
|
392
|
-
return (
|
|
876
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`);
|
|
877
|
+
return (a, d) => (c(), _(N, {
|
|
393
878
|
field: e.field,
|
|
394
879
|
error: e.error,
|
|
395
|
-
"input-id":
|
|
880
|
+
"input-id": o.value
|
|
396
881
|
}, {
|
|
397
882
|
default: j(() => [
|
|
398
|
-
|
|
399
|
-
id:
|
|
883
|
+
V(a.$slots, "input", {
|
|
884
|
+
id: o.value,
|
|
400
885
|
value: e.modelValue,
|
|
401
|
-
onInput: (
|
|
886
|
+
onInput: (s) => i("update:modelValue", s.target.value),
|
|
402
887
|
onBlur: () => i("blur")
|
|
403
888
|
}, () => [
|
|
404
|
-
|
|
405
|
-
id:
|
|
889
|
+
v("textarea", {
|
|
890
|
+
id: o.value,
|
|
406
891
|
class: "dcs-form-input dcs-form-textarea",
|
|
407
892
|
name: e.field.id,
|
|
408
893
|
placeholder: e.field.placeholder,
|
|
@@ -410,19 +895,19 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
410
895
|
"aria-invalid": !!e.error,
|
|
411
896
|
rows: "5",
|
|
412
897
|
value: e.modelValue ?? "",
|
|
413
|
-
onInput:
|
|
414
|
-
onBlur:
|
|
415
|
-
}, null, 40,
|
|
898
|
+
onInput: d[0] || (d[0] = (s) => i("update:modelValue", s.target.value)),
|
|
899
|
+
onBlur: d[1] || (d[1] = (s) => i("blur"))
|
|
900
|
+
}, null, 40, Ut)
|
|
416
901
|
])
|
|
417
902
|
]),
|
|
418
903
|
_: 3
|
|
419
904
|
}, 8, ["field", "error", "input-id"]));
|
|
420
905
|
}
|
|
421
|
-
}),
|
|
906
|
+
}), Wt = ["id", "name", "required", "multiple", "aria-invalid", "value"], Gt = {
|
|
422
907
|
key: 0,
|
|
423
908
|
value: "",
|
|
424
909
|
disabled: ""
|
|
425
|
-
},
|
|
910
|
+
}, Jt = ["value"], Yt = /* @__PURE__ */ M({
|
|
426
911
|
__name: "DcsFormSelect",
|
|
427
912
|
props: {
|
|
428
913
|
field: {},
|
|
@@ -431,51 +916,51 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
431
916
|
},
|
|
432
917
|
emits: ["update:modelValue", "blur"],
|
|
433
918
|
setup(e, { emit: t }) {
|
|
434
|
-
const n = e, i = t,
|
|
435
|
-
function
|
|
436
|
-
const
|
|
437
|
-
if (
|
|
919
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`), a = m(() => n.field.type === "multiselect"), d = m(() => n.field.options ?? []);
|
|
920
|
+
function s(l) {
|
|
921
|
+
const u = l.target;
|
|
922
|
+
if (a.value) {
|
|
438
923
|
const r = [];
|
|
439
|
-
for (const
|
|
924
|
+
for (const b of Array.from(u.selectedOptions)) r.push(b.value);
|
|
440
925
|
i("update:modelValue", r);
|
|
441
926
|
} else
|
|
442
|
-
i("update:modelValue",
|
|
927
|
+
i("update:modelValue", u.value);
|
|
443
928
|
}
|
|
444
|
-
return (l,
|
|
929
|
+
return (l, u) => (c(), _(N, {
|
|
445
930
|
field: e.field,
|
|
446
931
|
error: e.error,
|
|
447
|
-
"input-id":
|
|
932
|
+
"input-id": o.value
|
|
448
933
|
}, {
|
|
449
934
|
default: j(() => [
|
|
450
|
-
|
|
451
|
-
id:
|
|
935
|
+
V(l.$slots, "input", {
|
|
936
|
+
id: o.value,
|
|
452
937
|
value: e.modelValue,
|
|
453
|
-
options:
|
|
454
|
-
onChange:
|
|
938
|
+
options: d.value,
|
|
939
|
+
onChange: s
|
|
455
940
|
}, () => [
|
|
456
|
-
|
|
457
|
-
id:
|
|
941
|
+
v("select", {
|
|
942
|
+
id: o.value,
|
|
458
943
|
class: "dcs-form-input dcs-form-select",
|
|
459
944
|
name: e.field.id,
|
|
460
945
|
required: e.field.required,
|
|
461
|
-
multiple:
|
|
946
|
+
multiple: a.value,
|
|
462
947
|
"aria-invalid": !!e.error,
|
|
463
|
-
value: e.modelValue ?? (
|
|
464
|
-
onChange:
|
|
465
|
-
onBlur:
|
|
948
|
+
value: e.modelValue ?? (a.value ? [] : ""),
|
|
949
|
+
onChange: s,
|
|
950
|
+
onBlur: u[0] || (u[0] = (r) => i("blur"))
|
|
466
951
|
}, [
|
|
467
|
-
|
|
468
|
-
(
|
|
952
|
+
a.value ? T("", !0) : (c(), f("option", Gt, w(e.field.placeholder ?? "Select…"), 1)),
|
|
953
|
+
(c(!0), f(K, null, G(d.value, (r) => (c(), f("option", {
|
|
469
954
|
key: r.value,
|
|
470
955
|
value: r.value
|
|
471
|
-
},
|
|
472
|
-
], 40,
|
|
956
|
+
}, w(r.label), 9, Jt))), 128))
|
|
957
|
+
], 40, Wt)
|
|
473
958
|
])
|
|
474
959
|
]),
|
|
475
960
|
_: 3
|
|
476
961
|
}, 8, ["field", "error", "input-id"]));
|
|
477
962
|
}
|
|
478
|
-
}),
|
|
963
|
+
}), Qt = ["aria-required", "aria-invalid"], Xt = { class: "sr-only" }, Zt = ["name", "value", "checked", "onChange"], ei = /* @__PURE__ */ M({
|
|
479
964
|
__name: "DcsFormRadio",
|
|
480
965
|
props: {
|
|
481
966
|
field: {},
|
|
@@ -484,39 +969,39 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
484
969
|
},
|
|
485
970
|
emits: ["update:modelValue"],
|
|
486
971
|
setup(e, { emit: t }) {
|
|
487
|
-
const n = e, i = t,
|
|
488
|
-
return (
|
|
972
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`), a = m(() => n.field.options ?? []);
|
|
973
|
+
return (d, s) => (c(), _(N, {
|
|
489
974
|
field: e.field,
|
|
490
975
|
error: e.error,
|
|
491
|
-
"input-id":
|
|
976
|
+
"input-id": o.value
|
|
492
977
|
}, {
|
|
493
978
|
default: j(() => [
|
|
494
|
-
|
|
979
|
+
v("fieldset", {
|
|
495
980
|
class: "dcs-form-radio-group",
|
|
496
981
|
role: "radiogroup",
|
|
497
982
|
"aria-required": e.field.required,
|
|
498
983
|
"aria-invalid": !!e.error
|
|
499
984
|
}, [
|
|
500
|
-
|
|
501
|
-
(
|
|
985
|
+
v("legend", Xt, w(e.field.label), 1),
|
|
986
|
+
(c(!0), f(K, null, G(a.value, (l) => (c(), f("label", {
|
|
502
987
|
key: l.value,
|
|
503
988
|
class: "dcs-form-radio"
|
|
504
989
|
}, [
|
|
505
|
-
|
|
990
|
+
v("input", {
|
|
506
991
|
type: "radio",
|
|
507
992
|
name: e.field.id,
|
|
508
993
|
value: l.value,
|
|
509
994
|
checked: e.modelValue === l.value,
|
|
510
|
-
onChange: (
|
|
511
|
-
}, null, 40,
|
|
512
|
-
|
|
995
|
+
onChange: (u) => i("update:modelValue", l.value)
|
|
996
|
+
}, null, 40, Zt),
|
|
997
|
+
v("span", null, w(l.label), 1)
|
|
513
998
|
]))), 128))
|
|
514
|
-
], 8,
|
|
999
|
+
], 8, Qt)
|
|
515
1000
|
]),
|
|
516
1001
|
_: 1
|
|
517
1002
|
}, 8, ["field", "error", "input-id"]));
|
|
518
1003
|
}
|
|
519
|
-
}),
|
|
1004
|
+
}), ti = ["aria-required", "aria-invalid"], ii = { class: "sr-only" }, ni = ["name", "value", "checked", "onChange"], ri = /* @__PURE__ */ M({
|
|
520
1005
|
__name: "DcsFormCheckboxGroup",
|
|
521
1006
|
props: {
|
|
522
1007
|
field: {},
|
|
@@ -525,45 +1010,45 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
525
1010
|
},
|
|
526
1011
|
emits: ["update:modelValue"],
|
|
527
1012
|
setup(e, { emit: t }) {
|
|
528
|
-
const n = e, i = t,
|
|
529
|
-
function
|
|
530
|
-
const r = new Set(
|
|
531
|
-
|
|
1013
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`), a = m(() => n.field.options ?? []), d = m(() => n.modelValue ?? []);
|
|
1014
|
+
function s(l, u) {
|
|
1015
|
+
const r = new Set(d.value);
|
|
1016
|
+
u ? r.add(l) : r.delete(l), i("update:modelValue", Array.from(r));
|
|
532
1017
|
}
|
|
533
|
-
return (l,
|
|
1018
|
+
return (l, u) => (c(), _(N, {
|
|
534
1019
|
field: e.field,
|
|
535
1020
|
error: e.error,
|
|
536
|
-
"input-id":
|
|
1021
|
+
"input-id": o.value
|
|
537
1022
|
}, {
|
|
538
1023
|
default: j(() => [
|
|
539
|
-
|
|
1024
|
+
v("fieldset", {
|
|
540
1025
|
class: "dcs-form-checkbox-group",
|
|
541
1026
|
"aria-required": e.field.required,
|
|
542
1027
|
"aria-invalid": !!e.error
|
|
543
1028
|
}, [
|
|
544
|
-
|
|
545
|
-
(
|
|
1029
|
+
v("legend", ii, w(e.field.label), 1),
|
|
1030
|
+
(c(!0), f(K, null, G(a.value, (r) => (c(), f("label", {
|
|
546
1031
|
key: r.value,
|
|
547
1032
|
class: "dcs-form-checkbox"
|
|
548
1033
|
}, [
|
|
549
|
-
|
|
1034
|
+
v("input", {
|
|
550
1035
|
type: "checkbox",
|
|
551
1036
|
name: `${e.field.id}[]`,
|
|
552
1037
|
value: r.value,
|
|
553
|
-
checked:
|
|
554
|
-
onChange: (
|
|
555
|
-
}, null, 40,
|
|
556
|
-
|
|
1038
|
+
checked: d.value.includes(r.value),
|
|
1039
|
+
onChange: (b) => s(r.value, b.target.checked)
|
|
1040
|
+
}, null, 40, ni),
|
|
1041
|
+
v("span", null, w(r.label), 1)
|
|
557
1042
|
]))), 128))
|
|
558
|
-
], 8,
|
|
1043
|
+
], 8, ti)
|
|
559
1044
|
]),
|
|
560
1045
|
_: 1
|
|
561
1046
|
}, 8, ["field", "error", "input-id"]));
|
|
562
1047
|
}
|
|
563
|
-
}),
|
|
1048
|
+
}), oi = { class: "sr-only" }, ai = ["for"], si = ["id", "name", "checked", "required", "aria-invalid"], li = {
|
|
564
1049
|
key: 0,
|
|
565
1050
|
"aria-hidden": "true"
|
|
566
|
-
},
|
|
1051
|
+
}, di = /* @__PURE__ */ M({
|
|
567
1052
|
__name: "DcsFormCheckbox",
|
|
568
1053
|
props: {
|
|
569
1054
|
field: {},
|
|
@@ -572,39 +1057,39 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
572
1057
|
},
|
|
573
1058
|
emits: ["update:modelValue"],
|
|
574
1059
|
setup(e, { emit: t }) {
|
|
575
|
-
const n = e, i = t,
|
|
576
|
-
return (
|
|
1060
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`);
|
|
1061
|
+
return (a, d) => (c(), _(N, {
|
|
577
1062
|
field: e.field,
|
|
578
1063
|
error: e.error,
|
|
579
|
-
"input-id":
|
|
1064
|
+
"input-id": o.value
|
|
580
1065
|
}, {
|
|
581
1066
|
label: j(() => [
|
|
582
|
-
|
|
1067
|
+
v("span", oi, w(e.field.label), 1)
|
|
583
1068
|
]),
|
|
584
1069
|
default: j(() => [
|
|
585
|
-
|
|
1070
|
+
v("label", {
|
|
586
1071
|
class: "dcs-form-checkbox-single",
|
|
587
|
-
for:
|
|
1072
|
+
for: o.value
|
|
588
1073
|
}, [
|
|
589
|
-
|
|
590
|
-
id:
|
|
1074
|
+
v("input", {
|
|
1075
|
+
id: o.value,
|
|
591
1076
|
type: "checkbox",
|
|
592
1077
|
name: e.field.id,
|
|
593
1078
|
checked: !!e.modelValue,
|
|
594
1079
|
required: e.field.required,
|
|
595
1080
|
"aria-invalid": !!e.error,
|
|
596
|
-
onChange:
|
|
597
|
-
}, null, 40,
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
e.field.required ? (
|
|
1081
|
+
onChange: d[0] || (d[0] = (s) => i("update:modelValue", s.target.checked))
|
|
1082
|
+
}, null, 40, si),
|
|
1083
|
+
v("span", null, [
|
|
1084
|
+
W(w(e.field.label), 1),
|
|
1085
|
+
e.field.required ? (c(), f("span", li, " *")) : T("", !0)
|
|
601
1086
|
])
|
|
602
|
-
], 8,
|
|
1087
|
+
], 8, ai)
|
|
603
1088
|
]),
|
|
604
1089
|
_: 1
|
|
605
1090
|
}, 8, ["field", "error", "input-id"]));
|
|
606
1091
|
}
|
|
607
|
-
}),
|
|
1092
|
+
}), ui = ["id", "name", "required", "aria-invalid", "value"], ci = /* @__PURE__ */ M({
|
|
608
1093
|
__name: "DcsFormDate",
|
|
609
1094
|
props: {
|
|
610
1095
|
field: {},
|
|
@@ -613,40 +1098,40 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
613
1098
|
},
|
|
614
1099
|
emits: ["update:modelValue", "blur"],
|
|
615
1100
|
setup(e, { emit: t }) {
|
|
616
|
-
const n = e, i = t,
|
|
617
|
-
return (
|
|
1101
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`);
|
|
1102
|
+
return (a, d) => (c(), _(N, {
|
|
618
1103
|
field: e.field,
|
|
619
1104
|
error: e.error,
|
|
620
|
-
"input-id":
|
|
1105
|
+
"input-id": o.value
|
|
621
1106
|
}, {
|
|
622
1107
|
default: j(() => [
|
|
623
|
-
|
|
624
|
-
id:
|
|
1108
|
+
v("input", {
|
|
1109
|
+
id: o.value,
|
|
625
1110
|
class: "dcs-form-input dcs-form-date",
|
|
626
1111
|
type: "date",
|
|
627
1112
|
name: e.field.id,
|
|
628
1113
|
required: e.field.required,
|
|
629
1114
|
"aria-invalid": !!e.error,
|
|
630
1115
|
value: e.modelValue ?? "",
|
|
631
|
-
onInput:
|
|
632
|
-
onBlur:
|
|
633
|
-
}, null, 40,
|
|
1116
|
+
onInput: d[0] || (d[0] = (s) => i("update:modelValue", s.target.value)),
|
|
1117
|
+
onBlur: d[1] || (d[1] = (s) => i("blur"))
|
|
1118
|
+
}, null, 40, ui)
|
|
634
1119
|
]),
|
|
635
1120
|
_: 1
|
|
636
1121
|
}, 8, ["field", "error", "input-id"]));
|
|
637
1122
|
}
|
|
638
|
-
}),
|
|
1123
|
+
}), mi = ["id", "name", "multiple", "required", "aria-invalid", "accept"], fi = {
|
|
639
1124
|
key: 0,
|
|
640
1125
|
class: "dcs-form-file__status"
|
|
641
|
-
},
|
|
1126
|
+
}, pi = {
|
|
642
1127
|
key: 1,
|
|
643
1128
|
class: "dcs-form-file-preview-grid",
|
|
644
1129
|
"aria-live": "polite"
|
|
645
|
-
},
|
|
1130
|
+
}, hi = ["src", "alt"], yi = {
|
|
646
1131
|
key: 1,
|
|
647
1132
|
class: "dcs-form-file-preview__placeholder",
|
|
648
1133
|
"aria-hidden": "true"
|
|
649
|
-
},
|
|
1134
|
+
}, gi = { class: "dcs-form-file-preview__meta" }, bi = { class: "dcs-form-file-preview__name" }, vi = { class: "dcs-form-file-preview__size" }, wi = ["aria-label", "onClick"], Fi = /* @__PURE__ */ M({
|
|
650
1135
|
__name: "DcsFormFile",
|
|
651
1136
|
props: {
|
|
652
1137
|
field: {},
|
|
@@ -656,152 +1141,157 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
656
1141
|
},
|
|
657
1142
|
emits: ["update:modelValue"],
|
|
658
1143
|
setup(e, { emit: t }) {
|
|
659
|
-
const n = e, i = t,
|
|
660
|
-
function
|
|
661
|
-
return Array.isArray(
|
|
1144
|
+
const n = e, i = t, o = m(() => `field-${n.field.id}`), a = E(null), d = m(() => (n.field.validation?.accept ?? n.attachmentPolicy?.accept ?? []).join(",")), s = m(() => Math.max(1, Math.floor(n.attachmentPolicy?.maxFiles ?? 1))), l = m(() => s.value > 1), u = m(() => b(n.modelValue)), r = E([]);
|
|
1145
|
+
function b(p) {
|
|
1146
|
+
return Array.isArray(p) ? p.filter(Boolean) : p ? [p] : [];
|
|
662
1147
|
}
|
|
663
|
-
function
|
|
664
|
-
const
|
|
665
|
-
i("update:modelValue", l.value ?
|
|
1148
|
+
function F(p) {
|
|
1149
|
+
const $ = p.slice(0, s.value);
|
|
1150
|
+
i("update:modelValue", l.value ? $ : $[0]);
|
|
666
1151
|
}
|
|
667
|
-
function
|
|
668
|
-
return [
|
|
1152
|
+
function L(p) {
|
|
1153
|
+
return [p.name, p.type, p.size, p.lastModified].join(":");
|
|
669
1154
|
}
|
|
670
|
-
function
|
|
671
|
-
const
|
|
672
|
-
for (const
|
|
673
|
-
const
|
|
674
|
-
|
|
1155
|
+
function S(p) {
|
|
1156
|
+
const $ = /* @__PURE__ */ new Set(), q = [];
|
|
1157
|
+
for (const h of p) {
|
|
1158
|
+
const C = L(h);
|
|
1159
|
+
$.has(C) || ($.add(C), q.push(h));
|
|
675
1160
|
}
|
|
676
|
-
return
|
|
1161
|
+
return q;
|
|
677
1162
|
}
|
|
678
|
-
function
|
|
679
|
-
const
|
|
680
|
-
|
|
1163
|
+
function P(p) {
|
|
1164
|
+
const $ = p.target, q = Array.from($.files ?? []).filter((h) => h.size > 0);
|
|
1165
|
+
q.length !== 0 && (F(l.value ? S([...u.value, ...q]) : q), $.value = "");
|
|
681
1166
|
}
|
|
682
|
-
function
|
|
683
|
-
const
|
|
684
|
-
$
|
|
1167
|
+
function O(p) {
|
|
1168
|
+
const $ = u.value.filter((q, h) => h !== p);
|
|
1169
|
+
F($), $.length === 0 && a.value && (a.value.value = "");
|
|
685
1170
|
}
|
|
686
|
-
function
|
|
687
|
-
return
|
|
1171
|
+
function R(p) {
|
|
1172
|
+
return p < 1024 ? `${p} B` : p < 1024 * 1024 ? `${(p / 1024).toFixed(1)} KB` : `${(p / (1024 * 1024)).toFixed(1)} MB`;
|
|
688
1173
|
}
|
|
689
|
-
function
|
|
690
|
-
for (const
|
|
691
|
-
URL.revokeObjectURL(
|
|
1174
|
+
function D() {
|
|
1175
|
+
for (const p of r.value)
|
|
1176
|
+
URL.revokeObjectURL(p.url);
|
|
692
1177
|
r.value = [];
|
|
693
1178
|
}
|
|
694
|
-
return
|
|
695
|
-
|
|
696
|
-
(
|
|
697
|
-
|
|
698
|
-
file:
|
|
699
|
-
url: URL.createObjectURL(
|
|
700
|
-
canPreview:
|
|
1179
|
+
return ee(
|
|
1180
|
+
u,
|
|
1181
|
+
(p) => {
|
|
1182
|
+
D(), r.value = p.map(($) => ({
|
|
1183
|
+
file: $,
|
|
1184
|
+
url: URL.createObjectURL($),
|
|
1185
|
+
canPreview: $.type.toLowerCase().startsWith("image/")
|
|
701
1186
|
}));
|
|
702
1187
|
},
|
|
703
1188
|
{ immediate: !0 }
|
|
704
|
-
),
|
|
1189
|
+
), Re(D), (p, $) => (c(), _(N, {
|
|
705
1190
|
field: e.field,
|
|
706
1191
|
error: e.error,
|
|
707
|
-
"input-id":
|
|
1192
|
+
"input-id": o.value
|
|
708
1193
|
}, {
|
|
709
1194
|
default: j(() => [
|
|
710
|
-
|
|
1195
|
+
v("input", {
|
|
711
1196
|
ref_key: "inputEl",
|
|
712
|
-
ref:
|
|
713
|
-
id:
|
|
1197
|
+
ref: a,
|
|
1198
|
+
id: o.value,
|
|
714
1199
|
class: "dcs-form-input dcs-form-file",
|
|
715
1200
|
type: "file",
|
|
716
1201
|
name: e.field.id,
|
|
717
1202
|
multiple: l.value,
|
|
718
1203
|
required: e.field.required,
|
|
719
1204
|
"aria-invalid": !!e.error,
|
|
720
|
-
accept:
|
|
721
|
-
onChange:
|
|
722
|
-
}, null, 40,
|
|
723
|
-
l.value ? (
|
|
724
|
-
r.value.length > 0 ? (
|
|
725
|
-
(
|
|
726
|
-
key: q
|
|
1205
|
+
accept: d.value || void 0,
|
|
1206
|
+
onChange: P
|
|
1207
|
+
}, null, 40, mi),
|
|
1208
|
+
l.value ? (c(), f("p", fi, w(u.value.length) + " of " + w(s.value) + " files selected ", 1)) : T("", !0),
|
|
1209
|
+
r.value.length > 0 ? (c(), f("div", pi, [
|
|
1210
|
+
(c(!0), f(K, null, G(r.value, (q, h) => (c(), f("div", {
|
|
1211
|
+
key: L(q.file),
|
|
727
1212
|
class: "dcs-form-file-preview"
|
|
728
1213
|
}, [
|
|
729
|
-
|
|
1214
|
+
q.canPreview ? (c(), f("img", {
|
|
730
1215
|
key: 0,
|
|
731
1216
|
class: "dcs-form-file-preview__image",
|
|
732
|
-
src:
|
|
733
|
-
alt: `${
|
|
734
|
-
}, null, 8,
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
1217
|
+
src: q.url,
|
|
1218
|
+
alt: `${q.file.name} preview`
|
|
1219
|
+
}, null, 8, hi)) : (c(), f("div", yi, " File ")),
|
|
1220
|
+
v("div", gi, [
|
|
1221
|
+
v("span", bi, w(q.file.name), 1),
|
|
1222
|
+
v("span", vi, w(R(q.file.size)), 1)
|
|
738
1223
|
]),
|
|
739
|
-
|
|
1224
|
+
v("button", {
|
|
740
1225
|
type: "button",
|
|
741
1226
|
class: "dcs-form-file-preview__remove",
|
|
742
|
-
"aria-label": `Remove ${
|
|
743
|
-
onClick: (
|
|
744
|
-
}, " Remove ", 8,
|
|
1227
|
+
"aria-label": `Remove ${q.file.name}`,
|
|
1228
|
+
onClick: (C) => O(h)
|
|
1229
|
+
}, " Remove ", 8, wi)
|
|
745
1230
|
]))), 128))
|
|
746
|
-
])) :
|
|
1231
|
+
])) : T("", !0)
|
|
747
1232
|
]),
|
|
748
1233
|
_: 1
|
|
749
1234
|
}, 8, ["field", "error", "input-id"]));
|
|
750
1235
|
}
|
|
751
|
-
}),
|
|
1236
|
+
}), Si = ["name", "value", "data-form-field-key"], $i = /* @__PURE__ */ M({
|
|
752
1237
|
__name: "DcsFormHidden",
|
|
753
1238
|
props: {
|
|
754
1239
|
field: {},
|
|
755
1240
|
modelValue: {}
|
|
756
1241
|
},
|
|
757
1242
|
setup(e) {
|
|
758
|
-
return (t, n) => (
|
|
1243
|
+
return (t, n) => (c(), f("input", {
|
|
759
1244
|
type: "hidden",
|
|
760
1245
|
name: e.field.id,
|
|
761
1246
|
value: e.modelValue ?? e.field.defaultValue ?? "",
|
|
762
1247
|
"data-form-field-key": e.field.id
|
|
763
|
-
}, null, 8,
|
|
1248
|
+
}, null, 8, Si));
|
|
764
1249
|
}
|
|
765
|
-
}),
|
|
1250
|
+
}), xi = ["data-form-field-key"], ki = { class: "dcs-form-section__heading" }, Pi = {
|
|
766
1251
|
key: 0,
|
|
767
1252
|
class: "dcs-form-section__help"
|
|
768
|
-
},
|
|
1253
|
+
}, qi = /* @__PURE__ */ M({
|
|
769
1254
|
__name: "DcsFormSection",
|
|
770
1255
|
props: {
|
|
771
1256
|
field: {}
|
|
772
1257
|
},
|
|
773
1258
|
setup(e) {
|
|
774
|
-
return (t, n) => (
|
|
1259
|
+
return (t, n) => (c(), f("div", {
|
|
775
1260
|
class: "dcs-form-section",
|
|
776
1261
|
"data-form-field-key": e.field.id
|
|
777
1262
|
}, [
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
e.field.helpText ? (
|
|
1263
|
+
V(t.$slots, "default", {}, () => [
|
|
1264
|
+
v("h3", ki, w(e.field.label), 1),
|
|
1265
|
+
e.field.helpText ? (c(), f("p", Pi, w(e.field.helpText), 1)) : T("", !0)
|
|
781
1266
|
])
|
|
782
|
-
], 8,
|
|
1267
|
+
], 8, xi));
|
|
783
1268
|
}
|
|
784
|
-
}),
|
|
1269
|
+
}), Ii = ["data-form-field-key", "innerHTML"], Li = /* @__PURE__ */ M({
|
|
785
1270
|
__name: "DcsFormHtmlBlock",
|
|
786
1271
|
props: {
|
|
787
1272
|
field: {}
|
|
788
1273
|
},
|
|
789
1274
|
setup(e) {
|
|
790
|
-
return (t, n) => (
|
|
1275
|
+
return (t, n) => (c(), f("div", {
|
|
791
1276
|
class: "dcs-form-html-block",
|
|
792
1277
|
"data-form-field-key": e.field.id,
|
|
793
1278
|
innerHTML: e.field.html ?? ""
|
|
794
|
-
}, null, 8,
|
|
1279
|
+
}, null, 8, Ii));
|
|
795
1280
|
}
|
|
796
|
-
}),
|
|
1281
|
+
}), Se = {}, Ti = ["data-form-key"], Ci = ["data-form-key"], Ai = ["data-form-key"], Vi = {
|
|
797
1282
|
key: 0,
|
|
798
1283
|
class: "dcs-form__progress",
|
|
799
1284
|
"aria-live": "polite"
|
|
800
|
-
},
|
|
1285
|
+
}, Mi = { class: "dcs-form__fields" }, Ei = {
|
|
1286
|
+
key: 0,
|
|
1287
|
+
class: "dcs-form__phi-guidance",
|
|
1288
|
+
"data-form-phi-guidance": "",
|
|
1289
|
+
role: "note"
|
|
1290
|
+
}, Oi = {
|
|
801
1291
|
key: 1,
|
|
802
1292
|
class: "dcs-form__submit-error",
|
|
803
1293
|
role: "alert"
|
|
804
|
-
},
|
|
1294
|
+
}, Ri = { class: "dcs-form__actions" }, Di = ["disabled"], Zi = /* @__PURE__ */ M({
|
|
805
1295
|
__name: "DcsForm",
|
|
806
1296
|
props: {
|
|
807
1297
|
formId: {},
|
|
@@ -813,66 +1303,87 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
813
1303
|
},
|
|
814
1304
|
emits: ["submit-success", "submit-error", "validation-error"],
|
|
815
1305
|
setup(e, { expose: t, emit: n }) {
|
|
816
|
-
const i = e,
|
|
817
|
-
() =>
|
|
818
|
-
),
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
(
|
|
822
|
-
|
|
1306
|
+
const i = e, o = n, a = /* @__PURE__ */ Object.assign({}), d = m(
|
|
1307
|
+
() => Ot(i.formsModules ?? a)
|
|
1308
|
+
), s = m(() => i.definitionOverride ? i.definitionOverride : d.value[i.formId] ?? null), l = !1;
|
|
1309
|
+
ee(
|
|
1310
|
+
s,
|
|
1311
|
+
(h) => {
|
|
1312
|
+
h && Et(i.formId, h, l);
|
|
823
1313
|
},
|
|
824
1314
|
{ immediate: !0 }
|
|
825
1315
|
);
|
|
826
|
-
const
|
|
827
|
-
() =>
|
|
1316
|
+
const u = m(
|
|
1317
|
+
() => s.value ?? {
|
|
828
1318
|
formId: i.formId,
|
|
829
1319
|
submission: { kind: "lead" },
|
|
830
1320
|
fields: []
|
|
831
1321
|
}
|
|
832
|
-
), r =
|
|
833
|
-
|
|
834
|
-
() =>
|
|
1322
|
+
), r = st({ definition: u.value }), { play: b } = et();
|
|
1323
|
+
ee(
|
|
1324
|
+
() => u.value,
|
|
835
1325
|
() => r.reset()
|
|
836
1326
|
);
|
|
837
|
-
const
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
)
|
|
842
|
-
(
|
|
1327
|
+
const F = m(() => {
|
|
1328
|
+
const h = i.apiBase ?? Se?.VITE_DCS_PUBLIC_API ?? "";
|
|
1329
|
+
return h || L();
|
|
1330
|
+
});
|
|
1331
|
+
function L() {
|
|
1332
|
+
if (typeof window > "u") return "";
|
|
1333
|
+
const h = window.location.hostname.toLowerCase();
|
|
1334
|
+
return h === "localhost" || h === "127.0.0.1" || h === "::1" ? "/api/v1" : "https://api.duffcloudservices.com/api/v1";
|
|
1335
|
+
}
|
|
1336
|
+
const S = m(
|
|
1337
|
+
() => i.siteSlug ?? Se?.VITE_DCS_SITE_SLUG ?? ""
|
|
1338
|
+
), P = m(
|
|
1339
|
+
() => u.value.submitLabel ?? "Send"
|
|
843
1340
|
);
|
|
844
|
-
function
|
|
845
|
-
switch (
|
|
1341
|
+
function O(h) {
|
|
1342
|
+
switch (h.type) {
|
|
846
1343
|
case "text":
|
|
847
1344
|
case "email":
|
|
848
1345
|
case "tel":
|
|
849
|
-
return
|
|
1346
|
+
return Fe;
|
|
850
1347
|
case "textarea":
|
|
851
|
-
return
|
|
1348
|
+
return Ht;
|
|
852
1349
|
case "select":
|
|
853
1350
|
case "multiselect":
|
|
854
|
-
return
|
|
1351
|
+
return Yt;
|
|
855
1352
|
case "radio":
|
|
856
|
-
return
|
|
1353
|
+
return ei;
|
|
857
1354
|
case "checkbox-group":
|
|
858
|
-
return
|
|
1355
|
+
return ri;
|
|
859
1356
|
case "checkbox":
|
|
860
|
-
return
|
|
1357
|
+
return di;
|
|
861
1358
|
case "date":
|
|
862
|
-
return
|
|
1359
|
+
return ci;
|
|
863
1360
|
case "file":
|
|
864
|
-
return
|
|
1361
|
+
return Fi;
|
|
865
1362
|
case "hidden":
|
|
866
|
-
return
|
|
1363
|
+
return $i;
|
|
867
1364
|
case "section-heading":
|
|
868
|
-
return
|
|
1365
|
+
return qi;
|
|
869
1366
|
case "html-block":
|
|
870
|
-
return
|
|
1367
|
+
return Li;
|
|
871
1368
|
default:
|
|
872
|
-
return
|
|
1369
|
+
return Fe;
|
|
873
1370
|
}
|
|
874
1371
|
}
|
|
875
|
-
const
|
|
1372
|
+
const R = E(!1), D = m(
|
|
1373
|
+
() => R.value && !!s.value
|
|
1374
|
+
), p = m(() => {
|
|
1375
|
+
const h = r.visibleFields.value.findIndex(
|
|
1376
|
+
(C) => C.type === "textarea" || C.role === "message" || C.role === "summary"
|
|
1377
|
+
);
|
|
1378
|
+
return h >= 0 ? h : 0;
|
|
1379
|
+
});
|
|
1380
|
+
pe(async () => {
|
|
1381
|
+
R.value = await $t({
|
|
1382
|
+
apiBase: F.value,
|
|
1383
|
+
siteSlug: S.value
|
|
1384
|
+
});
|
|
1385
|
+
});
|
|
1386
|
+
const $ = E(null);
|
|
876
1387
|
t({
|
|
877
1388
|
values: r.values,
|
|
878
1389
|
errors: r.errors,
|
|
@@ -880,119 +1391,126 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
880
1391
|
collectSubmissionValues: r.collectSubmissionValues,
|
|
881
1392
|
reset: r.reset
|
|
882
1393
|
});
|
|
883
|
-
async function
|
|
884
|
-
if (
|
|
1394
|
+
async function q(h) {
|
|
1395
|
+
if (h.preventDefault(), !s.value) return;
|
|
885
1396
|
if (!r.validateAll()) {
|
|
886
|
-
|
|
1397
|
+
o("validation-error", r.errors.value);
|
|
887
1398
|
return;
|
|
888
1399
|
}
|
|
889
1400
|
r.submitting.value = !0, r.submitError.value = null;
|
|
890
|
-
const
|
|
1401
|
+
const A = {
|
|
891
1402
|
formId: i.formId,
|
|
892
1403
|
values: r.collectSubmissionValues(),
|
|
893
1404
|
captchaToken: i.captchaToken
|
|
894
1405
|
};
|
|
895
1406
|
try {
|
|
896
|
-
const
|
|
897
|
-
apiBase:
|
|
898
|
-
siteSlug:
|
|
899
|
-
payload:
|
|
1407
|
+
const y = await vt({
|
|
1408
|
+
apiBase: F.value,
|
|
1409
|
+
siteSlug: S.value,
|
|
1410
|
+
payload: A
|
|
900
1411
|
});
|
|
901
|
-
r.submitted.value = !0,
|
|
902
|
-
} catch (
|
|
903
|
-
const x =
|
|
904
|
-
r.submitError.value = x.error?.message ?? "Submission failed",
|
|
1412
|
+
r.submitted.value = !0, b("notification.success"), o("submit-success", y);
|
|
1413
|
+
} catch (y) {
|
|
1414
|
+
const x = y;
|
|
1415
|
+
r.submitError.value = x.error?.message ?? "Submission failed", o("submit-error", x);
|
|
905
1416
|
} finally {
|
|
906
1417
|
r.submitting.value = !1;
|
|
907
1418
|
}
|
|
908
1419
|
}
|
|
909
|
-
return
|
|
910
|
-
|
|
1420
|
+
return pe(() => {
|
|
1421
|
+
s.value || console.warn(
|
|
911
1422
|
`[@duffcloudservices/site-forms] No form definition found for "${i.formId}". Expected a YAML at .dcs/forms/${i.formId}.yaml. In customer-site repos the YAML lives above the Vite root, so the internal auto-glob will not find it — pass formsModules explicitly: <DcsForm form-id="${i.formId}" :forms-modules="dcsFormsModules" />. See @duffcloudservices/site-forms README "Vite setup" section.`
|
|
912
1423
|
);
|
|
913
|
-
}), (
|
|
1424
|
+
}), (h, C) => s.value ? g(r).submitted.value ? (c(), f("div", {
|
|
914
1425
|
key: 1,
|
|
915
1426
|
class: "dcs-form dcs-form--success",
|
|
916
1427
|
"data-form-key": e.formId
|
|
917
1428
|
}, [
|
|
918
|
-
|
|
919
|
-
|
|
1429
|
+
V(h.$slots, "success", { definition: s.value }, () => [
|
|
1430
|
+
v("p", null, w(s.value.successMessage ?? "Thanks — we received your message."), 1)
|
|
920
1431
|
])
|
|
921
|
-
], 8,
|
|
1432
|
+
], 8, Ci)) : (c(), f("form", {
|
|
922
1433
|
key: 2,
|
|
923
1434
|
ref_key: "formEl",
|
|
924
|
-
ref:
|
|
1435
|
+
ref: $,
|
|
925
1436
|
class: "dcs-form",
|
|
926
1437
|
"data-form-key": e.formId,
|
|
927
1438
|
novalidate: "",
|
|
928
|
-
onSubmit:
|
|
1439
|
+
onSubmit: q
|
|
929
1440
|
}, [
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
current:
|
|
934
|
-
total:
|
|
935
|
-
step:
|
|
1441
|
+
V(h.$slots, "header", { definition: s.value }),
|
|
1442
|
+
g(r).steps.value ? (c(), f("div", Vi, [
|
|
1443
|
+
V(h.$slots, "progress", {
|
|
1444
|
+
current: g(r).currentStepIndex.value,
|
|
1445
|
+
total: g(r).steps.value.length,
|
|
1446
|
+
step: g(r).currentStep.value
|
|
936
1447
|
}, () => [
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
], 64)) :
|
|
1448
|
+
v("p", null, [
|
|
1449
|
+
W(" Step " + w(g(r).currentStepIndex.value + 1) + " of " + w(g(r).steps.value.length) + " ", 1),
|
|
1450
|
+
g(r).currentStep.value ? (c(), f(K, { key: 0 }, [
|
|
1451
|
+
W(" — " + w(g(r).currentStep.value.title), 1)
|
|
1452
|
+
], 64)) : T("", !0)
|
|
942
1453
|
])
|
|
943
1454
|
])
|
|
944
|
-
])) :
|
|
945
|
-
|
|
946
|
-
(
|
|
947
|
-
key:
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1455
|
+
])) : T("", !0),
|
|
1456
|
+
v("div", Mi, [
|
|
1457
|
+
(c(!0), f(K, null, G(g(r).visibleFields.value, (A, y) => (c(), f(K, {
|
|
1458
|
+
key: A.id
|
|
1459
|
+
}, [
|
|
1460
|
+
D.value && y === p.value ? (c(), f("p", Ei, [
|
|
1461
|
+
v("strong", null, w(g(we).lead), 1),
|
|
1462
|
+
W(" " + w(g(we).detail), 1)
|
|
1463
|
+
])) : T("", !0),
|
|
1464
|
+
(c(), _(De(O(A)), {
|
|
1465
|
+
field: A,
|
|
1466
|
+
"attachment-policy": u.value.attachmentPolicy,
|
|
1467
|
+
"model-value": g(r).values[A.id],
|
|
1468
|
+
error: g(r).errors.value[A.id],
|
|
1469
|
+
"onUpdate:modelValue": (x) => g(r).setValue(A.id, x),
|
|
1470
|
+
onBlur: (x) => g(r).touch(A.id)
|
|
1471
|
+
}, null, 40, ["field", "attachment-policy", "model-value", "error", "onUpdate:modelValue", "onBlur"]))
|
|
1472
|
+
], 64))), 128))
|
|
955
1473
|
]),
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
isFirstStep:
|
|
960
|
-
isLastStep:
|
|
961
|
-
submitting:
|
|
962
|
-
prev:
|
|
963
|
-
next:
|
|
1474
|
+
g(r).submitError.value ? (c(), f("div", Oi, w(g(r).submitError.value), 1)) : T("", !0),
|
|
1475
|
+
v("div", Ri, [
|
|
1476
|
+
V(h.$slots, "actions", {
|
|
1477
|
+
isFirstStep: g(r).isFirstStep.value,
|
|
1478
|
+
isLastStep: g(r).isLastStep.value,
|
|
1479
|
+
submitting: g(r).submitting.value,
|
|
1480
|
+
prev: g(r).prev,
|
|
1481
|
+
next: g(r).next
|
|
964
1482
|
}, () => [
|
|
965
|
-
|
|
1483
|
+
g(r).steps.value && !g(r).isFirstStep.value ? (c(), f("button", {
|
|
966
1484
|
key: 0,
|
|
967
1485
|
type: "button",
|
|
968
1486
|
class: "dcs-form__btn dcs-form__btn--prev",
|
|
969
|
-
onClick:
|
|
970
|
-
}, " Previous ")) :
|
|
971
|
-
|
|
1487
|
+
onClick: C[0] || (C[0] = (A) => g(r).prev())
|
|
1488
|
+
}, " Previous ")) : T("", !0),
|
|
1489
|
+
g(r).steps.value && !g(r).isLastStep.value ? (c(), f("button", {
|
|
972
1490
|
key: 1,
|
|
973
1491
|
type: "button",
|
|
974
1492
|
class: "dcs-form__btn dcs-form__btn--next",
|
|
975
|
-
onClick:
|
|
976
|
-
}, " Next ")) :
|
|
977
|
-
!
|
|
1493
|
+
onClick: C[1] || (C[1] = (A) => g(r).next())
|
|
1494
|
+
}, " Next ")) : T("", !0),
|
|
1495
|
+
!g(r).steps.value || g(r).isLastStep.value ? (c(), f("button", {
|
|
978
1496
|
key: 2,
|
|
979
1497
|
type: "submit",
|
|
980
1498
|
class: "dcs-form__btn dcs-form__btn--submit",
|
|
981
|
-
disabled:
|
|
982
|
-
},
|
|
1499
|
+
disabled: g(r).submitting.value
|
|
1500
|
+
}, w(g(r).submitting.value ? "Sending…" : P.value), 9, Di)) : T("", !0)
|
|
983
1501
|
])
|
|
984
1502
|
])
|
|
985
|
-
], 40,
|
|
1503
|
+
], 40, Ai)) : (c(), f("div", {
|
|
986
1504
|
key: 0,
|
|
987
1505
|
class: "dcs-form dcs-form--missing",
|
|
988
1506
|
"data-form-key": e.formId
|
|
989
1507
|
}, [
|
|
990
|
-
|
|
991
|
-
|
|
1508
|
+
V(h.$slots, "missing", { formId: e.formId }, () => [
|
|
1509
|
+
v("p", null, "Form “" + w(e.formId) + "” is not configured.", 1)
|
|
992
1510
|
])
|
|
993
|
-
], 8,
|
|
1511
|
+
], 8, Ti));
|
|
994
1512
|
}
|
|
995
|
-
}),
|
|
1513
|
+
}), en = {
|
|
996
1514
|
contact: {
|
|
997
1515
|
label: "Contact",
|
|
998
1516
|
description: "Canonical contact form with standard contact fields."
|
|
@@ -1009,7 +1527,7 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
1009
1527
|
label: "Custom / free-form",
|
|
1010
1528
|
description: "Flexible starter that stays fully editable for questionnaires and bespoke intake."
|
|
1011
1529
|
}
|
|
1012
|
-
},
|
|
1530
|
+
}, ji = () => [
|
|
1013
1531
|
{ id: "name", type: "text", role: "contact-name", label: "Full name", required: !0, width: "full" },
|
|
1014
1532
|
{ id: "email", type: "email", role: "contact-email", label: "Email", required: !0, width: "half" },
|
|
1015
1533
|
{ id: "phone", type: "tel", role: "contact-phone", label: "Phone", width: "half" },
|
|
@@ -1023,7 +1541,7 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
1023
1541
|
width: "full",
|
|
1024
1542
|
validation: { minLength: 10, maxLength: 2e3 }
|
|
1025
1543
|
}
|
|
1026
|
-
],
|
|
1544
|
+
], _i = () => [
|
|
1027
1545
|
{ id: "name", type: "text", role: "contact-name", label: "Full name", required: !0, width: "full" },
|
|
1028
1546
|
{ id: "email", type: "email", role: "contact-email", label: "Email", required: !0, width: "half" },
|
|
1029
1547
|
{ id: "phone", type: "tel", role: "contact-phone", label: "Phone", required: !0, width: "half" },
|
|
@@ -1047,7 +1565,7 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
1047
1565
|
width: "full",
|
|
1048
1566
|
validation: { accept: ["image/*"] }
|
|
1049
1567
|
}
|
|
1050
|
-
],
|
|
1568
|
+
], Bi = () => [
|
|
1051
1569
|
{ id: "name", type: "text", role: "contact-name", label: "Full name", required: !0, width: "full" },
|
|
1052
1570
|
{ id: "email", type: "email", role: "contact-email", label: "Email", required: !0, width: "half" },
|
|
1053
1571
|
{ id: "phone", type: "tel", role: "contact-phone", label: "Phone", width: "half" },
|
|
@@ -1075,7 +1593,7 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
1075
1593
|
]
|
|
1076
1594
|
}
|
|
1077
1595
|
}
|
|
1078
|
-
],
|
|
1596
|
+
], Ni = () => [
|
|
1079
1597
|
{ id: "name", type: "text", label: "Full name", required: !0, width: "full" },
|
|
1080
1598
|
{ id: "email", type: "email", label: "Email", required: !0, width: "half" },
|
|
1081
1599
|
{ id: "phone", type: "tel", label: "Phone", width: "half" },
|
|
@@ -1088,7 +1606,7 @@ const je = ["data-form-field-key"], Ae = ["for"], De = {
|
|
|
1088
1606
|
validation: { minLength: 10, maxLength: 2e3 }
|
|
1089
1607
|
}
|
|
1090
1608
|
];
|
|
1091
|
-
function
|
|
1609
|
+
function tn(e, t = {}) {
|
|
1092
1610
|
switch (e ?? "custom") {
|
|
1093
1611
|
case "contact":
|
|
1094
1612
|
return {
|
|
@@ -1100,7 +1618,7 @@ function Bt(e, t = {}) {
|
|
|
1100
1618
|
kind: "lead",
|
|
1101
1619
|
...t.leadCategory ? { category: t.leadCategory } : {}
|
|
1102
1620
|
},
|
|
1103
|
-
fields:
|
|
1621
|
+
fields: ji()
|
|
1104
1622
|
};
|
|
1105
1623
|
case "revenue-contractor":
|
|
1106
1624
|
return {
|
|
@@ -1118,7 +1636,7 @@ function Bt(e, t = {}) {
|
|
|
1118
1636
|
maxFiles: 5,
|
|
1119
1637
|
accept: ["image/*"]
|
|
1120
1638
|
},
|
|
1121
|
-
fields:
|
|
1639
|
+
fields: _i()
|
|
1122
1640
|
};
|
|
1123
1641
|
case "resume-submission":
|
|
1124
1642
|
return {
|
|
@@ -1140,7 +1658,7 @@ function Bt(e, t = {}) {
|
|
|
1140
1658
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
1141
1659
|
]
|
|
1142
1660
|
},
|
|
1143
|
-
fields:
|
|
1661
|
+
fields: Bi()
|
|
1144
1662
|
};
|
|
1145
1663
|
default:
|
|
1146
1664
|
return {
|
|
@@ -1152,35 +1670,45 @@ function Bt(e, t = {}) {
|
|
|
1152
1670
|
kind: "lead",
|
|
1153
1671
|
...t.leadCategory ? { category: t.leadCategory } : {}
|
|
1154
1672
|
},
|
|
1155
|
-
fields:
|
|
1673
|
+
fields: Ni()
|
|
1156
1674
|
};
|
|
1157
1675
|
}
|
|
1158
1676
|
}
|
|
1159
1677
|
export {
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1678
|
+
Zi as DcsForm,
|
|
1679
|
+
di as DcsFormCheckbox,
|
|
1680
|
+
ri as DcsFormCheckboxGroup,
|
|
1681
|
+
ci as DcsFormDate,
|
|
1682
|
+
N as DcsFormFieldWrapper,
|
|
1683
|
+
Fi as DcsFormFile,
|
|
1684
|
+
$i as DcsFormHidden,
|
|
1685
|
+
Li as DcsFormHtmlBlock,
|
|
1686
|
+
ei as DcsFormRadio,
|
|
1687
|
+
qi as DcsFormSection,
|
|
1688
|
+
Yt as DcsFormSelect,
|
|
1689
|
+
Fe as DcsFormText,
|
|
1690
|
+
Ht as DcsFormTextarea,
|
|
1691
|
+
we as PHI_GUIDANCE_COPY,
|
|
1692
|
+
en as STANDARD_FORM_PRESET_META,
|
|
1693
|
+
tn as buildStandardFormDefinition,
|
|
1694
|
+
$t as fetchSiteHandlesPhi,
|
|
1695
|
+
nt as hasErrors,
|
|
1696
|
+
Yi as isBookingCancellationReceipt,
|
|
1697
|
+
Gi as isEstimateReceipt,
|
|
1698
|
+
de as isFieldVisible,
|
|
1699
|
+
ct as isManagedFormReceipt,
|
|
1700
|
+
Ji as isPasswordlessVerifyReceipt,
|
|
1701
|
+
Wi as isSiteContactReceipt,
|
|
1702
|
+
Ot as loadFormDefinitions,
|
|
1703
|
+
Xi as parseFormYaml,
|
|
1704
|
+
dt as readExpectedJson,
|
|
1705
|
+
lt as readOkBody,
|
|
1706
|
+
Qi as resetSitePhiPostureCache,
|
|
1707
|
+
vt as submitFormValues,
|
|
1708
|
+
st as useDcsForm,
|
|
1709
|
+
tt as validateField,
|
|
1710
|
+
it as validateForm,
|
|
1711
|
+
Mt as validateFormDefinition,
|
|
1712
|
+
Et as warnIfInvalid
|
|
1185
1713
|
};
|
|
1186
1714
|
//# sourceMappingURL=index.js.map
|