@webx-ui/module-notifications 0.1.0 → 0.2.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,427 @@
1
+ import { defineComponent as le, ref as v, computed as p, openBlock as o, createBlock as f, unref as a, isRef as Se, withCtx as m, createVNode as g, createTextVNode as V, toDisplayString as B, createCommentVNode as _, createElementBlock as j, Fragment as L, renderList as ie, onMounted as We, onBeforeUnmount as $e, createSlots as Ne, createElementVNode as Ce } from "vue";
2
+ import { useRoute as Te, useRouter as Ve, onBeforeRouteLeave as Be } from "vue-router";
3
+ import { useModal as Ae, WxDialog as Me, WxText as te, WxFormItem as je, WxSelect as De, WxAlert as W, WxSpace as Le, WxButton as P, useLocales as qe, createModal as Ee, confirm as ne, WxSkeleton as Oe, WxBadge as Pe, WxActionBar as Ke, toast as y } from "@webx-ui/core";
4
+ import { useAdmin as re, useTranslate as se, useErrorText as oe, provideHistorySubject as Re, useBodyKeys as Ue, WxScreenHead as ze, WxScreen as Je, WxSaveState as Fe } from "@webx-ui/module-admin";
5
+ import { c as ue, u as ce, p as He, M as Ie, _ as Ge } from "./index-DIeEPPSh.js";
6
+ const Qe = /* @__PURE__ */ le({
7
+ name: "WxNotificationsTestDialog",
8
+ __name: "TestDialog",
9
+ props: {
10
+ channel: { default: null },
11
+ values: {},
12
+ recipients: { default: () => [] }
13
+ },
14
+ setup(q) {
15
+ const w = q, { open: C, dismiss: h } = Ae(), k = ue(re());
16
+ ce();
17
+ const d = se("webx-notifications"), E = oe(), t = v(""), x = v(!1), r = v(null), S = v(null), l = p(() => [
18
+ { value: "", label: d("panel.test-everybody") },
19
+ ...w.recipients
20
+ ]);
21
+ async function i() {
22
+ x.value = !0, S.value = null;
23
+ try {
24
+ r.value = await k.test(w.channel, w.values, t.value === "" ? null : t.value);
25
+ } catch (u) {
26
+ const c = u.body;
27
+ S.value = c?.errors ? Object.values(c.errors).flat().join(" ") : E(u);
28
+ } finally {
29
+ x.value = !1;
30
+ }
31
+ }
32
+ function N(u) {
33
+ const c = u.label ? `${u.label} (${u.recipient})` : u.recipient;
34
+ return u.status === "sent" ? d("panel.test-sent", { recipient: c }) : d("panel.test-failed", {
35
+ recipient: c,
36
+ error: u.error ?? (u.reason ? d(`module.reasons.${u.reason}`) : u.status)
37
+ });
38
+ }
39
+ return (u, c) => (o(), f(a(Me), {
40
+ open: a(C),
41
+ "onUpdate:open": c[2] || (c[2] = (b) => Se(C) ? C.value = b : null),
42
+ title: a(d)("panel.test-title"),
43
+ width: 480
44
+ }, {
45
+ footer: m(() => [
46
+ g(a(Le), { size: "sm" }, {
47
+ default: m(() => [
48
+ g(a(P), {
49
+ variant: "outline",
50
+ onClick: c[1] || (c[1] = (b) => a(h)())
51
+ }, {
52
+ default: m(() => [
53
+ V(B(a(d)("panel.cancel")), 1)
54
+ ]),
55
+ _: 1
56
+ }),
57
+ g(a(P), {
58
+ type: "primary",
59
+ loading: x.value,
60
+ onClick: i
61
+ }, {
62
+ default: m(() => [
63
+ V(B(a(d)("panel.test-send")), 1)
64
+ ]),
65
+ _: 1
66
+ }, 8, ["loading"])
67
+ ]),
68
+ _: 1
69
+ })
70
+ ]),
71
+ default: m(() => [
72
+ g(a(te), {
73
+ size: "sm",
74
+ tone: "muted"
75
+ }, {
76
+ default: m(() => [
77
+ V(B(a(d)("panel.test-help")), 1)
78
+ ]),
79
+ _: 1
80
+ }),
81
+ g(a(je), {
82
+ label: a(d)("panel.test-to")
83
+ }, {
84
+ default: m(() => [
85
+ g(a(De), {
86
+ modelValue: t.value,
87
+ "onUpdate:modelValue": c[0] || (c[0] = (b) => t.value = b),
88
+ options: l.value,
89
+ disabled: x.value
90
+ }, null, 8, ["modelValue", "options", "disabled"])
91
+ ]),
92
+ _: 1
93
+ }, 8, ["label"]),
94
+ S.value ? (o(), f(a(W), {
95
+ key: 0,
96
+ type: "danger",
97
+ variant: "soft",
98
+ description: S.value
99
+ }, null, 8, ["description"])) : _("", !0),
100
+ r.value ? (o(), j(L, { key: 1 }, [
101
+ r.value.length === 0 ? (o(), f(a(te), {
102
+ key: 0,
103
+ size: "sm",
104
+ tone: "muted"
105
+ }, {
106
+ default: m(() => [
107
+ V(B(a(d)("panel.test-none")), 1)
108
+ ]),
109
+ _: 1
110
+ })) : _("", !0),
111
+ (o(!0), j(L, null, ie(r.value, (b, $) => (o(), f(a(W), {
112
+ key: $,
113
+ type: b.status === "sent" ? "success" : "danger",
114
+ variant: "soft",
115
+ description: N(b)
116
+ }, null, 8, ["type", "description"]))), 128))
117
+ ], 64)) : _("", !0)
118
+ ]),
119
+ _: 1
120
+ }, 8, ["open", "title"]));
121
+ }
122
+ }), Xe = { class: "wx-notifications-channel__body" }, Ye = /* @__PURE__ */ le({
123
+ __name: "ChannelPage",
124
+ props: {
125
+ base: { default: "/notifications" }
126
+ },
127
+ setup(q) {
128
+ const w = q, C = re(), h = ue(C), k = Te(), d = Ve(), E = qe();
129
+ ce();
130
+ const t = se("webx-notifications"), x = oe(), r = v(
131
+ typeof k.params.id == "string" && k.params.id !== "" ? Number(k.params.id) : null
132
+ ), S = v(null), l = v(null), i = v({}), N = v(""), u = v([]), c = v({}), b = v(!0), $ = v(!1), O = v(!1), K = He(S, i, r);
133
+ Re({ id: p(() => l.value?.id ?? null) });
134
+ const T = p(() => C.can("notifications.manage")), R = p(() => JSON.stringify(i.value)), A = p(() => N.value !== "" && R.value !== N.value), de = p(() => $.value ? "saving" : A.value || r.value === null ? "unsaved" : "saved"), U = p(() => {
135
+ const e = typeof i.value.name == "string" ? i.value.name.trim() : "";
136
+ return e !== "" ? e : r.value === null ? t("panel.new") : t("panel.untitled");
137
+ }), z = p(
138
+ () => Array.isArray(i.value.forget) ? i.value.forget : []
139
+ ), J = p(
140
+ () => (K.provider.value?.fields ?? []).filter((e) => e.secret).map((e) => ({
141
+ field: e,
142
+ set: l.value?.credentials_set[e.name] === !0 && !z.value.includes(e.name)
143
+ }))
144
+ ), ve = p(() => [
145
+ { op: "set", target: "provider", props: { disabled: !0 } },
146
+ ...J.value.filter((e) => e.set).map((e) => ({
147
+ op: "set",
148
+ target: e.field.name,
149
+ help: t("panel.secret-set"),
150
+ props: { placeholder: "••••••••" }
151
+ }))
152
+ ]);
153
+ function F(e) {
154
+ l.value = e.channel, i.value = e.values, N.value = JSON.stringify(e.values), u.value = e.warnings;
155
+ }
156
+ function pe(e) {
157
+ const n = typeof k.query.provider == "string" ? k.query.provider : "email", s = typeof k.query.event == "string" && k.query.event !== "" ? k.query.event : null, D = e.events.find((M) => M.key === s), Z = D?.sample[n] ?? D?.sample["*"], ee = E.list.value[0]?.code ?? "en", ae = {};
158
+ for (const M of e.providers.find((xe) => xe.key === n)?.fields ?? [])
159
+ ae[M.name] = M.secret ? "" : M.default ?? "";
160
+ return {
161
+ name: "",
162
+ provider: n,
163
+ event: s,
164
+ enabled: !1,
165
+ recipients: [],
166
+ ...ae,
167
+ template: { [ee]: Z?.template ?? "" },
168
+ subject: { [ee]: Z?.subject ?? "" }
169
+ };
170
+ }
171
+ const H = v([]);
172
+ async function fe() {
173
+ b.value = !0;
174
+ try {
175
+ const [e, n] = await Promise.all([
176
+ h.meta(),
177
+ r.value === null ? Promise.resolve(null) : h.get(r.value)
178
+ ]);
179
+ if (S.value = e, n === null) {
180
+ const s = pe(e);
181
+ i.value = s, N.value = JSON.stringify(s);
182
+ } else
183
+ F(n);
184
+ } catch (e) {
185
+ y.danger(x(e)), d.push(w.base);
186
+ } finally {
187
+ b.value = !1;
188
+ }
189
+ i.value.provider === "email" && T.value && h.administrators().then((e) => H.value = e).catch(() => {
190
+ });
191
+ }
192
+ function I(e) {
193
+ const n = e.body;
194
+ n?.errors ? (c.value = n.errors, y.danger(t("panel.save-failed"))) : y.danger(x(e));
195
+ }
196
+ async function G() {
197
+ if (!($.value || !T.value)) {
198
+ $.value = !0, c.value = {};
199
+ try {
200
+ const e = r.value === null, n = e ? await h.create(i.value) : await h.save(r.value, i.value);
201
+ F(n), n.warnings.length > 0 ? y.warning(t("panel.saved-warning", { warning: n.warnings.join(" ") })) : y.success(t("panel.saved")), e && (r.value = n.channel.id, d.replace(`${w.base}/channels/${n.channel.id}`));
202
+ } catch (e) {
203
+ I(e);
204
+ } finally {
205
+ $.value = !1;
206
+ }
207
+ }
208
+ }
209
+ async function me() {
210
+ O.value = !0;
211
+ try {
212
+ const e = await h.check(r.value, i.value);
213
+ e.ok ? y.success(e.message || t("panel.check-ok")) : y.warning(e.message);
214
+ } catch (e) {
215
+ I(e);
216
+ } finally {
217
+ O.value = !1;
218
+ }
219
+ }
220
+ const ye = Ee(Qe), ge = p(() => (Array.isArray(i.value.recipients) ? i.value.recipients : []).flatMap((n) => {
221
+ if (n.chat_id)
222
+ return [
223
+ { value: n.chat_id, label: n.label ? `${n.label} · ${n.chat_id}` : n.chat_id }
224
+ ];
225
+ if (n.email) return [{ value: n.email, label: n.email }];
226
+ const s = H.value.find((D) => D.id === n.admin_id);
227
+ return s ? [{ value: s.email, label: `${s.name} · ${s.email}` }] : [];
228
+ }));
229
+ async function be() {
230
+ await ye({ channel: r.value, values: i.value, recipients: ge.value });
231
+ }
232
+ async function he() {
233
+ if (r.value !== null)
234
+ try {
235
+ const e = await h.copy(r.value);
236
+ y.success(t("panel.copied", { name: e.channel.name })), d.push(`${w.base}/channels/${e.channel.id}`);
237
+ } catch (e) {
238
+ y.danger(x(e));
239
+ }
240
+ }
241
+ async function ke() {
242
+ const e = l.value;
243
+ if (!(!e || !await ne({
244
+ title: t("panel.delete-title", { title: U.value }),
245
+ message: t("panel.delete-text"),
246
+ confirmText: t("panel.delete"),
247
+ cancelText: t("panel.cancel"),
248
+ tone: "danger"
249
+ })))
250
+ try {
251
+ await h.remove(e.id), y.success(t("panel.deleted")), N.value = R.value, d.push(w.base);
252
+ } catch (s) {
253
+ y.danger(x(s));
254
+ }
255
+ }
256
+ function _e(e, n) {
257
+ i.value = { ...i.value, forget: [...z.value, e], [e]: "" }, y.info(t("panel.forgotten", { field: n }));
258
+ }
259
+ function Q(e) {
260
+ A.value && e.preventDefault();
261
+ }
262
+ function X(e) {
263
+ (e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "s" && (e.preventDefault(), (A.value || r.value === null) && G());
264
+ }
265
+ Ue(X), We(() => {
266
+ fe(), window.addEventListener("beforeunload", Q);
267
+ }), $e(() => {
268
+ window.removeEventListener("beforeunload", Q);
269
+ }), Be(async () => !A.value || !T.value ? !0 : await ne({
270
+ title: t("panel.leave-title"),
271
+ message: t("panel.leave-text"),
272
+ confirmText: t("panel.leave"),
273
+ cancelText: t("panel.cancel"),
274
+ tone: "danger"
275
+ }));
276
+ const we = p(() => {
277
+ if (!T.value) return [];
278
+ const e = [
279
+ {
280
+ key: "check",
281
+ label: t("panel.check"),
282
+ icon: "check-circle",
283
+ loading: O.value,
284
+ run: () => {
285
+ me();
286
+ }
287
+ },
288
+ { key: "test", label: t("panel.test"), icon: "send", run: () => {
289
+ be();
290
+ } }
291
+ ];
292
+ l.value !== null && e.push({
293
+ key: "copy",
294
+ label: t("panel.copy"),
295
+ icon: "copy",
296
+ menu: !0,
297
+ run: () => {
298
+ he();
299
+ }
300
+ });
301
+ for (const n of J.value.filter((s) => s.set))
302
+ e.push({
303
+ key: `forget-${n.field.name}`,
304
+ label: t("panel.forget", { field: n.field.label }),
305
+ icon: "unlock",
306
+ menu: !0,
307
+ run: () => _e(n.field.name, n.field.label)
308
+ });
309
+ return l.value !== null && e.push({
310
+ key: "delete",
311
+ label: t("panel.delete"),
312
+ icon: "trash",
313
+ danger: !0,
314
+ run: () => {
315
+ ke();
316
+ }
317
+ }), e;
318
+ }), Y = p(() => S.value?.environment ?? "production");
319
+ return (e, n) => (o(), j("div", {
320
+ class: "wx-notifications-channel",
321
+ onKeydown: X
322
+ }, [
323
+ b.value ? (o(), f(a(Oe), {
324
+ key: 0,
325
+ class: "wx-notifications-channel__ghost",
326
+ title: "",
327
+ rows: 8
328
+ })) : (o(), j(L, { key: 1 }, [
329
+ g(a(ze), {
330
+ back: w.base,
331
+ "back-label": a(t)("panel.channels"),
332
+ title: U.value,
333
+ subtitle: l.value?.provider_label ?? a(K).provider.value?.label,
334
+ actions: we.value
335
+ }, Ne({ _: 2 }, [
336
+ l.value && !l.value.enabled ? {
337
+ name: "title-after",
338
+ fn: m(() => [
339
+ g(a(Pe), { dot: "" }, {
340
+ default: m(() => [
341
+ V(B(a(t)("panel.off")), 1)
342
+ ]),
343
+ _: 1
344
+ })
345
+ ]),
346
+ key: "0"
347
+ } : void 0
348
+ ]), 1032, ["back", "back-label", "title", "subtitle", "actions"]),
349
+ Y.value !== "production" ? (o(), f(a(W), {
350
+ key: 0,
351
+ type: "info",
352
+ variant: "soft",
353
+ description: a(t)("panel.environment", { environment: Y.value })
354
+ }, null, 8, ["description"])) : _("", !0),
355
+ S.value?.mode === "after_response" ? (o(), f(a(W), {
356
+ key: 1,
357
+ type: "warning",
358
+ variant: "soft",
359
+ description: a(t)("panel.mode-after-response")
360
+ }, null, 8, ["description"])) : _("", !0),
361
+ l.value && !l.value.provider_declared ? (o(), f(a(W), {
362
+ key: 2,
363
+ type: "danger",
364
+ title: a(t)("panel.provider-undeclared"),
365
+ description: a(t)("panel.provider-undeclared-text", { provider: l.value.provider })
366
+ }, null, 8, ["title", "description"])) : _("", !0),
367
+ l.value && !l.value.event_declared ? (o(), f(a(W), {
368
+ key: 3,
369
+ type: "warning",
370
+ title: a(t)("panel.event-undeclared"),
371
+ description: a(t)("panel.event-undeclared-text", { event: l.value.event ?? "" })
372
+ }, null, 8, ["title", "description"])) : _("", !0),
373
+ l.value && !l.value.credentials_readable ? (o(), f(a(W), {
374
+ key: 4,
375
+ type: "danger",
376
+ description: a(t)("panel.unreadable")
377
+ }, null, 8, ["description"])) : _("", !0),
378
+ l.value?.copied_from ? (o(), f(a(W), {
379
+ key: 5,
380
+ type: "info",
381
+ variant: "soft",
382
+ description: a(t)("panel.copied-from", { id: String(l.value.copied_from) })
383
+ }, null, 8, ["description"])) : _("", !0),
384
+ (o(!0), j(L, null, ie(u.value, (s) => (o(), f(a(W), {
385
+ key: s,
386
+ type: "warning",
387
+ description: s
388
+ }, null, 8, ["description"]))), 128)),
389
+ Ce("div", Xe, [
390
+ g(a(Je), {
391
+ modelValue: i.value,
392
+ "onUpdate:modelValue": n[0] || (n[0] = (s) => i.value = s),
393
+ class: "wx-notifications-channel__form",
394
+ name: "notifications.channel",
395
+ errors: c.value,
396
+ patch: ve.value,
397
+ disabled: !T.value || $.value
398
+ }, null, 8, ["modelValue", "errors", "patch", "disabled"]),
399
+ g(Ie, { class: "wx-notifications-channel__preview" })
400
+ ]),
401
+ T.value ? (o(), f(a(Ke), { key: 6 }, {
402
+ state: m(() => [
403
+ g(a(Fe), { state: de.value }, null, 8, ["state"])
404
+ ]),
405
+ default: m(() => [
406
+ g(a(P), {
407
+ type: "primary",
408
+ loading: $.value,
409
+ disabled: !A.value && r.value !== null,
410
+ onClick: G
411
+ }, {
412
+ default: m(() => [
413
+ V(B(a(t)("panel.save")), 1)
414
+ ]),
415
+ _: 1
416
+ }, 8, ["loading", "disabled"])
417
+ ]),
418
+ _: 1
419
+ })) : _("", !0)
420
+ ], 64))
421
+ ], 32));
422
+ }
423
+ }), la = /* @__PURE__ */ Ge(Ye, [["__scopeId", "data-v-b5c7b69a"]]);
424
+ export {
425
+ la as default
426
+ };
427
+ //# sourceMappingURL=ChannelPage-C47YoMPO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelPage-C47YoMPO.js","sources":["../src/TestDialog.vue","../src/ChannelPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport {\n useModal,\n WxAlert,\n WxButton,\n WxDialog,\n WxFormItem,\n WxSelect,\n WxSpace,\n WxText,\n} from '@webx-ui/core'\nimport { useAdmin, useErrorText, useTranslate } from '@webx-ui/module-admin'\nimport type { ScreenModel } from '@webx-ui/schema'\nimport { createNotificationsApi } from './api'\nimport { useNotificationsMessages } from './i18n'\nimport type { TestResult } from './types'\n\n/**\n * \"Send a test\" (§8.5): now, past the queue, with the event's example values, to everybody on the\n * list or to one of them — through the form's values, saved or not, and through a channel that\n * is switched off, which is what a test is for. What happened to each recipient stays in the\n * dialog: a test that failed is read, not dismissed with a toast.\n */\ndefineOptions({ name: 'WxNotificationsTestDialog' })\n\nconst props = withDefaults(\n defineProps<{\n channel?: number | null\n values: ScreenModel\n /** The fixed recipients, as the server knows them by: a chat id, an address. */\n recipients?: { value: string; label: string }[]\n }>(),\n { channel: null, recipients: () => [] },\n)\n\nconst { open, dismiss } = useModal<void>()\n\nconst api = createNotificationsApi(useAdmin())\nuseNotificationsMessages()\n\nconst t = useTranslate('webx-notifications')\nconst message = useErrorText()\n\nconst to = ref('')\nconst sending = ref(false)\nconst results = ref<TestResult[] | null>(null)\nconst failure = ref<string | null>(null)\n\nconst options = computed(() => [\n { value: '', label: t('panel.test-everybody') },\n ...props.recipients,\n])\n\nasync function send(): Promise<void> {\n sending.value = true\n failure.value = null\n\n try {\n results.value = await api.test(props.channel, props.values, to.value === '' ? null : to.value)\n } catch (error) {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n failure.value = body?.errors ? Object.values(body.errors).flat().join(' ') : message(error)\n } finally {\n sending.value = false\n }\n}\n\nfunction lineOf(result: TestResult): string {\n const recipient = result.label ? `${result.label} (${result.recipient})` : result.recipient\n\n if (result.status === 'sent') return t('panel.test-sent', { recipient })\n\n return t('panel.test-failed', {\n recipient,\n error: result.error ?? (result.reason ? t(`module.reasons.${result.reason}`) : result.status),\n })\n}\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('panel.test-title')\" :width=\"480\">\n <wx-text size=\"sm\" tone=\"muted\">{{ t('panel.test-help') }}</wx-text>\n\n <wx-form-item :label=\"t('panel.test-to')\">\n <wx-select v-model=\"to\" :options=\"options\" :disabled=\"sending\" />\n </wx-form-item>\n\n <wx-alert v-if=\"failure\" type=\"danger\" variant=\"soft\" :description=\"failure\" />\n\n <template v-if=\"results\">\n <wx-text v-if=\"results.length === 0\" size=\"sm\" tone=\"muted\">{{\n t('panel.test-none')\n }}</wx-text>\n <wx-alert\n v-for=\"(result, index) in results\"\n :key=\"index\"\n :type=\"result.status === 'sent' ? 'success' : 'danger'\"\n variant=\"soft\"\n :description=\"lineOf(result)\"\n />\n </template>\n\n <template #footer>\n <wx-space size=\"sm\">\n <wx-button variant=\"outline\" @click=\"dismiss()\">{{ t('panel.cancel') }}</wx-button>\n <wx-button type=\"primary\" :loading=\"sending\" @click=\"send\">\n {{ t('panel.test-send') }}\n </wx-button>\n </wx-space>\n </template>\n </wx-dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport { onBeforeRouteLeave, useRoute, useRouter } from 'vue-router'\nimport {\n confirm,\n createModal,\n toast,\n useLocales,\n WxActionBar,\n WxAlert,\n WxBadge,\n WxButton,\n WxSkeleton,\n} from '@webx-ui/core'\nimport {\n provideHistorySubject,\n useAdmin,\n useBodyKeys,\n useErrorText,\n useTranslate,\n WxSaveState,\n WxScreen,\n WxScreenHead,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport type { Patch, ScreenModel } from '@webx-ui/schema'\nimport { createNotificationsApi } from './api'\nimport { provideChannel } from './context'\nimport { useNotificationsMessages } from './i18n'\nimport MessagePreview from './MessagePreview.vue'\nimport TestDialog from './TestDialog.vue'\nimport type {\n Administrator,\n ChannelDetail,\n ChannelRow,\n ChatRecipient,\n EmailRecipient,\n NotificationsMeta,\n} from './types'\n\n/**\n * One channel (§10.3): the described screen `notifications.channel` — the common part and the\n * provider's settings the server lays over it — with the live preview beside it on a wide pane and\n * under it on a narrow one, and one explicit save.\n *\n * A secret is never in the form: the server answers which are set, and the field says so with\n * `••••••••` until a new one is typed. \"Forget\" is in the head's menu, one per secret that is set,\n * and takes effect on the save, like every other change here.\n *\n * The form's values are what \"Check\", \"Send a test\" and the preview run on — saved or not: a\n * channel is tried before it is kept, and a test of a switched-off channel is the point of one.\n */\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/notifications' })\n\nconst admin = useAdmin()\nconst api = createNotificationsApi(admin)\nconst route = useRoute()\nconst router = useRouter()\nconst locales = useLocales()\nuseNotificationsMessages()\n\nconst t = useTranslate('webx-notifications')\n/* Not the server's `message`: the panel says how a request failed in its own words. */\nconst message = useErrorText()\n\nconst id = ref<number | null>(\n typeof route.params.id === 'string' && route.params.id !== '' ? Number(route.params.id) : null,\n)\n\nconst meta = ref<NotificationsMeta | null>(null)\nconst channel = ref<ChannelRow | null>(null)\nconst values = ref<ScreenModel>({})\nconst snapshot = ref('')\nconst warnings = ref<string[]>([])\nconst errors = ref<Record<string, string[]>>({})\nconst loading = ref(true)\nconst saving = ref(false)\nconst checking = ref(false)\n\nconst context = provideChannel(meta, values, id)\n\nprovideHistorySubject({ id: computed(() => channel.value?.id ?? null) })\n\nconst canManage = computed(() => admin.can('notifications.manage'))\n\nconst current = computed(() => JSON.stringify(values.value))\nconst dirty = computed(() => snapshot.value !== '' && current.value !== snapshot.value)\n\nconst state = computed<'saving' | 'unsaved' | 'saved'>(() => {\n if (saving.value) return 'saving'\n\n return dirty.value || id.value === null ? 'unsaved' : 'saved'\n})\n\nconst title = computed(() => {\n const written = typeof values.value.name === 'string' ? values.value.name.trim() : ''\n\n if (written !== '') return written\n\n return id.value === null ? t('panel.new') : t('panel.untitled')\n})\n\nconst forgetting = computed<string[]>(() =>\n Array.isArray(values.value.forget) ? (values.value.forget as string[]) : [],\n)\n\n/** The provider's secret settings, and whether each is set on the saved channel. */\nconst secrets = computed(() =>\n (context.provider.value?.fields ?? [])\n .filter((field) => field.secret)\n .map((field) => ({\n field,\n set:\n channel.value?.credentials_set[field.name] === true &&\n !forgetting.value.includes(field.name),\n })),\n)\n\n/*\n * What only this page knows about the tree: the kind of channel is chosen once, and a secret that\n * is set says so instead of showing an empty field that reads as \"not set\".\n */\nconst patch = computed<Patch>(() => [\n { op: 'set', target: 'provider', props: { disabled: true } },\n ...secrets.value\n .filter((one) => one.set)\n .map((one): Patch[number] => ({\n op: 'set',\n target: one.field.name,\n help: t('panel.secret-set'),\n props: { placeholder: '••••••••' },\n })),\n])\n\nfunction take(detail: ChannelDetail): void {\n channel.value = detail.channel\n values.value = detail.values\n snapshot.value = JSON.stringify(detail.values)\n warnings.value = detail.warnings\n}\n\n/** What the server would answer for a channel with nothing in it yet, and the event's sample. */\nfunction blank(found: NotificationsMeta): ScreenModel {\n const provider = typeof route.query.provider === 'string' ? route.query.provider : 'email'\n const event =\n typeof route.query.event === 'string' && route.query.event !== '' ? route.query.event : null\n const definition = found.events.find((one) => one.key === event)\n const sample = definition?.sample[provider] ?? definition?.sample['*']\n const locale = locales.list.value[0]?.code ?? 'en'\n const settings: ScreenModel = {}\n\n for (const field of found.providers.find((one) => one.key === provider)?.fields ?? []) {\n settings[field.name] = field.secret ? '' : (field.default ?? '')\n }\n\n return {\n name: '',\n provider,\n event,\n enabled: false,\n recipients: [],\n ...settings,\n template: { [locale]: sample?.template ?? '' },\n subject: { [locale]: sample?.subject ?? '' },\n }\n}\n\nconst administrators = ref<Administrator[]>([])\n\nasync function load(): Promise<void> {\n loading.value = true\n\n try {\n const [found, detail] = await Promise.all([\n api.meta(),\n id.value === null ? Promise.resolve(null) : api.get(id.value),\n ])\n\n meta.value = found\n\n if (detail === null) {\n const made = blank(found)\n\n values.value = made\n snapshot.value = JSON.stringify(made)\n } else {\n take(detail)\n }\n } catch (error) {\n toast.danger(message(error))\n void router.push(props.base)\n } finally {\n loading.value = false\n }\n\n if (values.value.provider === 'email' && canManage.value) {\n api\n .administrators()\n .then((found) => (administrators.value = found))\n .catch(() => undefined)\n }\n}\n\nfunction refusal(error: unknown): void {\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n if (body?.errors) {\n errors.value = body.errors\n toast.danger(t('panel.save-failed'))\n } else {\n toast.danger(message(error))\n }\n}\n\nasync function save(): Promise<void> {\n if (saving.value || !canManage.value) return\n\n saving.value = true\n errors.value = {}\n\n try {\n const made = id.value === null\n const detail = made\n ? await api.create(values.value)\n : await api.save(id.value as number, values.value)\n\n take(detail)\n\n if (detail.warnings.length > 0) {\n toast.warning(t('panel.saved-warning', { warning: detail.warnings.join(' ') }))\n } else {\n toast.success(t('panel.saved'))\n }\n\n if (made) {\n id.value = detail.channel.id\n // Nothing left to protect: the record exists, and its address is the one to keep.\n void router.replace(`${props.base}/channels/${detail.channel.id}`)\n }\n } catch (error) {\n refusal(error)\n } finally {\n saving.value = false\n }\n}\n\nasync function check(): Promise<void> {\n checking.value = true\n\n try {\n const answer = await api.check(id.value, values.value)\n\n if (answer.ok) toast.success(answer.message || t('panel.check-ok'))\n else toast.warning(answer.message)\n } catch (error) {\n refusal(error)\n } finally {\n checking.value = false\n }\n}\n\nconst tester = createModal<\n void,\n { channel?: number | null; values: ScreenModel; recipients?: { value: string; label: string }[] }\n>(TestDialog)\n\n/** The fixed recipients as the server knows them by: a chat id, an address. */\nconst fixed = computed(() => {\n const list = Array.isArray(values.value.recipients) ? values.value.recipients : []\n\n return (list as (ChatRecipient & EmailRecipient)[]).flatMap((one) => {\n if (one.chat_id)\n return [\n { value: one.chat_id, label: one.label ? `${one.label} · ${one.chat_id}` : one.chat_id },\n ]\n if (one.email) return [{ value: one.email, label: one.email }]\n\n const found = administrators.value.find((person) => person.id === one.admin_id)\n\n return found ? [{ value: found.email, label: `${found.name} · ${found.email}` }] : []\n })\n})\n\nasync function test(): Promise<void> {\n await tester({ channel: id.value, values: values.value, recipients: fixed.value })\n}\n\nasync function copy(): Promise<void> {\n if (id.value === null) return\n\n try {\n const detail = await api.copy(id.value)\n\n toast.success(t('panel.copied', { name: detail.channel.name }))\n void router.push(`${props.base}/channels/${detail.channel.id}`)\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function remove(): Promise<void> {\n const row = channel.value\n\n if (!row) return\n\n const agreed = await confirm({\n title: t('panel.delete-title', { title: title.value }),\n message: t('panel.delete-text'),\n confirmText: t('panel.delete'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.remove(row.id)\n toast.success(t('panel.deleted'))\n snapshot.value = current.value\n void router.push(props.base)\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction forget(name: string, label: string): void {\n values.value = { ...values.value, forget: [...forgetting.value, name], [name]: '' }\n toast.info(t('panel.forgotten', { field: label }))\n}\n\n/* The browser's own guard: it cannot wait for a request, so all it can do is ask. */\nfunction leaveGuard(event: BeforeUnloadEvent): void {\n if (dirty.value) event.preventDefault()\n}\n\n/* Ctrl+S saves, as it does everywhere else that has a save button. */\nfunction onKeydown(event: KeyboardEvent): void {\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 's') {\n event.preventDefault()\n if (dirty.value || id.value === null) void save()\n }\n}\n\nuseBodyKeys(onKeydown)\n\nonMounted(() => {\n void load()\n window.addEventListener('beforeunload', leaveGuard)\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('beforeunload', leaveGuard)\n})\n\nonBeforeRouteLeave(async () => {\n if (!dirty.value || !canManage.value) return true\n\n return await confirm({\n title: t('panel.leave-title'),\n message: t('panel.leave-text'),\n confirmText: t('panel.leave'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n})\n\nconst actions = computed<ScreenAction[]>(() => {\n if (!canManage.value) return []\n\n const list: ScreenAction[] = [\n {\n key: 'check',\n label: t('panel.check'),\n icon: 'check-circle',\n loading: checking.value,\n run: () => void check(),\n },\n { key: 'test', label: t('panel.test'), icon: 'send', run: () => void test() },\n ]\n\n if (channel.value !== null) {\n list.push({\n key: 'copy',\n label: t('panel.copy'),\n icon: 'copy',\n menu: true,\n run: () => void copy(),\n })\n }\n\n for (const one of secrets.value.filter((secret) => secret.set)) {\n list.push({\n key: `forget-${one.field.name}`,\n label: t('panel.forget', { field: one.field.label }),\n icon: 'unlock',\n menu: true,\n run: () => forget(one.field.name, one.field.label),\n })\n }\n\n if (channel.value !== null) {\n list.push({\n key: 'delete',\n label: t('panel.delete'),\n icon: 'trash',\n danger: true,\n run: () => void remove(),\n })\n }\n\n return list\n})\n\nconst environment = computed(() => meta.value?.environment ?? 'production')\n</script>\n\n<template>\n <div class=\"wx-notifications-channel\" @keydown=\"onKeydown\">\n <wx-skeleton v-if=\"loading\" class=\"wx-notifications-channel__ghost\" title :rows=\"8\" />\n\n <template v-else>\n <wx-screen-head\n :back=\"props.base\"\n :back-label=\"t('panel.channels')\"\n :title=\"title\"\n :subtitle=\"channel?.provider_label ?? context.provider.value?.label\"\n :actions=\"actions\"\n >\n <template v-if=\"channel && !channel.enabled\" #title-after>\n <wx-badge dot>{{ t('panel.off') }}</wx-badge>\n </template>\n </wx-screen-head>\n\n <wx-alert\n v-if=\"environment !== 'production'\"\n type=\"info\"\n variant=\"soft\"\n :description=\"t('panel.environment', { environment })\"\n />\n <wx-alert\n v-if=\"meta?.mode === 'after_response'\"\n type=\"warning\"\n variant=\"soft\"\n :description=\"t('panel.mode-after-response')\"\n />\n <wx-alert\n v-if=\"channel && !channel.provider_declared\"\n type=\"danger\"\n :title=\"t('panel.provider-undeclared')\"\n :description=\"t('panel.provider-undeclared-text', { provider: channel.provider })\"\n />\n <wx-alert\n v-if=\"channel && !channel.event_declared\"\n type=\"warning\"\n :title=\"t('panel.event-undeclared')\"\n :description=\"t('panel.event-undeclared-text', { event: channel.event ?? '' })\"\n />\n <wx-alert\n v-if=\"channel && !channel.credentials_readable\"\n type=\"danger\"\n :description=\"t('panel.unreadable')\"\n />\n <wx-alert\n v-if=\"channel?.copied_from\"\n type=\"info\"\n variant=\"soft\"\n :description=\"t('panel.copied-from', { id: String(channel.copied_from) })\"\n />\n <wx-alert v-for=\"warning in warnings\" :key=\"warning\" type=\"warning\" :description=\"warning\" />\n\n <div class=\"wx-notifications-channel__body\">\n <wx-screen\n v-model=\"values\"\n class=\"wx-notifications-channel__form\"\n name=\"notifications.channel\"\n :errors=\"errors\"\n :patch=\"patch\"\n :disabled=\"!canManage || saving\"\n />\n\n <message-preview class=\"wx-notifications-channel__preview\" />\n </div>\n\n <wx-action-bar v-if=\"canManage\">\n <template #state>\n <wx-save-state :state=\"state\" />\n </template>\n\n <wx-button type=\"primary\" :loading=\"saving\" :disabled=\"!dirty && id !== null\" @click=\"save\">\n {{ t('panel.save') }}\n </wx-button>\n </wx-action-bar>\n </template>\n </div>\n</template>\n\n<style scoped>\n.wx-notifications-channel {\n display: flex;\n flex-direction: column;\n gap: var(--wx-gap, var(--wx-space-16));\n min-width: 0;\n container-type: inline-size;\n}\n\n.wx-notifications-channel__ghost {\n max-width: 480px;\n}\n\n.wx-notifications-channel__body {\n display: flex;\n flex-direction: column;\n gap: var(--wx-gap, var(--wx-space-16));\n min-width: 0;\n}\n\n.wx-notifications-channel__form,\n.wx-notifications-channel__preview {\n min-width: 0;\n}\n\n/*\n * Beside the form once the pane has room for both, and staying in view while the template is\n * scrolled to: the preview is read while typing, not after.\n */\n@container (min-width: 1040px) {\n .wx-notifications-channel__body {\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(320px, 400px);\n align-items: start;\n }\n\n .wx-notifications-channel__preview {\n position: sticky;\n top: var(--wx-space-16);\n }\n}\n</style>\n"],"names":["props","__props","open","dismiss","useModal","api","createNotificationsApi","useAdmin","useNotificationsMessages","t","useTranslate","message","useErrorText","to","ref","sending","results","failure","options","computed","send","error","body","lineOf","result","recipient","_createBlock","_unref","WxDialog","$event","_createVNode","WxSpace","WxButton","WxText","WxFormItem","WxSelect","WxAlert","_createElementBlock","_Fragment","_openBlock","_renderList","index","admin","route","useRoute","router","useRouter","locales","useLocales","id","meta","channel","values","snapshot","warnings","errors","loading","saving","checking","context","provideChannel","provideHistorySubject","canManage","current","dirty","state","title","written","forgetting","secrets","field","patch","one","take","detail","blank","found","provider","event","definition","sample","locale","settings","administrators","load","made","toast","refusal","save","check","answer","tester","createModal","TestDialog","fixed","person","test","copy","remove","row","confirm","forget","name","label","leaveGuard","onKeydown","useBodyKeys","onMounted","onBeforeUnmount","onBeforeRouteLeave","actions","list","secret","environment","WxSkeleton","WxScreenHead","WxBadge","warning","_createElementVNode","_hoisted_1","WxScreen","MessagePreview","WxActionBar","WxSaveState"],"mappings":"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"}
@@ -17,7 +17,7 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
17
17
  }>, {
18
18
  disabled: boolean;
19
19
  base: string;
20
- emptyText: string;
21
20
  addText: string;
21
+ emptyText: string;
22
22
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
23
23
  export default _default;