@webx-ui/module-inbox 0.7.0 → 0.8.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.
@@ -0,0 +1,1735 @@
1
+ import { inject as Qe, defineComponent as ae, useModel as Te, computed as $, ref as A, watch as $e, openBlock as p, createElementBlock as O, createElementVNode as D, toDisplayString as I, createCommentVNode as U, createBlock as w, unref as e, withCtx as u, createTextVNode as q, createVNode as i, mergeModels as Se, nextTick as Je, isRef as Ee, Fragment as Z, renderList as qe, useTemplateRef as et, createSlots as ze, defineAsyncComponent as fe } from "vue";
2
+ import { useLocales as ue, localizedValue as ie, WxBadge as pe, WxAction as Re, WxAutocomplete as tt, useModal as Be, WxDialog as Pe, WxAlert as Ne, WxSkeleton as lt, WxFormItem as L, WxTextarea as at, WxSelect as he, WxRadioGroup as st, WxCheckboxGroup as nt, WxCheckbox as ee, WxDatePicker as _e, WxInput as j, WxSpace as Le, WxButton as Q, toast as H, useElementWidth as ot, createModal as Me, WxTabs as it, WxTable as ut, WxEntityCard as rt, WxAvatar as Ue, WxIcon as ve, WxTooltip as dt, WxText as te, confirm as Oe, WxLocales as ct, WxRichText as We, WxInputNumber as oe, WxTagsInput as mt, WxCard as pt, WxEmpty as ht, WxSortableList as vt } from "@webx-ui/core";
3
+ import { useAdmin as se, i18nKey as ft, useTranslate as le, createRelationsApi as bt, useErrorText as be, rowMenuWidth as yt, WxScreenHead as gt, WxRowMenu as Ve, WxDate as Ie, WxFilterChips as xt } from "@webx-ui/module-admin";
4
+ import { useRoute as wt, useRouter as kt } from "vue-router";
5
+ const _t = {
6
+ module: {
7
+ title: "Inbox"
8
+ },
9
+ panel: {
10
+ forms: "Forms",
11
+ "new-form": "New form",
12
+ "no-forms": "No forms yet.",
13
+ "no-forms-help": "A form is a few questions and a list of who hears the answers.",
14
+ unread: "Unread",
15
+ submissions: "Submissions in all",
16
+ off: "Off",
17
+ settings: "Settings",
18
+ duplicate: "Duplicate",
19
+ delete: "Delete",
20
+ "delete-form-title": "Delete “:form”?",
21
+ "delete-form-text": "The form and its questions go. This cannot be undone.",
22
+ cancel: "Cancel",
23
+ save: "Save",
24
+ saved: "Saved.",
25
+ deleted: "Deleted.",
26
+ duplicated: "A copy was made.",
27
+ failed: "Some values were not accepted. Check the highlighted fields.",
28
+ "reorder-failed": "The new order could not be saved.",
29
+ reorder: "Reorder",
30
+ "new-form-title": "New form",
31
+ title: "Title",
32
+ slug: "Address",
33
+ "slug-help": "What the form is called on the site and where it posts.",
34
+ "is-enabled": "Active",
35
+ "is-enabled-help": "A form that is off is neither drawn nor accepted.",
36
+ "tab-general": "General",
37
+ "tab-fields": "Fields",
38
+ "tab-notifications": "Notifications",
39
+ "tab-antispam": "Antispam",
40
+ "tab-embed": "Embedding",
41
+ "after-sending": "After sending",
42
+ "thank-you-heading": "Heading",
43
+ "thank-you-text": "Text",
44
+ "submit-text": "Text on the button",
45
+ redirect: "Go to this address instead",
46
+ "redirect-help": "Left empty, the thank-you takes the form’s place on the page.",
47
+ recipients: "Who is written to",
48
+ "recipients-help": "Nobody here means nobody is told. The submission is kept either way.",
49
+ "no-recipients": "Nobody yet.",
50
+ "add-admin": "Add an administrator",
51
+ "add-email": "Add an address",
52
+ remove: "Remove",
53
+ "remove-recipient-title": "Remove this recipient?",
54
+ "remove-recipient-text": "They stop being told when something arrives.",
55
+ "email-field": "The field holding the sender’s address",
56
+ "email-field-help": "A reply to the notification then goes to whoever wrote in.",
57
+ "notify-through": "Notify through",
58
+ "notify-through-help": "Channels of the Notifications section: Telegram, e-mail and others. A submission from the site goes to each of them by its own template, beside the letter above.",
59
+ "pick-channels": "Add a channel",
60
+ "no-channels": "No channels chosen.",
61
+ "set-up-channels": "Set up channels",
62
+ channels: "Channels",
63
+ "channels-none": "Nothing was sent through channels.",
64
+ "channels-failed": "A channel did not deliver the notification",
65
+ "no-email-field": "None",
66
+ honeypot: "Hidden field",
67
+ "honeypot-help": "A field nobody sees and a robot fills in.",
68
+ "min-seconds": "Fastest a person could send it, in seconds",
69
+ "min-seconds-help": "Zero switches the check off.",
70
+ throttle: "Sends a minute from one address",
71
+ "throttle-help": "Zero switches the limit off.",
72
+ captcha: "Captcha",
73
+ "captcha-keys": "The keys are not set in the panel but in the site’s .env: WEBX_INBOX_RECAPTCHA_KEY / WEBX_INBOX_RECAPTCHA_SECRET for reCAPTCHA, WEBX_INBOX_TURNSTILE_KEY / WEBX_INBOX_TURNSTILE_SECRET for Turnstile.",
74
+ "captcha-off": "Off",
75
+ "captcha-recaptcha": "reCAPTCHA",
76
+ "captcha-turnstile": "Turnstile",
77
+ "captcha-unconfigured": "The site has no keys for this captcha yet, so the form refuses every submission until they are in its .env.",
78
+ "captcha-recaptcha-checkbox": "This site draws reCAPTCHA as the “I’m not a robot” checkbox, so its keys must be v2 Checkbox keys. To run it invisibly, create v2 Invisible keys and set WEBX_INBOX_RECAPTCHA_TYPE=invisible.",
79
+ "captcha-recaptcha-invisible": "This site runs reCAPTCHA invisibly when the form is sent, so its keys must be v2 Invisible keys (WEBX_INBOX_RECAPTCHA_TYPE=invisible).",
80
+ "captcha-recaptcha-v3": "This site runs reCAPTCHA v3: no widget, only a score checked when the form is sent, so its keys must be v3 keys (WEBX_INBOX_RECAPTCHA_TYPE=v3).",
81
+ "captcha-turnstile-checkbox": "This site draws Turnstile when the page opens, and a Managed widget shows visitors “Verify you are human”. To run it invisibly, set WEBX_INBOX_TURNSTILE_MODE=invisible and the widget mode to Invisible in Cloudflare.",
82
+ "captcha-turnstile-invisible": "This site runs Turnstile invisibly when the form is sent. Set the widget mode to Invisible in Cloudflare: a Managed widget still shows a challenge when it decides one is needed.",
83
+ "embed-blade": "On a page of the site",
84
+ "embed-blade-help": "Put the tag where the form belongs. The markup is published and rewritten by the site.",
85
+ "embed-block": "In the block builder",
86
+ "embed-block-help": "A block type prints the same tag, so an editor drops the form in without touching a template.",
87
+ "embed-block-panel-help": "On this site block templates are written in the panel, in Blocks: put the same tag into the template of a block there.",
88
+ "embed-extras": "Filled in and placed",
89
+ "embed-extras-help": ":values fills the hidden fields by their name; placement names where the form stands, so the submission remembers it and the site can style each place.",
90
+ loading: "Loading…",
91
+ "embed-names": "Names of the fields",
92
+ "embed-names-help": "A hidden field is filled in by the page: the address it was sent from, a product, a campaign.",
93
+ copy: "Copy",
94
+ copied: "Copied.",
95
+ statuses: "Statuses",
96
+ "new-status": "New status",
97
+ "status-key": "Key",
98
+ "status-color": "Colour",
99
+ "status-default": "Given to a new submission",
100
+ "status-spam": "Spam",
101
+ "status-closed": "Nothing further expected",
102
+ "in-use": "In use",
103
+ "delete-status-title": "Delete “:status”?",
104
+ "delete-status-text": "Only a status nothing is in can go.",
105
+ "no-statuses": "No statuses yet.",
106
+ "color-default": "Grey",
107
+ "color-primary": "Blue",
108
+ "color-success": "Green",
109
+ "color-warning": "Amber",
110
+ "color-info": "Cyan",
111
+ "color-danger": "Red",
112
+ // The submissions: the list on the right of the section, and one of them opened.
113
+ id: "ID",
114
+ received: "Received",
115
+ status: "Status",
116
+ assignee: "Assignee",
117
+ unassigned: "Nobody",
118
+ "submissions-empty": "Nothing has come in through this form yet.",
119
+ "search-submissions": "Search the answers",
120
+ "view-all": "All",
121
+ "view-unread": "Unread",
122
+ export: "Export",
123
+ "new-submission": "New submission",
124
+ "new-submission-title": "A submission by hand",
125
+ "new-submission-help": "For one that came by telephone or on paper. It is written the same way and lands in the same list.",
126
+ created: "Added.",
127
+ submission: "Submission :id",
128
+ previous: "Previous",
129
+ next: "Next",
130
+ "mark-read": "Mark as read",
131
+ "mark-unread": "Mark as unread",
132
+ "delete-submission-title": "Delete this submission?",
133
+ "delete-submission-text": "It goes with its attachments. This cannot be undone.",
134
+ selected: ":count selected",
135
+ "move-to": "Move to",
136
+ "delete-selected-title": "Delete :count submissions?",
137
+ answers: "Answers",
138
+ attachments: "Attachments",
139
+ details: "Details",
140
+ "meta-page": "Page",
141
+ "meta-placement": "Placement",
142
+ "any-placement": "Any placement",
143
+ "placement-none": "Not specified",
144
+ "meta-referrer": "Came from",
145
+ "meta-ip": "Address",
146
+ "meta-agent": "Browser",
147
+ "meta-locale": "Language",
148
+ "meta-source": "How it arrived",
149
+ "source-web": "From the site",
150
+ "source-panel": "Typed in",
151
+ notified: "The notification went out",
152
+ "not-notified": "No notification was sent",
153
+ "notify-failed": "The notification could not be sent",
154
+ reply: "Reply by mail",
155
+ log: "What has happened",
156
+ "event-created": "Arrived",
157
+ "event-status": "Status: :to",
158
+ "event-assignee": "Given to :to",
159
+ "event-unassigned": "Left to nobody",
160
+ "event-note": "A note was added",
161
+ "event-notified": "The notification went out",
162
+ "event-handled": "Handed to :name",
163
+ "event-handler-error": ":name failed: :error",
164
+ system: "System",
165
+ "no-answers": "Nothing was filled in.",
166
+ download: "Download",
167
+ "no-files-by-hand": "A file cannot be attached by hand: the files a submission carries are what was posted with it.",
168
+ "submissions-none": "Nothing here under this filter.",
169
+ "notifies-nobody": "Nobody is told about this form",
170
+ "notifies-nobody-text": "Every submission is kept here, but no letter goes out. Add a recipient on the Notifications tab.",
171
+ "notifies-nobody-short": "Nobody is told",
172
+ "recipient-admin_deleted": "This administrator no longer exists and gets no letter.",
173
+ "recipient-admin_inactive": "This administrator is switched off and gets no letter.",
174
+ "recipient-invalid_email": "This is not an e-mail address.",
175
+ "event-no-recipients": "Nobody was told: the form names no recipients",
176
+ "notified-nobody": "No notification: the form names nobody to tell",
177
+ "notify-queued": "The notification is waiting in the queue",
178
+ "notify-again": "Send the notification again",
179
+ "notify-sent-again": "The notification has been sent again",
180
+ "notify-recipient-queued": "waiting",
181
+ "notify-recipient-delivered": "sent",
182
+ "notify-recipient-failed": "failed",
183
+ "event-notify-queued": "The notification was queued",
184
+ "event-notify-failed": "The notification to :to failed",
185
+ "event-value": "Answer “:field” corrected: “:from” → “:to”"
186
+ },
187
+ fields: {
188
+ field: "Field",
189
+ "new-field": "New field",
190
+ "edit-field": "Field",
191
+ edit: "Edit",
192
+ "no-fields": "No questions yet.",
193
+ "no-fields-help": "A form with no fields draws nothing on the page.",
194
+ "save-first": "Save the form first, then write its questions.",
195
+ delete: "Delete",
196
+ "delete-title": "Delete “:field”?",
197
+ "delete-text": "It stops being asked. Answers already given keep it.",
198
+ cancel: "Cancel",
199
+ save: "Save",
200
+ name: "Name",
201
+ "name-help": "What the field is called in the HTML. Left empty, it answers to f17.",
202
+ type: "Type",
203
+ title: "Label",
204
+ placeholder: "Placeholder",
205
+ help: "Hint under the field",
206
+ "is-enabled": "Shown",
207
+ "is-required": "Required",
208
+ "is-fullsize": "Full width",
209
+ "in-table": "A column in the list",
210
+ choices: "Choices",
211
+ "choice-value": "Value",
212
+ "choice-label": "Label",
213
+ "add-choice": "Add a choice",
214
+ "no-choices": "No choices yet. A field with none accepts nothing.",
215
+ maxlength: "Longest answer, in characters",
216
+ rows: "Height, in lines",
217
+ pattern: "Pattern the answer has to match",
218
+ "pattern-help": "The browser’s own, written without delimiters: [0-9+ ()-]{6,}",
219
+ earliest: "Earliest date",
220
+ latest: "Latest date",
221
+ "min-choices": "Fewest ticks",
222
+ "max-choices": "Most ticks",
223
+ "consent-text": "The sentence beside the tick",
224
+ "consent-text-help": "A link is allowed here: it is printed as written.",
225
+ "max-size": "Largest file, in kilobytes",
226
+ extensions: "Extensions allowed",
227
+ "extensions-help": "Comma separated. Empty means the list the site allows.",
228
+ multiple: "Several files at once",
229
+ "type-text": "Text",
230
+ "type-email": "E-mail",
231
+ "type-tel": "Telephone",
232
+ "type-textarea": "Long text",
233
+ "type-select": "Drop-down",
234
+ "type-radio": "One of several",
235
+ "type-checkbox": "Several of several",
236
+ "type-consent": "Consent",
237
+ "type-date": "Date",
238
+ "type-file": "File",
239
+ "type-hidden": "Hidden"
240
+ },
241
+ relations: {
242
+ form: "Form",
243
+ "field-search": "Find a form by its name or address",
244
+ "field-empty": "No form",
245
+ "field-remove": "Remove the form",
246
+ "field-missing": "No such form",
247
+ "field-off": "Switched off",
248
+ "field-nothing": "No form matches",
249
+ "field-searching": "Searching…",
250
+ unknown: "The Inbox has no form “:slug”. It has: :forms.",
251
+ "unknown-none": "The Inbox has no form “:slug” — it has no forms yet."
252
+ }
253
+ }, Fe = /* @__PURE__ */ new WeakSet();
254
+ function re() {
255
+ try {
256
+ const { i18n: a } = se();
257
+ Fe.has(a) || (a.defaults("webx-inbox", _t), Fe.add(a));
258
+ } catch {
259
+ }
260
+ }
261
+ function Vt() {
262
+ const a = Qe(ft, null), n = ue();
263
+ return (c) => {
264
+ const y = a?.state.locale;
265
+ return (y === void 0 ? void 0 : c.title[y]) || ie(c.title, n.active.value, c.key);
266
+ };
267
+ }
268
+ const Tt = { class: "wx-inbox-form-field" }, $t = {
269
+ key: 0,
270
+ class: "wx-inbox-form-field__chosen"
271
+ }, St = { class: "wx-inbox-form-field__text" }, Ct = { class: "wx-inbox-form-field__title" }, At = {
272
+ key: 0,
273
+ class: "wx-inbox-form-field__slug"
274
+ }, Nt = {
275
+ key: 1,
276
+ class: "wx-inbox-form-field__empty"
277
+ }, Ut = { class: "wx-inbox-form-field__search" }, Wt = /* @__PURE__ */ ae({
278
+ name: "WxInboxFormField",
279
+ __name: "FormField",
280
+ props: /* @__PURE__ */ Se({
281
+ disabled: { type: Boolean, default: !1 },
282
+ placeholder: { default: void 0 },
283
+ emptyText: { default: void 0 }
284
+ }, {
285
+ modelValue: { default: null },
286
+ modelModifiers: {}
287
+ }),
288
+ emits: ["update:modelValue"],
289
+ setup(a) {
290
+ const n = a, c = Te(a, "modelValue");
291
+ re();
292
+ const y = se(), b = le("webx-inbox"), R = bt(y, "inbox-form"), t = $(() => typeof c.value == "string" ? c.value.trim() : ""), l = A(/* @__PURE__ */ new Map()), g = A(/* @__PURE__ */ new Set()), F = A([]), E = A(!1), W = A("");
293
+ function T(k) {
294
+ const f = new Map(l.value);
295
+ for (const x of k) x.slug && f.set(x.slug, x);
296
+ l.value = f;
297
+ }
298
+ async function S(k) {
299
+ if (!(k === "" || l.value.has(k) || g.value.has(k)))
300
+ try {
301
+ const f = await R.search(k);
302
+ T(f), f.some((x) => x.slug === k) || (g.value = /* @__PURE__ */ new Set([...g.value, k]));
303
+ } catch {
304
+ }
305
+ }
306
+ $e(t, (k) => {
307
+ S(k);
308
+ }, { immediate: !0 });
309
+ const v = $(() => t.value === "" ? null : l.value.get(t.value) ?? null), M = $(() => t.value === "" ? null : v.value === null ? g.value.has(t.value) ? b("relations.field-missing") : null : v.value.visible ? null : b("relations.field-off")), m = $(
310
+ () => F.value.filter((k) => k.slug && k.slug !== t.value).map((k) => ({
311
+ value: k.title,
312
+ description: [k.slug, k.visible ? null : b("relations.field-off")].filter((f) => typeof f == "string" && f !== "").join(" · "),
313
+ id: k.slug
314
+ }))
315
+ );
316
+ async function C(k) {
317
+ E.value = !0;
318
+ try {
319
+ const f = await R.search(k);
320
+ F.value = f, T(f);
321
+ } catch {
322
+ F.value = [];
323
+ } finally {
324
+ E.value = !1;
325
+ }
326
+ }
327
+ function _() {
328
+ F.value.length === 0 && !E.value && C(W.value);
329
+ }
330
+ function B(k) {
331
+ typeof k.id != "string" || k.id === "" || (c.value = k.id, Je(() => {
332
+ W.value = "";
333
+ }));
334
+ }
335
+ function P() {
336
+ c.value = null;
337
+ }
338
+ const X = $(() => n.placeholder ?? b("relations.field-search"));
339
+ return (k, f) => (p(), O("div", Tt, [
340
+ t.value !== "" ? (p(), O("div", $t, [
341
+ D("span", St, [
342
+ D("span", Ct, I(v.value?.title ?? t.value), 1),
343
+ v.value ? (p(), O("span", At, I(t.value), 1)) : U("", !0)
344
+ ]),
345
+ M.value ? (p(), w(e(pe), {
346
+ key: 0,
347
+ type: "warning"
348
+ }, {
349
+ default: u(() => [
350
+ q(I(M.value), 1)
351
+ ]),
352
+ _: 1
353
+ })) : U("", !0),
354
+ n.disabled ? U("", !0) : (p(), w(e(Re), {
355
+ key: 1,
356
+ type: "remove",
357
+ size: "sm",
358
+ title: e(b)("relations.field-remove"),
359
+ onClick: P
360
+ }, null, 8, ["title"]))
361
+ ])) : (p(), O("p", Nt, I(n.emptyText ?? e(b)("relations.field-empty")), 1)),
362
+ D("div", Ut, [
363
+ i(e(tt), {
364
+ modelValue: W.value,
365
+ "onUpdate:modelValue": f[0] || (f[0] = (x) => W.value = x),
366
+ options: m.value,
367
+ remote: "",
368
+ teleport: "",
369
+ loading: E.value,
370
+ "loading-text": e(b)("relations.field-searching"),
371
+ "empty-text": e(b)("relations.field-nothing"),
372
+ placeholder: X.value,
373
+ "aria-label": X.value,
374
+ disabled: n.disabled,
375
+ onSearch: C,
376
+ onOpen: _,
377
+ onSelect: B
378
+ }, null, 8, ["modelValue", "options", "loading", "loading-text", "empty-text", "placeholder", "aria-label", "disabled"])
379
+ ])
380
+ ]));
381
+ }
382
+ }), de = (a, n) => {
383
+ const c = a.__vccOpts || a;
384
+ for (const [y, b] of n)
385
+ c[y] = b;
386
+ return c;
387
+ }, It = /* @__PURE__ */ de(Wt, [["__scopeId", "data-v-91f60441"]]);
388
+ function al(a = {}) {
389
+ const n = a.path ?? "/inbox";
390
+ return {
391
+ id: "inbox",
392
+ path: n,
393
+ landing: a.landing ?? !0,
394
+ routes: [
395
+ // The section's own path travels as a prop, so a panel that mounted it somewhere else
396
+ // still links between its screens correctly.
397
+ {
398
+ path: n,
399
+ name: "webx.inbox",
400
+ component: () => import("./InboxPage-CCYXnZed.js"),
401
+ props: { base: n }
402
+ },
403
+ {
404
+ path: `${n}/statuses`,
405
+ name: "webx.inbox.statuses",
406
+ component: () => import("./StatusesPage-Mra8TB7G.js"),
407
+ props: { base: n }
408
+ },
409
+ {
410
+ path: `${n}/forms/:id(\\d+)`,
411
+ name: "webx.inbox.form",
412
+ component: () => import("./FormEditorPage-BoHzlFfz.js"),
413
+ props: { base: n }
414
+ },
415
+ // A submission has an address of its own, not a dialog over the list (§11): it goes in
416
+ // the mail to whoever deals with it, it gets pasted into a chat, an agent links to it.
417
+ {
418
+ path: `${n}/submissions/:id(\\d+)`,
419
+ name: "webx.inbox.submission",
420
+ component: () => import("./SubmissionPage-DVNKYpWH.js"),
421
+ props: { base: n }
422
+ }
423
+ ],
424
+ // A form of the Inbox as a field of any screen or block — the contact block's form — chosen
425
+ // by name and kept by slug. Here and not in the panel: what it lists is this section's.
426
+ types: {
427
+ "wx-inbox-form": { component: It, kind: "field" }
428
+ }
429
+ };
430
+ }
431
+ const me = /* @__PURE__ */ new WeakMap();
432
+ function ye(a) {
433
+ const n = `${a.apiPath}/inbox`, c = (t) => t.data, y = () => {
434
+ }, b = (t) => (me.delete(a.http), t);
435
+ function R() {
436
+ const t = me.get(a.http);
437
+ if (t !== void 0)
438
+ return t.then((g) => [...g]);
439
+ const l = a.http.get(`${n}/statuses`).then(c);
440
+ return me.set(a.http, l), l.catch(() => me.delete(a.http)), l.then((g) => [...g]);
441
+ }
442
+ return {
443
+ forms: () => a.http.get(`${n}/forms`).then(c),
444
+ form: (t) => a.http.get(`${n}/forms/${t}`).then(c),
445
+ createForm: (t) => a.http.post(`${n}/forms`, t).then(c),
446
+ saveForm: (t, l) => a.http.put(`${n}/forms/${t}`, l).then(c),
447
+ removeForm: (t) => a.http.delete(`${n}/forms/${t}`).then(y),
448
+ duplicateForm: (t) => a.http.post(`${n}/forms/${t}/duplicate`, {}).then(c),
449
+ sortForms: (t) => a.http.post(`${n}/forms/sorting`, { ids: t }).then(y),
450
+ fields: (t) => a.http.get(`${n}/forms/${t}/fields`).then(c),
451
+ createField: (t, l) => a.http.post(`${n}/forms/${t}/fields`, l).then(c),
452
+ saveField: (t, l) => a.http.put(`${n}/fields/${t}`, l).then(c),
453
+ removeField: (t) => a.http.delete(`${n}/fields/${t}`).then(y),
454
+ sortFields: (t, l) => a.http.post(`${n}/forms/${t}/fields/sorting`, { ids: l }).then(y),
455
+ statuses: R,
456
+ createStatus: (t) => a.http.post(`${n}/statuses`, t).then(c).then(b),
457
+ saveStatus: (t, l) => a.http.put(`${n}/statuses/${t}`, l).then(c).then(b),
458
+ removeStatus: (t) => a.http.delete(`${n}/statuses/${t}`).then(y).then(b),
459
+ sortStatuses: (t) => a.http.post(`${n}/statuses/sorting`, { ids: t }).then(y).then(b),
460
+ recipients: () => a.http.get(`${n}/recipients`).then(c),
461
+ submissions: (t, l = {}) => a.http.get(`${n}/forms/${t}/submissions`, { query: ke(l) }).then((g) => ({
462
+ ...g.meta,
463
+ data: g.data,
464
+ columns: g.columns,
465
+ counts: g.counts,
466
+ // Optional on the wire: a server from before placements answers without them.
467
+ placements: g.placements ?? []
468
+ })),
469
+ submission: (t, l = {}) => a.http.get(`${n}/submissions/${t}`, { query: ke(l) }).then(c),
470
+ createSubmission: (t, l) => a.http.post(`${n}/forms/${t}/submissions`, { fields: l }).then(c),
471
+ saveSubmission: (t, l) => a.http.put(`${n}/submissions/${t}`, l).then(c),
472
+ removeSubmission: (t) => a.http.delete(`${n}/submissions/${t}`).then(y),
473
+ notifySubmission: (t) => a.http.post(`${n}/submissions/${t}/notify`).then(c),
474
+ massSubmissions: (t) => a.http.post(`${n}/submissions/mass`, t).then(c),
475
+ exportUrl: (t, l = {}) => {
476
+ const g = new URLSearchParams();
477
+ for (const [E, W] of Object.entries(ke(l)))
478
+ W != null && W !== "" && g.set(E, String(W));
479
+ const F = g.toString();
480
+ return `${n}/forms/${t}/submissions/export${F === "" ? "" : `?${F}`}`;
481
+ }
482
+ };
483
+ }
484
+ function ke(a) {
485
+ return {
486
+ view: a.view === void 0 || a.view === "" ? void 0 : a.view,
487
+ search: a.search === void 0 || a.search === "" ? void 0 : a.search,
488
+ assignee: a.assignee ?? void 0,
489
+ placement: a.placement ?? void 0,
490
+ sort: a.sort ?? void 0,
491
+ page: a.page,
492
+ per_page: a.per_page
493
+ };
494
+ }
495
+ function sl(a, n, c) {
496
+ return $({
497
+ get: () => a.value[n] ?? c,
498
+ set: (y) => {
499
+ const b = { ...a.value };
500
+ y === "" || y === null || y === void 0 ? delete b[n] : b[n] = y, a.value = b;
501
+ }
502
+ });
503
+ }
504
+ const Ft = { class: "wx-inbox-by-hand" }, Et = /* @__PURE__ */ ae({
505
+ __name: "SubmissionCreateDialog",
506
+ props: {
507
+ form: {}
508
+ },
509
+ setup(a) {
510
+ const n = a, { resolve: c, dismiss: y, open: b } = Be(), R = se(), t = ye(R), l = ue();
511
+ re();
512
+ const g = le("webx-inbox"), F = be(), E = A([]), W = A(!0), T = A(!1), S = A({}), v = A({}), M = $(() => E.value.filter((f) => f.type !== "file")), m = $(() => E.value.some((f) => f.type === "file"));
513
+ function C(f) {
514
+ return v.value[`fields.${f.key}`]?.[0];
515
+ }
516
+ function _(f) {
517
+ return ie(f.title, l.active.value, f.key);
518
+ }
519
+ function B(f, x = "") {
520
+ return ie(
521
+ f,
522
+ l.active.value,
523
+ x
524
+ );
525
+ }
526
+ function P(f) {
527
+ return (f.options.choices ?? []).map((x) => ({
528
+ value: x.value,
529
+ label: B(x.label, x.value)
530
+ }));
531
+ }
532
+ async function X() {
533
+ try {
534
+ const f = await t.form(n.form.id);
535
+ E.value = (f.fields ?? []).filter((x) => x.is_enabled);
536
+ for (const x of E.value)
537
+ S.value[x.key] = x.type === "checkbox" ? [] : x.type === "consent" ? !1 : "";
538
+ } catch (f) {
539
+ H.danger(F(f));
540
+ } finally {
541
+ W.value = !1;
542
+ }
543
+ }
544
+ X();
545
+ async function k() {
546
+ T.value = !0, v.value = {};
547
+ try {
548
+ c(await t.createSubmission(n.form.id, S.value));
549
+ } catch (f) {
550
+ const x = f.body;
551
+ x?.errors ? (v.value = x.errors, H.danger(g("panel.failed"))) : H.danger(F(f));
552
+ } finally {
553
+ T.value = !1;
554
+ }
555
+ }
556
+ return (f, x) => (p(), w(e(Pe), {
557
+ open: e(b),
558
+ "onUpdate:open": x[1] || (x[1] = (s) => Ee(b) ? b.value = s : null),
559
+ title: e(g)("panel.new-submission-title"),
560
+ width: 560
561
+ }, {
562
+ footer: u(() => [
563
+ i(e(Le), { size: "sm" }, {
564
+ default: u(() => [
565
+ i(e(Q), {
566
+ variant: "outline",
567
+ onClick: x[0] || (x[0] = (s) => e(y)())
568
+ }, {
569
+ default: u(() => [
570
+ q(I(e(g)("panel.cancel")), 1)
571
+ ]),
572
+ _: 1
573
+ }),
574
+ i(e(Q), {
575
+ type: "primary",
576
+ loading: T.value,
577
+ disabled: W.value,
578
+ onClick: k
579
+ }, {
580
+ default: u(() => [
581
+ q(I(e(g)("panel.save")), 1)
582
+ ]),
583
+ _: 1
584
+ }, 8, ["loading", "disabled"])
585
+ ]),
586
+ _: 1
587
+ })
588
+ ]),
589
+ default: u(() => [
590
+ D("div", Ft, [
591
+ i(e(Ne), {
592
+ type: "info",
593
+ closable: !1
594
+ }, {
595
+ default: u(() => [
596
+ q(I(e(g)("panel.new-submission-help")), 1)
597
+ ]),
598
+ _: 1
599
+ }),
600
+ W.value ? (p(), w(e(lt), {
601
+ key: 0,
602
+ rows: 4
603
+ })) : (p(), O(Z, { key: 1 }, [
604
+ (p(!0), O(Z, null, qe(M.value, (s) => (p(), w(e(L), {
605
+ key: s.id,
606
+ label: _(s),
607
+ help: B(s.help),
608
+ error: C(s),
609
+ required: s.is_required
610
+ }, {
611
+ default: u(() => [
612
+ s.type === "textarea" ? (p(), w(e(at), {
613
+ key: 0,
614
+ modelValue: S.value[s.key],
615
+ "onUpdate:modelValue": (z) => S.value[s.key] = z,
616
+ rows: s.options.rows ?? 4,
617
+ placeholder: B(s.placeholder)
618
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "rows", "placeholder"])) : s.type === "select" ? (p(), w(e(he), {
619
+ key: 1,
620
+ modelValue: S.value[s.key],
621
+ "onUpdate:modelValue": (z) => S.value[s.key] = z,
622
+ options: P(s),
623
+ clearable: "",
624
+ placeholder: B(s.placeholder)
625
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "options", "placeholder"])) : s.type === "radio" ? (p(), w(e(st), {
626
+ key: 2,
627
+ modelValue: S.value[s.key],
628
+ "onUpdate:modelValue": (z) => S.value[s.key] = z,
629
+ options: P(s)
630
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "options"])) : s.type === "checkbox" ? (p(), w(e(nt), {
631
+ key: 3,
632
+ modelValue: S.value[s.key],
633
+ "onUpdate:modelValue": (z) => S.value[s.key] = z,
634
+ options: P(s)
635
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "options"])) : s.type === "consent" ? (p(), w(e(ee), {
636
+ key: 4,
637
+ modelValue: S.value[s.key],
638
+ "onUpdate:modelValue": (z) => S.value[s.key] = z,
639
+ label: B(s.options.text, _(s))
640
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "label"])) : s.type === "date" ? (p(), w(e(_e), {
641
+ key: 5,
642
+ modelValue: S.value[s.key],
643
+ "onUpdate:modelValue": (z) => S.value[s.key] = z,
644
+ placeholder: B(s.placeholder)
645
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "placeholder"])) : (p(), w(e(j), {
646
+ key: 6,
647
+ modelValue: S.value[s.key],
648
+ "onUpdate:modelValue": (z) => S.value[s.key] = z,
649
+ type: s.type === "email" ? "email" : s.type === "tel" ? "tel" : "text",
650
+ placeholder: B(s.placeholder),
651
+ maxlength: s.options.maxlength
652
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "type", "placeholder", "maxlength"]))
653
+ ]),
654
+ _: 2
655
+ }, 1032, ["label", "help", "error", "required"]))), 128)),
656
+ m.value ? (p(), w(e(Ne), {
657
+ key: 0,
658
+ type: "warning",
659
+ closable: !1
660
+ }, {
661
+ default: u(() => [
662
+ q(I(e(g)("panel.no-files-by-hand")), 1)
663
+ ]),
664
+ _: 1
665
+ })) : U("", !0)
666
+ ], 64))
667
+ ])
668
+ ]),
669
+ _: 1
670
+ }, 8, ["open", "title"]));
671
+ }
672
+ }), qt = /* @__PURE__ */ de(Et, [["__scopeId", "data-v-72006299"]]), zt = { class: "wx-submissions__mass" }, Rt = { class: "wx-submissions__state" }, Bt = 640, Pt = /* @__PURE__ */ ae({
673
+ __name: "SubmissionList",
674
+ props: {
675
+ form: {},
676
+ base: { default: "/inbox" }
677
+ },
678
+ emits: ["changed"],
679
+ setup(a, { expose: n, emit: c }) {
680
+ const y = a, b = c, R = se(), t = ye(R), l = wt(), g = kt(), F = ue();
681
+ re();
682
+ const E = et("root"), W = ot(E), T = $(() => W.value > 0 && W.value < Bt), S = $(() => T.value ? Number.POSITIVE_INFINITY : 0), v = le("webx-inbox"), M = le("webx-admin"), m = be(), C = A(null), _ = A([]), B = A(!1), P = A([]), X = A(!1), k = $(() => R.can("inbox.update")), f = Me(qt), x = $({
683
+ get: () => typeof l.query.view == "string" && l.query.view !== "" ? l.query.view : "all",
684
+ set: (o) => {
685
+ g.replace({
686
+ query: { ...l.query, view: o === "all" ? void 0 : o, page: void 0 }
687
+ });
688
+ }
689
+ }), s = $(() => ({
690
+ view: x.value,
691
+ search: typeof l.query.search == "string" ? l.query.search : "",
692
+ assignee: typeof l.query.assignee == "string" ? l.query.assignee : null,
693
+ placement: typeof l.query.placement == "string" ? l.query.placement : null,
694
+ sort: typeof l.query.sort == "string" ? l.query.sort : null,
695
+ page: Number(l.query.page ?? 1) || 1
696
+ })), z = $(
697
+ () => (C.value?.placements ?? []).map(
698
+ (o) => o === null ? { value: "none", label: v("panel.placement-none") } : { value: o, label: o }
699
+ )
700
+ ), ge = $(
701
+ () => z.value.length > 1 || s.value.placement !== null
702
+ ), J = $(() => {
703
+ const o = s.value.placement;
704
+ if (o === null) return [];
705
+ const N = z.value.find((h) => h.value === o)?.label ?? (o === "none" ? v("panel.placement-none") : o);
706
+ return [
707
+ {
708
+ key: "placement",
709
+ label: `${v("panel.meta-placement")}: ${N}`,
710
+ clear: () => K(void 0)
711
+ }
712
+ ];
713
+ });
714
+ function K(o) {
715
+ g.replace({
716
+ query: {
717
+ ...l.query,
718
+ placement: typeof o == "string" && o !== "" ? o : void 0,
719
+ page: void 0
720
+ }
721
+ });
722
+ }
723
+ const xe = $(() => {
724
+ const o = C.value?.counts, N = [
725
+ { value: "all", label: v("panel.view-all"), badge: o?.all || void 0 },
726
+ { value: "unread", label: v("panel.view-unread"), badge: o?.unread || void 0 }
727
+ ];
728
+ for (const h of _.value)
729
+ N.push({
730
+ value: h.key,
731
+ label: G(h),
732
+ badge: o?.statuses[h.key] || void 0
733
+ });
734
+ return N;
735
+ });
736
+ function V(o, N) {
737
+ const h = C.value?.columns?.[N];
738
+ return h ? o.values[h.key] ?? "" : "";
739
+ }
740
+ const r = $(() => {
741
+ const o = C.value?.columns ?? [];
742
+ return T.value ? [{ key: "card", label: "" }] : [
743
+ ...o.map((N, h) => ({
744
+ key: `values.${N.key}`,
745
+ label: N.label,
746
+ sortable: !0,
747
+ // The first answer is what the row is recognised by and stays at any width; every one
748
+ // after it is worth less than the room it takes, so it goes a step sooner. The steps are
749
+ // wide — 640, 960 — because an answer is a sentence and not a number: two of them plus
750
+ // the status and the date is already what a 755px pane holds without scrolling sideways,
751
+ // which is what the pane beside the forms actually is on a 1280 screen (§11).
752
+ hideBelow: h === 0 ? void 0 : 320 + h * 320
753
+ })),
754
+ // A floor rather than a width: the cell holds a badge, sometimes an avatar and sometimes
755
+ // a paperclip, and a fixed width that any of them overflows makes the whole table scroll
756
+ // sideways by two pixels.
757
+ { key: "status", label: v("panel.status"), minWidth: 100 },
758
+ {
759
+ key: "created_at",
760
+ label: v("panel.received"),
761
+ sortable: !0,
762
+ width: 120,
763
+ // "today at 16:22" is three words the table will break over two lines given half a
764
+ // chance, and a date read down a column has to be one line to be read at all.
765
+ cellClass: "wx-submissions__when",
766
+ hideBelow: 520
767
+ // Kept on the card, unlike most dates: "when did this come in" is one of the two
768
+ // questions a submission is looked at for, and the other one is who sent it.
769
+ },
770
+ { key: "actions", label: "", width: yt, align: "right", hideOnCards: !0 }
771
+ ];
772
+ }), d = $(
773
+ () => s.value.view === "all" && s.value.search === "" && s.value.assignee === null && s.value.placement === null ? v("panel.submissions-empty") : v("panel.submissions-none")
774
+ ), Y = $(
775
+ () => _.value.map((o) => ({ value: o.id, label: G(o) }))
776
+ ), G = Vt();
777
+ function De() {
778
+ return ie(y.form.title, F.active.value, y.form.slug);
779
+ }
780
+ async function ce(o) {
781
+ B.value = !0;
782
+ try {
783
+ C.value = await t.submissions(y.form.id, {
784
+ view: s.value.view,
785
+ search: o?.search ?? s.value.search,
786
+ assignee: s.value.assignee,
787
+ placement: s.value.placement,
788
+ sort: o?.sort ? `${o.sort.order === "desc" ? "-" : ""}${o.sort.key}` : null,
789
+ page: o?.page ?? s.value.page,
790
+ per_page: o?.perPage
791
+ });
792
+ } catch (N) {
793
+ H.danger(m(N));
794
+ } finally {
795
+ B.value = !1;
796
+ }
797
+ }
798
+ function He(o) {
799
+ const N = {
800
+ ...l.query,
801
+ search: o.search === "" ? void 0 : o.search,
802
+ sort: o.sort === null ? void 0 : `${o.sort.order === "desc" ? "-" : ""}${o.sort.key}`,
803
+ page: o.page === 1 ? void 0 : String(o.page)
804
+ };
805
+ g.replace({ query: N }), ce(o);
806
+ }
807
+ $e([() => y.form.id, x, () => s.value.assignee, () => s.value.placement], () => {
808
+ P.value = [], ce();
809
+ }), Xe();
810
+ async function Xe() {
811
+ try {
812
+ _.value = await t.statuses();
813
+ } catch (o) {
814
+ H.danger(m(o));
815
+ }
816
+ }
817
+ function Ge(o) {
818
+ g.push({ path: `${y.base}/submissions/${o.id}`, query: { ...l.query } });
819
+ }
820
+ function Ce(o) {
821
+ return k.value ? [
822
+ {
823
+ key: "read",
824
+ icon: o.is_read ? "eye-off" : "eye",
825
+ label: o.is_read ? v("panel.mark-unread") : v("panel.mark-read"),
826
+ run: () => {
827
+ we([o.id], o.is_read ? "unread" : "read");
828
+ }
829
+ },
830
+ {
831
+ key: "delete",
832
+ icon: "trash",
833
+ label: v("panel.delete"),
834
+ danger: !0,
835
+ run: () => {
836
+ Ae([o.id]);
837
+ }
838
+ }
839
+ ] : [];
840
+ }
841
+ async function Ye(o) {
842
+ typeof o == "number" && (X.value = !0, await we(
843
+ P.value.map((N) => N.id),
844
+ "status",
845
+ o
846
+ ), X.value = !1);
847
+ }
848
+ async function Ae(o) {
849
+ await Oe({
850
+ title: o.length === 1 ? v("panel.delete-submission-title") : v("panel.delete-selected-title", { count: o.length }),
851
+ message: v("panel.delete-submission-text"),
852
+ confirmText: v("panel.delete"),
853
+ cancelText: v("panel.cancel"),
854
+ tone: "danger"
855
+ }) && await we(o, "delete");
856
+ }
857
+ async function we(o, N, h) {
858
+ if (o.length !== 0)
859
+ try {
860
+ await t.massSubmissions({ ids: o, action: N, status_id: h }), P.value = [], await ce(), b("changed");
861
+ } catch (ne) {
862
+ H.danger(m(ne));
863
+ }
864
+ }
865
+ async function je() {
866
+ const o = await f({ form: y.form });
867
+ o && (H.success(v("panel.created")), await ce(), b("changed"), g.push({ path: `${y.base}/submissions/${o.id}`, query: { ...l.query } }));
868
+ }
869
+ const Ke = $(
870
+ () => t.exportUrl(y.form.id, {
871
+ view: s.value.view,
872
+ search: s.value.search,
873
+ assignee: s.value.assignee,
874
+ placement: s.value.placement,
875
+ sort: s.value.sort
876
+ })
877
+ ), Ze = $(() => [
878
+ { key: "export", label: v("panel.export"), icon: "download", href: Ke.value }
879
+ ]);
880
+ return n({ create: je }), (o, N) => (p(), O("div", {
881
+ ref_key: "root",
882
+ ref: E,
883
+ class: "wx-submissions"
884
+ }, [
885
+ i(e(gt), {
886
+ class: "wx-submissions__head",
887
+ level: 3,
888
+ title: De(),
889
+ subtitle: a.form.slug,
890
+ actions: Ze.value
891
+ }, null, 8, ["title", "subtitle", "actions"]),
892
+ i(e(it), {
893
+ modelValue: x.value,
894
+ "onUpdate:modelValue": N[2] || (N[2] = (h) => x.value = h),
895
+ class: "wx-submissions__views",
896
+ items: xe.value,
897
+ "collapse-below": 560,
898
+ "aria-label": e(v)("panel.status")
899
+ }, {
900
+ default: u(() => [
901
+ i(e(ut), {
902
+ data: C.value,
903
+ columns: r.value,
904
+ "row-key": "id",
905
+ searchable: "",
906
+ clickable: "",
907
+ hover: "",
908
+ flush: "",
909
+ loading: B.value,
910
+ "loading-text": e(v)("panel.loading"),
911
+ selectable: k.value,
912
+ "select-row-label": e(M)("filters.select-row"),
913
+ "select-all-label": e(M)("filters.select-all"),
914
+ "row-class": (h) => h.is_read ? void 0 : "is-unread",
915
+ "search-placeholder": e(v)("panel.search-submissions"),
916
+ "empty-text": d.value,
917
+ "cards-below": S.value,
918
+ "filters-count": J.value.length,
919
+ onRowClick: Ge,
920
+ onStateChange: He,
921
+ onSelectionChange: N[1] || (N[1] = (h, ne) => P.value = ne)
922
+ }, ze({
923
+ "cell-status": u(({ row: h }) => [
924
+ D("div", Rt, [
925
+ h.status ? (p(), w(e(pe), {
926
+ key: 0,
927
+ type: h.status.color
928
+ }, {
929
+ default: u(() => [
930
+ q(I(e(G)(h.status)), 1)
931
+ ]),
932
+ _: 2
933
+ }, 1032, ["type"])) : U("", !0),
934
+ h.assignee ? (p(), w(e(Ue), {
935
+ key: 1,
936
+ name: h.assignee.name,
937
+ title: h.assignee.name,
938
+ size: "xs",
939
+ tone: "auto"
940
+ }, null, 8, ["name", "title"])) : U("", !0),
941
+ h.files_count > 0 ? (p(), w(e(dt), {
942
+ key: 2,
943
+ content: e(v)("panel.attachments")
944
+ }, {
945
+ default: u(() => [
946
+ i(e(ve), {
947
+ name: "file",
948
+ size: "sm"
949
+ })
950
+ ]),
951
+ _: 1
952
+ }, 8, ["content"])) : U("", !0)
953
+ ])
954
+ ]),
955
+ "cell-created_at": u(({ row: h }) => [
956
+ i(e(Ie), {
957
+ value: h.created_at,
958
+ compact: ""
959
+ }, null, 8, ["value"])
960
+ ]),
961
+ "cell-card": u(({ row: h }) => [
962
+ i(e(rt), {
963
+ variant: "plain",
964
+ shape: "circle",
965
+ title: V(h, 0)
966
+ }, {
967
+ subtitle: u(() => [
968
+ q(I(V(h, 1)), 1)
969
+ ]),
970
+ meta: u(() => [
971
+ h.status ? (p(), w(e(pe), {
972
+ key: 0,
973
+ type: h.status.color,
974
+ size: "sm"
975
+ }, {
976
+ default: u(() => [
977
+ q(I(e(G)(h.status)), 1)
978
+ ]),
979
+ _: 2
980
+ }, 1032, ["type"])) : U("", !0),
981
+ h.assignee ? (p(), w(e(Ue), {
982
+ key: 1,
983
+ name: h.assignee.name,
984
+ title: h.assignee.name,
985
+ size: "xs",
986
+ tone: "auto"
987
+ }, null, 8, ["name", "title"])) : U("", !0),
988
+ h.files_count > 0 ? (p(), w(e(ve), {
989
+ key: 2,
990
+ name: "file",
991
+ size: "sm"
992
+ })) : U("", !0),
993
+ i(e(Ie), {
994
+ value: h.created_at
995
+ }, null, 8, ["value"])
996
+ ]),
997
+ _: 2
998
+ }, 1032, ["title"])
999
+ ]),
1000
+ "card-actions": u(({ row: h }) => [
1001
+ i(e(Ve), {
1002
+ actions: Ce(h),
1003
+ label: String(h.id)
1004
+ }, null, 8, ["actions", "label"])
1005
+ ]),
1006
+ "cell-actions": u(({ row: h }) => [
1007
+ i(e(Ve), {
1008
+ actions: Ce(h),
1009
+ label: String(h.id)
1010
+ }, null, 8, ["actions", "label"])
1011
+ ]),
1012
+ _: 2
1013
+ }, [
1014
+ P.value.length > 0 ? {
1015
+ name: "actions",
1016
+ fn: u(() => [
1017
+ D("div", zt, [
1018
+ i(e(te), {
1019
+ size: "sm",
1020
+ weight: "medium"
1021
+ }, {
1022
+ default: u(() => [
1023
+ q(I(e(v)("panel.selected", { count: P.value.length })), 1)
1024
+ ]),
1025
+ _: 1
1026
+ }),
1027
+ i(e(he), {
1028
+ "model-value": null,
1029
+ options: Y.value,
1030
+ placeholder: e(v)("panel.move-to"),
1031
+ disabled: X.value,
1032
+ size: "sm",
1033
+ style: { width: "180px" },
1034
+ "onUpdate:modelValue": Ye
1035
+ }, null, 8, ["options", "placeholder", "disabled"]),
1036
+ i(e(Q), {
1037
+ size: "sm",
1038
+ variant: "outline",
1039
+ type: "danger",
1040
+ icon: "trash",
1041
+ onClick: N[0] || (N[0] = (h) => Ae(P.value.map((ne) => ne.id)))
1042
+ }, {
1043
+ default: u(() => [
1044
+ q(I(e(v)("panel.delete")), 1)
1045
+ ]),
1046
+ _: 1
1047
+ })
1048
+ ])
1049
+ ]),
1050
+ key: "0"
1051
+ } : void 0,
1052
+ ge.value ? {
1053
+ name: "filters",
1054
+ fn: u(() => [
1055
+ i(e(L), {
1056
+ label: e(v)("panel.meta-placement")
1057
+ }, {
1058
+ default: u(() => [
1059
+ i(e(he), {
1060
+ "model-value": s.value.placement,
1061
+ options: z.value,
1062
+ placeholder: e(v)("panel.any-placement"),
1063
+ clearable: "",
1064
+ size: "sm",
1065
+ "onUpdate:modelValue": K
1066
+ }, null, 8, ["model-value", "options", "placeholder"])
1067
+ ]),
1068
+ _: 1
1069
+ }, 8, ["label"])
1070
+ ]),
1071
+ key: "1"
1072
+ } : void 0,
1073
+ J.value.length > 0 ? {
1074
+ name: "applied",
1075
+ fn: u(() => [
1076
+ i(e(xt), { filters: J.value }, null, 8, ["filters"])
1077
+ ]),
1078
+ key: "2"
1079
+ } : void 0
1080
+ ]), 1032, ["data", "columns", "loading", "loading-text", "selectable", "select-row-label", "select-all-label", "row-class", "search-placeholder", "empty-text", "cards-below", "filters-count"])
1081
+ ]),
1082
+ _: 1
1083
+ }, 8, ["modelValue", "items", "aria-label"])
1084
+ ], 512));
1085
+ }
1086
+ }), nl = /* @__PURE__ */ de(Pt, [["__scopeId", "data-v-b23e9ac8"]]), Lt = /* @__PURE__ */ ae({
1087
+ __name: "LocalizedRichText",
1088
+ props: /* @__PURE__ */ Se({
1089
+ placeholder: { default: void 0 },
1090
+ minHeight: { default: "160px" }
1091
+ }, {
1092
+ modelValue: { default: "" },
1093
+ modelModifiers: {}
1094
+ }),
1095
+ emits: ["update:modelValue"],
1096
+ setup(a) {
1097
+ const n = Te(a, "modelValue"), c = a, y = ue(), b = $(() => {
1098
+ const t = y.active.value;
1099
+ return y.list.value.some((g) => g.code === t) ? t : y.list.value[0]?.code ?? "";
1100
+ }), R = $({
1101
+ get: () => {
1102
+ const t = n.value;
1103
+ return typeof t == "string" ? b.value === "" || b.value === y.list.value[0]?.code ? t : "" : t[b.value] ?? "";
1104
+ },
1105
+ set: (t) => {
1106
+ if (b.value === "") {
1107
+ n.value = t;
1108
+ return;
1109
+ }
1110
+ const l = typeof n.value == "string" ? { [b.value]: n.value } : n.value;
1111
+ n.value = { ...l, [b.value]: t };
1112
+ }
1113
+ });
1114
+ return (t, l) => e(y).list.value.length > 0 ? (p(), w(e(ct), { key: 0 }, {
1115
+ default: u(() => [
1116
+ i(e(We), {
1117
+ modelValue: R.value,
1118
+ "onUpdate:modelValue": l[0] || (l[0] = (g) => R.value = g),
1119
+ placeholder: c.placeholder,
1120
+ "min-height": c.minHeight
1121
+ }, null, 8, ["modelValue", "placeholder", "min-height"])
1122
+ ]),
1123
+ _: 1
1124
+ })) : (p(), w(e(We), {
1125
+ key: 1,
1126
+ modelValue: R.value,
1127
+ "onUpdate:modelValue": l[1] || (l[1] = (g) => R.value = g),
1128
+ placeholder: c.placeholder,
1129
+ "min-height": c.minHeight
1130
+ }, null, 8, ["modelValue", "placeholder", "min-height"]));
1131
+ }
1132
+ }), Mt = [
1133
+ "text",
1134
+ "email",
1135
+ "tel",
1136
+ "textarea",
1137
+ "select",
1138
+ "radio",
1139
+ "checkbox",
1140
+ "consent",
1141
+ "date",
1142
+ "file",
1143
+ "hidden"
1144
+ ], ol = ["default", "primary", "success", "warning", "info", "danger"], Ot = { class: "wx-inbox-field-form" }, Dt = { class: "wx-inbox-field-form__row" }, Ht = {
1145
+ key: 2,
1146
+ class: "wx-inbox-choices"
1147
+ }, Xt = { class: "wx-inbox-field-form__row" }, Gt = { class: "wx-inbox-field-form__checks" }, Yt = /* @__PURE__ */ ae({
1148
+ __name: "FieldDialog",
1149
+ props: {
1150
+ field: {},
1151
+ form: {}
1152
+ },
1153
+ setup(a) {
1154
+ const n = a, { resolve: c, dismiss: y, open: b } = Be(), R = se(), t = ye(R);
1155
+ re();
1156
+ const l = le("webx-inbox"), g = be(), F = A(!1), E = A({}), W = A(""), T = A("text"), S = A({}), v = A({}), M = A({}), m = A({}), C = A(!0), _ = A(!1), B = A(!0), P = A(!1);
1157
+ $e(
1158
+ () => n.field,
1159
+ (V) => {
1160
+ W.value = V?.name ?? "", T.value = V?.type ?? "text", S.value = { ...V?.title ?? {} }, v.value = { ...V?.placeholder ?? {} }, M.value = { ...V?.help ?? {} }, m.value = { ...V?.options ?? {} }, C.value = V?.is_enabled ?? !0, _.value = V?.is_required ?? !1, B.value = V?.is_fullsize ?? !0, P.value = V?.in_table ?? !1, E.value = {};
1161
+ },
1162
+ { immediate: !0 }
1163
+ );
1164
+ const X = $(
1165
+ () => Mt.map((V) => ({ value: V, label: l(`fields.type-${V}`) }))
1166
+ ), k = $(() => ["select", "radio", "checkbox"].includes(T.value)), f = $(
1167
+ () => Array.isArray(m.value.choices) ? m.value.choices : []
1168
+ ), x = $({
1169
+ get: () => Array.isArray(m.value.extensions) ? m.value.extensions : [],
1170
+ set: (V) => s(
1171
+ "extensions",
1172
+ V.map((r) => r.replace(/^\./, ""))
1173
+ )
1174
+ });
1175
+ function s(V, r) {
1176
+ m.value = { ...m.value, [V]: r };
1177
+ }
1178
+ function z() {
1179
+ s("choices", [...f.value, { value: "", label: {} }]);
1180
+ }
1181
+ function ge(V) {
1182
+ s(
1183
+ "choices",
1184
+ f.value.filter((r, d) => d !== V)
1185
+ );
1186
+ }
1187
+ function J(V, r) {
1188
+ s(
1189
+ "choices",
1190
+ f.value.map((d, Y) => Y === V ? { ...d, ...r } : d)
1191
+ );
1192
+ }
1193
+ function K(V) {
1194
+ return E.value[V]?.[0];
1195
+ }
1196
+ async function xe() {
1197
+ F.value = !0, E.value = {};
1198
+ const V = {
1199
+ name: W.value.trim() === "" ? null : W.value.trim(),
1200
+ type: T.value,
1201
+ title: S.value,
1202
+ placeholder: v.value,
1203
+ help: M.value,
1204
+ options: m.value,
1205
+ is_enabled: C.value,
1206
+ is_required: _.value,
1207
+ is_fullsize: B.value,
1208
+ in_table: P.value
1209
+ };
1210
+ try {
1211
+ c(
1212
+ n.field === null ? await t.createField(n.form.id, V) : await t.saveField(n.field.id, V)
1213
+ );
1214
+ } catch (r) {
1215
+ const d = r.body;
1216
+ d?.errors ? (E.value = d.errors, H.danger(l("panel.failed"))) : H.danger(g(r));
1217
+ } finally {
1218
+ F.value = !1;
1219
+ }
1220
+ }
1221
+ return (V, r) => (p(), w(e(Pe), {
1222
+ open: e(b),
1223
+ "onUpdate:open": r[21] || (r[21] = (d) => Ee(b) ? b.value = d : null),
1224
+ title: a.field ? e(l)("fields.edit-field") : e(l)("fields.new-field"),
1225
+ width: 720
1226
+ }, {
1227
+ footer: u(() => [
1228
+ i(e(Le), { size: "sm" }, {
1229
+ default: u(() => [
1230
+ i(e(Q), {
1231
+ variant: "outline",
1232
+ onClick: r[20] || (r[20] = (d) => e(y)())
1233
+ }, {
1234
+ default: u(() => [
1235
+ q(I(e(l)("fields.cancel")), 1)
1236
+ ]),
1237
+ _: 1
1238
+ }),
1239
+ i(e(Q), {
1240
+ type: "primary",
1241
+ loading: F.value,
1242
+ onClick: xe
1243
+ }, {
1244
+ default: u(() => [
1245
+ q(I(e(l)("fields.save")), 1)
1246
+ ]),
1247
+ _: 1
1248
+ }, 8, ["loading"])
1249
+ ]),
1250
+ _: 1
1251
+ })
1252
+ ]),
1253
+ default: u(() => [
1254
+ D("div", Ot, [
1255
+ D("div", Dt, [
1256
+ i(e(L), {
1257
+ label: e(l)("fields.type")
1258
+ }, {
1259
+ default: u(() => [
1260
+ i(e(he), {
1261
+ modelValue: T.value,
1262
+ "onUpdate:modelValue": r[0] || (r[0] = (d) => T.value = d),
1263
+ options: X.value
1264
+ }, null, 8, ["modelValue", "options"])
1265
+ ]),
1266
+ _: 1
1267
+ }, 8, ["label"]),
1268
+ i(e(L), {
1269
+ label: e(l)("fields.name"),
1270
+ help: e(l)("fields.name-help"),
1271
+ error: K("name")
1272
+ }, {
1273
+ default: u(() => [
1274
+ i(e(j), {
1275
+ modelValue: W.value,
1276
+ "onUpdate:modelValue": r[1] || (r[1] = (d) => W.value = d),
1277
+ placeholder: "email"
1278
+ }, null, 8, ["modelValue"])
1279
+ ]),
1280
+ _: 1
1281
+ }, 8, ["label", "help", "error"])
1282
+ ]),
1283
+ i(e(L), {
1284
+ label: e(l)("fields.title"),
1285
+ error: K("title"),
1286
+ required: ""
1287
+ }, {
1288
+ default: u(() => [
1289
+ i(e(j), {
1290
+ modelValue: S.value,
1291
+ "onUpdate:modelValue": r[2] || (r[2] = (d) => S.value = d),
1292
+ localized: ""
1293
+ }, null, 8, ["modelValue"])
1294
+ ]),
1295
+ _: 1
1296
+ }, 8, ["label", "error"]),
1297
+ T.value !== "hidden" ? (p(), O(Z, { key: 0 }, [
1298
+ T.value !== "consent" ? (p(), w(e(L), {
1299
+ key: 0,
1300
+ label: e(l)("fields.placeholder")
1301
+ }, {
1302
+ default: u(() => [
1303
+ i(e(j), {
1304
+ modelValue: v.value,
1305
+ "onUpdate:modelValue": r[3] || (r[3] = (d) => v.value = d),
1306
+ localized: ""
1307
+ }, null, 8, ["modelValue"])
1308
+ ]),
1309
+ _: 1
1310
+ }, 8, ["label"])) : U("", !0),
1311
+ i(e(L), {
1312
+ label: e(l)("fields.help")
1313
+ }, {
1314
+ default: u(() => [
1315
+ i(e(j), {
1316
+ modelValue: M.value,
1317
+ "onUpdate:modelValue": r[4] || (r[4] = (d) => M.value = d),
1318
+ localized: ""
1319
+ }, null, 8, ["modelValue"])
1320
+ ]),
1321
+ _: 1
1322
+ }, 8, ["label"])
1323
+ ], 64)) : U("", !0),
1324
+ T.value === "consent" ? (p(), w(e(L), {
1325
+ key: 1,
1326
+ label: e(l)("fields.consent-text"),
1327
+ help: e(l)("fields.consent-text-help")
1328
+ }, {
1329
+ default: u(() => [
1330
+ i(Lt, {
1331
+ "model-value": m.value.text ?? {},
1332
+ "min-height": "100px",
1333
+ "onUpdate:modelValue": r[5] || (r[5] = (d) => s("text", d))
1334
+ }, null, 8, ["model-value"])
1335
+ ]),
1336
+ _: 1
1337
+ }, 8, ["label", "help"])) : U("", !0),
1338
+ k.value ? (p(), O("div", Ht, [
1339
+ i(e(te), {
1340
+ size: "sm",
1341
+ weight: "medium"
1342
+ }, {
1343
+ default: u(() => [
1344
+ q(I(e(l)("fields.choices")), 1)
1345
+ ]),
1346
+ _: 1
1347
+ }),
1348
+ f.value.length === 0 ? (p(), w(e(te), {
1349
+ key: 0,
1350
+ size: "sm",
1351
+ tone: "placeholder"
1352
+ }, {
1353
+ default: u(() => [
1354
+ q(I(e(l)("fields.no-choices")), 1)
1355
+ ]),
1356
+ _: 1
1357
+ })) : U("", !0),
1358
+ (p(!0), O(Z, null, qe(f.value, (d, Y) => (p(), O("div", {
1359
+ key: Y,
1360
+ class: "wx-inbox-choices__row"
1361
+ }, [
1362
+ i(e(j), {
1363
+ "model-value": d.value,
1364
+ placeholder: e(l)("fields.choice-value"),
1365
+ "onUpdate:modelValue": (G) => J(Y, { value: String(G) })
1366
+ }, null, 8, ["model-value", "placeholder", "onUpdate:modelValue"]),
1367
+ i(e(j), {
1368
+ "model-value": d.label,
1369
+ localized: "",
1370
+ placeholder: e(l)("fields.choice-label"),
1371
+ "onUpdate:modelValue": (G) => J(Y, { label: G })
1372
+ }, null, 8, ["model-value", "placeholder", "onUpdate:modelValue"]),
1373
+ i(e(Re), {
1374
+ icon: "trash",
1375
+ title: e(l)("fields.delete"),
1376
+ onClick: (G) => ge(Y)
1377
+ }, null, 8, ["title", "onClick"])
1378
+ ]))), 128)),
1379
+ i(e(Q), {
1380
+ variant: "outline",
1381
+ size: "sm",
1382
+ onClick: z
1383
+ }, {
1384
+ icon: u(() => [
1385
+ i(e(ve), { name: "plus" })
1386
+ ]),
1387
+ default: u(() => [
1388
+ q(" " + I(e(l)("fields.add-choice")), 1)
1389
+ ]),
1390
+ _: 1
1391
+ }),
1392
+ K("options.choices") ? (p(), w(e(te), {
1393
+ key: 1,
1394
+ size: "sm",
1395
+ tone: "danger"
1396
+ }, {
1397
+ default: u(() => [
1398
+ q(I(K("options.choices")), 1)
1399
+ ]),
1400
+ _: 1
1401
+ })) : U("", !0)
1402
+ ])) : U("", !0),
1403
+ D("div", Xt, [
1404
+ T.value === "textarea" ? (p(), w(e(L), {
1405
+ key: 0,
1406
+ label: e(l)("fields.rows")
1407
+ }, {
1408
+ default: u(() => [
1409
+ i(e(oe), {
1410
+ "model-value": m.value.rows ?? 5,
1411
+ min: 2,
1412
+ max: 30,
1413
+ "onUpdate:modelValue": r[6] || (r[6] = (d) => s("rows", d))
1414
+ }, null, 8, ["model-value"])
1415
+ ]),
1416
+ _: 1
1417
+ }, 8, ["label"])) : U("", !0),
1418
+ ["text", "email", "textarea"].includes(T.value) ? (p(), w(e(L), {
1419
+ key: 1,
1420
+ label: e(l)("fields.maxlength")
1421
+ }, {
1422
+ default: u(() => [
1423
+ i(e(oe), {
1424
+ "model-value": m.value.maxlength ?? null,
1425
+ min: 1,
1426
+ max: 2e4,
1427
+ "onUpdate:modelValue": r[7] || (r[7] = (d) => s("maxlength", d))
1428
+ }, null, 8, ["model-value"])
1429
+ ]),
1430
+ _: 1
1431
+ }, 8, ["label"])) : U("", !0),
1432
+ T.value === "tel" ? (p(), w(e(L), {
1433
+ key: 2,
1434
+ label: e(l)("fields.pattern"),
1435
+ help: e(l)("fields.pattern-help")
1436
+ }, {
1437
+ default: u(() => [
1438
+ i(e(j), {
1439
+ "model-value": m.value.pattern ?? "",
1440
+ "onUpdate:modelValue": r[8] || (r[8] = (d) => s("pattern", d))
1441
+ }, null, 8, ["model-value"])
1442
+ ]),
1443
+ _: 1
1444
+ }, 8, ["label", "help"])) : U("", !0),
1445
+ T.value === "date" ? (p(), O(Z, { key: 3 }, [
1446
+ i(e(L), {
1447
+ label: e(l)("fields.earliest")
1448
+ }, {
1449
+ default: u(() => [
1450
+ i(e(_e), {
1451
+ clearable: "",
1452
+ "model-value": m.value.min ?? null,
1453
+ "onUpdate:modelValue": r[9] || (r[9] = (d) => s("min", d))
1454
+ }, null, 8, ["model-value"])
1455
+ ]),
1456
+ _: 1
1457
+ }, 8, ["label"]),
1458
+ i(e(L), {
1459
+ label: e(l)("fields.latest")
1460
+ }, {
1461
+ default: u(() => [
1462
+ i(e(_e), {
1463
+ clearable: "",
1464
+ "model-value": m.value.max ?? null,
1465
+ "onUpdate:modelValue": r[10] || (r[10] = (d) => s("max", d))
1466
+ }, null, 8, ["model-value"])
1467
+ ]),
1468
+ _: 1
1469
+ }, 8, ["label"])
1470
+ ], 64)) : U("", !0),
1471
+ T.value === "checkbox" ? (p(), O(Z, { key: 4 }, [
1472
+ i(e(L), {
1473
+ label: e(l)("fields.min-choices")
1474
+ }, {
1475
+ default: u(() => [
1476
+ i(e(oe), {
1477
+ "model-value": m.value.min ?? null,
1478
+ min: 0,
1479
+ "onUpdate:modelValue": r[11] || (r[11] = (d) => s("min", d))
1480
+ }, null, 8, ["model-value"])
1481
+ ]),
1482
+ _: 1
1483
+ }, 8, ["label"]),
1484
+ i(e(L), {
1485
+ label: e(l)("fields.max-choices")
1486
+ }, {
1487
+ default: u(() => [
1488
+ i(e(oe), {
1489
+ "model-value": m.value.max ?? null,
1490
+ min: 0,
1491
+ "onUpdate:modelValue": r[12] || (r[12] = (d) => s("max", d))
1492
+ }, null, 8, ["model-value"])
1493
+ ]),
1494
+ _: 1
1495
+ }, 8, ["label"])
1496
+ ], 64)) : U("", !0),
1497
+ T.value === "file" ? (p(), w(e(L), {
1498
+ key: 5,
1499
+ label: e(l)("fields.max-size")
1500
+ }, {
1501
+ default: u(() => [
1502
+ i(e(oe), {
1503
+ "model-value": m.value.max_size ?? null,
1504
+ min: 1,
1505
+ "onUpdate:modelValue": r[13] || (r[13] = (d) => s("max_size", d))
1506
+ }, null, 8, ["model-value"])
1507
+ ]),
1508
+ _: 1
1509
+ }, 8, ["label"])) : U("", !0)
1510
+ ]),
1511
+ T.value === "file" ? (p(), O(Z, { key: 3 }, [
1512
+ i(e(L), {
1513
+ label: e(l)("fields.extensions"),
1514
+ help: e(l)("fields.extensions-help")
1515
+ }, {
1516
+ default: u(() => [
1517
+ i(e(mt), {
1518
+ modelValue: x.value,
1519
+ "onUpdate:modelValue": r[14] || (r[14] = (d) => x.value = d)
1520
+ }, null, 8, ["modelValue"])
1521
+ ]),
1522
+ _: 1
1523
+ }, 8, ["label", "help"]),
1524
+ i(e(ee), {
1525
+ "model-value": !!m.value.multiple,
1526
+ label: e(l)("fields.multiple"),
1527
+ "onUpdate:modelValue": r[15] || (r[15] = (d) => s("multiple", d))
1528
+ }, null, 8, ["model-value", "label"])
1529
+ ], 64)) : U("", !0),
1530
+ D("div", Gt, [
1531
+ i(e(ee), {
1532
+ modelValue: C.value,
1533
+ "onUpdate:modelValue": r[16] || (r[16] = (d) => C.value = d),
1534
+ label: e(l)("fields.is-enabled")
1535
+ }, null, 8, ["modelValue", "label"]),
1536
+ i(e(ee), {
1537
+ modelValue: _.value,
1538
+ "onUpdate:modelValue": r[17] || (r[17] = (d) => _.value = d),
1539
+ label: e(l)("fields.is-required")
1540
+ }, null, 8, ["modelValue", "label"]),
1541
+ T.value !== "hidden" ? (p(), w(e(ee), {
1542
+ key: 0,
1543
+ modelValue: B.value,
1544
+ "onUpdate:modelValue": r[18] || (r[18] = (d) => B.value = d),
1545
+ label: e(l)("fields.is-fullsize")
1546
+ }, null, 8, ["modelValue", "label"])) : U("", !0),
1547
+ i(e(ee), {
1548
+ modelValue: P.value,
1549
+ "onUpdate:modelValue": r[19] || (r[19] = (d) => P.value = d),
1550
+ label: e(l)("fields.in-table")
1551
+ }, null, 8, ["modelValue", "label"])
1552
+ ])
1553
+ ])
1554
+ ]),
1555
+ _: 1
1556
+ }, 8, ["open", "title"]));
1557
+ }
1558
+ }), jt = /* @__PURE__ */ de(Yt, [["__scopeId", "data-v-a3de6c60"]]), Kt = { class: "wx-inbox-field" }, Zt = { class: "wx-inbox-field__name" }, Qt = /* @__PURE__ */ ae({
1559
+ __name: "FieldList",
1560
+ props: /* @__PURE__ */ Se({
1561
+ form: {},
1562
+ canManage: { type: Boolean }
1563
+ }, {
1564
+ modelValue: { required: !0 },
1565
+ modelModifiers: {}
1566
+ }),
1567
+ emits: ["update:modelValue"],
1568
+ setup(a) {
1569
+ const n = a, c = Te(a, "modelValue"), y = se(), b = ye(y), R = ue();
1570
+ re();
1571
+ const t = le("webx-inbox"), l = be(), g = Me(jt);
1572
+ function F(m) {
1573
+ return ie(m.title, R.active.value, m.key);
1574
+ }
1575
+ function E(m) {
1576
+ return [
1577
+ t(`fields.type-${m.type}`),
1578
+ ...m.is_required ? [t("fields.is-required")] : [],
1579
+ ...m.in_table ? [t("fields.in-table")] : [],
1580
+ ...m.is_fullsize ? [] : [t("fields.is-fullsize")]
1581
+ ];
1582
+ }
1583
+ const W = $(() => c.value.length === 0);
1584
+ async function T(m) {
1585
+ const C = await g({ field: m, form: n.form });
1586
+ C && (c.value = m === null ? [...c.value, C] : c.value.map((_) => _.id === C.id ? C : _));
1587
+ }
1588
+ async function S(m) {
1589
+ if (await Oe({
1590
+ title: t("fields.delete-title", { field: F(m) }),
1591
+ message: t("fields.delete-text"),
1592
+ confirmText: t("fields.delete"),
1593
+ cancelText: t("fields.cancel"),
1594
+ tone: "danger"
1595
+ }))
1596
+ try {
1597
+ await b.removeField(m.id), c.value = c.value.filter((_) => _.id !== m.id), H.success(t("panel.deleted"));
1598
+ } catch (_) {
1599
+ H.danger(l(_));
1600
+ }
1601
+ }
1602
+ function v(m) {
1603
+ return n.canManage ? [
1604
+ { key: "edit", icon: "edit", label: t("fields.edit"), run: () => {
1605
+ T(m);
1606
+ } },
1607
+ {
1608
+ key: "delete",
1609
+ icon: "trash",
1610
+ label: t("fields.delete"),
1611
+ danger: !0,
1612
+ run: () => {
1613
+ S(m);
1614
+ }
1615
+ }
1616
+ ] : [];
1617
+ }
1618
+ async function M() {
1619
+ try {
1620
+ await b.sortFields(
1621
+ n.form.id,
1622
+ c.value.map((m) => m.id)
1623
+ );
1624
+ } catch (m) {
1625
+ H.danger(l(m, t("panel.reorder-failed")));
1626
+ }
1627
+ }
1628
+ return (m, C) => (p(), w(e(pt), {
1629
+ title: e(t)("panel.tab-fields")
1630
+ }, ze({
1631
+ default: u(() => [
1632
+ W.value ? (p(), w(e(ht), {
1633
+ key: 0,
1634
+ title: e(t)("fields.no-fields"),
1635
+ description: e(t)("fields.no-fields-help")
1636
+ }, null, 8, ["title", "description"])) : (p(), w(e(vt), {
1637
+ key: 1,
1638
+ modelValue: c.value,
1639
+ "onUpdate:modelValue": C[1] || (C[1] = (_) => c.value = _),
1640
+ plain: "",
1641
+ "item-key": "id",
1642
+ "item-label": F,
1643
+ "drag-label": e(t)("panel.reorder"),
1644
+ disabled: !a.canManage,
1645
+ "aria-label": e(t)("panel.tab-fields"),
1646
+ onMove: M
1647
+ }, {
1648
+ default: u(({ item: _ }) => [
1649
+ D("div", Kt, [
1650
+ D("div", Zt, [
1651
+ i(e(te), {
1652
+ weight: "medium",
1653
+ truncate: ""
1654
+ }, {
1655
+ default: u(() => [
1656
+ q(I(F(_)), 1)
1657
+ ]),
1658
+ _: 2
1659
+ }, 1024),
1660
+ _.is_enabled ? U("", !0) : (p(), w(e(pe), {
1661
+ key: 0,
1662
+ type: "default"
1663
+ }, {
1664
+ default: u(() => [
1665
+ q(I(e(t)("panel.off")), 1)
1666
+ ]),
1667
+ _: 1
1668
+ }))
1669
+ ]),
1670
+ i(e(te), {
1671
+ size: "sm",
1672
+ tone: "muted",
1673
+ truncate: ""
1674
+ }, {
1675
+ default: u(() => [
1676
+ D("code", null, "fields[" + I(_.key) + "]", 1),
1677
+ q(" · " + I(E(_).join(" · ")), 1)
1678
+ ]),
1679
+ _: 2
1680
+ }, 1024)
1681
+ ])
1682
+ ]),
1683
+ actions: u(({ item: _ }) => [
1684
+ i(e(Ve), {
1685
+ actions: v(_),
1686
+ label: F(_)
1687
+ }, null, 8, ["actions", "label"])
1688
+ ]),
1689
+ _: 1
1690
+ }, 8, ["modelValue", "drag-label", "disabled", "aria-label"]))
1691
+ ]),
1692
+ _: 2
1693
+ }, [
1694
+ a.canManage ? {
1695
+ name: "extra",
1696
+ fn: u(() => [
1697
+ i(e(Q), {
1698
+ type: "primary",
1699
+ size: "sm",
1700
+ onClick: C[0] || (C[0] = (_) => T(null))
1701
+ }, {
1702
+ icon: u(() => [
1703
+ i(e(ve), { name: "plus" })
1704
+ ]),
1705
+ default: u(() => [
1706
+ q(" " + I(e(t)("fields.new-field")), 1)
1707
+ ]),
1708
+ _: 1
1709
+ })
1710
+ ]),
1711
+ key: "0"
1712
+ } : void 0
1713
+ ]), 1032, ["title"]));
1714
+ }
1715
+ }), il = /* @__PURE__ */ de(Qt, [["__scopeId", "data-v-db38e823"]]), ul = fe(() => import("./InboxPage-CCYXnZed.js")), rl = fe(() => import("./FormEditorPage-BoHzlFfz.js")), dl = fe(() => import("./StatusesPage-Mra8TB7G.js")), cl = fe(() => import("./SubmissionPage-DVNKYpWH.js"));
1716
+ export {
1717
+ il as F,
1718
+ nl as S,
1719
+ rl as W,
1720
+ de as _,
1721
+ Lt as a,
1722
+ ol as b,
1723
+ ye as c,
1724
+ Vt as d,
1725
+ Mt as e,
1726
+ It as f,
1727
+ ul as g,
1728
+ dl as h,
1729
+ cl as i,
1730
+ al as j,
1731
+ _t as k,
1732
+ sl as o,
1733
+ re as u
1734
+ };
1735
+ //# sourceMappingURL=index-BQj2UlUS.js.map