@webx-ui/module-notifications 0.2.1 → 0.3.1

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,1416 @@
1
+ import { defineComponent as P, useModel as K, computed as m, openBlock as p, createElementBlock as w, createVNode as g, unref as s, createBlock as _, withCtx as f, createTextVNode as y, toDisplayString as h, createCommentVNode as j, mergeModels as G, provide as Ce, inject as Se, ref as A, onMounted as ae, isRef as Ae, Fragment as F, renderList as L, createElementVNode as D, mergeProps as fe, watch as je, onBeforeUnmount as We, normalizeStyle as Ne, defineAsyncComponent as me } from "vue";
2
+ import { useRouter as Ve } from "vue-router";
3
+ import { WxLink as Oe, useModal as ze, WxDialog as Fe, WxSkeleton as Ee, WxAlert as H, WxEmpty as Me, WxCheckbox as Le, WxText as W, WxBadge as le, WxSpace as se, WxButton as O, createModal as Pe, WxInput as J, WxAction as he, WxIcon as q, toast as Y, WxSelect as Re, useLocales as ve, mustacheCompletions as Ue, mustacheProblems as Be, WxCodeEditor as Ie, WxTooltip as De, confirm as He, localizedValue as oe, WxCard as qe } from "@webx-ui/core";
4
+ import { useAdmin as Q, useTranslate as R, WxRelationsField as Ke, useErrorText as Ge, useRemoveConfirm as be } from "@webx-ui/module-admin";
5
+ import Qe from "mustache";
6
+ const Xe = {
7
+ module: {
8
+ title: "Notifications",
9
+ channel: "Channel",
10
+ statuses: {
11
+ queued: "Queued",
12
+ sent: "Sent",
13
+ failed: "Failed",
14
+ skipped: "Skipped"
15
+ },
16
+ reasons: {
17
+ channel_deleted: "The channel is deleted",
18
+ channel_disabled: "The channel is switched off",
19
+ wrong_event: "The channel is for another event",
20
+ provider_missing: "The provider is not installed",
21
+ no_recipients: "The channel has no recipients",
22
+ no_address: "The event brought no address",
23
+ admin_deleted: "The administrator is deleted",
24
+ admin_inactive: "The administrator is switched off"
25
+ }
26
+ },
27
+ screen: {
28
+ "any-event": "Any event"
29
+ },
30
+ panel: {
31
+ channels: "Channels",
32
+ log: "Log",
33
+ bin: "Bin",
34
+ new: "New channel",
35
+ untitled: "Untitled channel",
36
+ "new-title": "New channel",
37
+ "new-help": "The kind is chosen once. An event is optional: with one, the editor knows its variables and only that event offers the channel.",
38
+ "new-provider": "Kind",
39
+ "new-event": "For the event",
40
+ "new-create": "Continue",
41
+ "any-event": "Any event",
42
+ "event-undeclared": "Event not declared",
43
+ "event-undeclared-text": "No installed module declares “:event” any more. The channel works as one for any event.",
44
+ "provider-undeclared": "Provider not installed",
45
+ "provider-undeclared-text": "The provider “:provider” is not installed on the site: the channel sends nothing.",
46
+ unreadable: "The channel's secrets cannot be read: the application key has changed. Enter them again.",
47
+ recipients: "Recipients: :count",
48
+ "never-sent": "Nothing sent yet",
49
+ off: "Off",
50
+ enable: "Enabled",
51
+ enabled: "Switched on.",
52
+ disabled: "Switched off.",
53
+ edit: "Edit",
54
+ copy: "Make a copy",
55
+ copied: "A copy is made, switched off: “:name”.",
56
+ "copied-from": "The secrets were copied from channel #:id. Replace them if this channel needs another bot or server.",
57
+ delete: "Delete",
58
+ "delete-title": "Delete “:title”?",
59
+ "delete-text": "The channel goes to the bin and sends nothing. The modules that chose it keep it, and it comes back to them when it is restored.",
60
+ deleted: "The channel is in the bin.",
61
+ restore: "Restore",
62
+ restored: "The channel is back.",
63
+ purge: "Delete for good",
64
+ "purge-title": "Delete “:title” for good?",
65
+ "purge-text": "The channel disappears from every module that chose it. Its lines in the log stay, without a link to it.",
66
+ purged: "The channel is deleted for good.",
67
+ cancel: "Cancel",
68
+ save: "Save",
69
+ saved: "Saved.",
70
+ "saved-warning": "Saved, but look: :warning",
71
+ "save-failed": "Not saved: look at the fields marked in red.",
72
+ "leave-title": "Leave without saving?",
73
+ "leave-text": "The changes to this channel will be lost.",
74
+ leave: "Leave",
75
+ "empty-channels-text": "A channel is where notifications go and how they read: a Telegram bot and its chats, or e-mail and its addresses.",
76
+ "empty-bin": "The bin is empty",
77
+ environment: "The site runs as “:environment”: notifications are sent all the same. Switch channels off on a copy of the site.",
78
+ "mode-after-response": "The site has no queue worker: notifications are sent right after the page answers, without retries in the background.",
79
+ "secret-set": "Set. Type a new one to replace it.",
80
+ forget: "Forget :field",
81
+ forgotten: ":field will be forgotten on save.",
82
+ check: "Check the connection",
83
+ "check-ok": "Connection works.",
84
+ test: "Send a test",
85
+ "test-title": "Send a test",
86
+ "test-help": "Sent now, past the queue, with the example values of the event — even through a channel that is switched off. What the form has is used, saved or not.",
87
+ "test-to": "To",
88
+ "test-everybody": "Everybody on the list",
89
+ "test-send": "Send",
90
+ "test-sent": "Sent to :recipient.",
91
+ "test-failed": "Not sent to :recipient: :error",
92
+ "test-none": "The channel has no recipients to send a test to.",
93
+ preview: "Preview",
94
+ "preview-help": "The message as it goes out, on the example values of the event.",
95
+ "preview-no-event": "For any event: the variables are empty here.",
96
+ "preview-subject": "Subject",
97
+ "preview-empty": "The message is empty.",
98
+ "preview-truncated": "Longer than :limit characters: Telegram gets it as plain text, cut to fit.",
99
+ "preview-unknown": "Empty in this message: :names.",
100
+ "preview-refused": "The template cannot be drawn:",
101
+ variables: "Variables",
102
+ "variables-help": "A click puts it where the cursor is; type {{ to see them in the editor.",
103
+ "variables-none": "A channel for any event knows no variables. Choose an event to get its list, or type the names it gives.",
104
+ "default-insert": "Insert the default template",
105
+ "default-title": "Replace the message with the default template?",
106
+ "default-text": "The subject and the template in every language become the ones the event suggests. What is written now is lost once you save.",
107
+ "default-replace": "Replace",
108
+ "default-inserted": "The event's default template is in the message. Save to keep it.",
109
+ "variable-list": "list of :fields",
110
+ "problem-unclosed": "The section {{#:name}} is not closed: end it with {{/:name}}.",
111
+ "problem-stray": "{{/:name}} closes a section that was never opened.",
112
+ "problem-unknown": "Not a variable of this event: :names.",
113
+ "problem-refused": ":tag is not available in a message template.",
114
+ "problem-broken": "A tag is not closed: end it with }}.",
115
+ "hint-variable": "variable",
116
+ "hint-list": "list",
117
+ "hint-field": "field of :list",
118
+ "hint-section": "shown when :name has a value",
119
+ "hint-inverted": "shown when :name is empty",
120
+ "hint-close": "closes :name",
121
+ "hint-comment": "a comment, never printed",
122
+ "hint-example": "Example: :example",
123
+ "add-chat": "Add a chat",
124
+ "chat-id": "Chat id",
125
+ "chat-label": "Label",
126
+ "find-chats": "Find chats",
127
+ "find-title": "Chats the bot has seen",
128
+ "find-help": "Write to the bot, or add it to a group and write there, then search again.",
129
+ "find-add": "Add the chosen",
130
+ "find-token": "Type the bot token first.",
131
+ "find-added": "Chats added: :count.",
132
+ "chat-private": "Private",
133
+ "chat-group": "Group",
134
+ "chat-supergroup": "Supergroup",
135
+ "chat-channel": "Channel",
136
+ addressee: "From the event: :label",
137
+ "add-admin": "Add an administrator",
138
+ "add-email": "Add an address",
139
+ "admin-unknown": "Administrator #:id",
140
+ remove: "Remove",
141
+ "no-recipients": "No recipients yet.",
142
+ "column-when": "When",
143
+ "column-channel": "Channel",
144
+ "column-recipient": "Recipient",
145
+ "column-status": "Status",
146
+ "column-attempts": "Attempts",
147
+ "all-statuses": "Any status",
148
+ "all-channels": "Any channel",
149
+ "with-tests": "Tests too",
150
+ "test-mark": "Test",
151
+ "cut-mark": "Cut",
152
+ "log-empty": "Nothing sent yet.",
153
+ retry: "Send again",
154
+ retried: "Queued again.",
155
+ "open-subject": "Open",
156
+ "unknown-variables": "Empty variables: :names",
157
+ "channel-gone": "deleted",
158
+ filters: "Filters",
159
+ "pick-channels": "Choose channels",
160
+ "set-up-channels": "Set up channels"
161
+ },
162
+ errors: {
163
+ "template-unclosed": "The section {{#:section}} is not closed: end it with {{/:section}}.",
164
+ "template-unexpected": "{{/:section}} closes a section that was never opened.",
165
+ "template-tag": "The tag {{:tag is not closed: end it with }}.",
166
+ "template-name": "{{:name}} is not a variable name: lowercase letters, digits and _, one dot at most.",
167
+ "template-partial": "Partials ({{>name}}) are not available in a message template.",
168
+ "template-delimiters": "Changing the delimiters ({{=<% %>=}}) is not available in a message template.",
169
+ "template-pragma": "Pragmas and blocks ({{%…}}, {{$…}}) are not available in a message template."
170
+ }
171
+ }, re = /* @__PURE__ */ new WeakSet();
172
+ function U() {
173
+ try {
174
+ const { i18n: t } = Q();
175
+ re.has(t) || (t.defaults("webx-notifications", Xe), re.add(t));
176
+ } catch {
177
+ }
178
+ }
179
+ const Ze = { class: "wx-notification-channels" }, Je = /* @__PURE__ */ P({
180
+ name: "WxNotificationChannelsField",
181
+ __name: "ChannelsField",
182
+ props: /* @__PURE__ */ G({
183
+ event: {},
184
+ disabled: { type: Boolean, default: !1 },
185
+ base: { default: "/notifications" },
186
+ addText: { default: void 0 },
187
+ emptyText: { default: void 0 }
188
+ }, {
189
+ modelValue: { default: () => [] },
190
+ modelModifiers: {}
191
+ }),
192
+ emits: ["update:modelValue"],
193
+ setup(t) {
194
+ const e = t, a = K(t, "modelValue");
195
+ U();
196
+ const l = Q(), n = R("webx-notifications"), i = m(() => `notify-${e.event.replace(/[._]/g, "-")}`), r = m(() => l.can("notifications.manage")), u = Ve(), b = m(() => `${l.basePath}${e.base}`.replace(/\/{2,}/g, "/"));
197
+ function k(v) {
198
+ v.metaKey || v.ctrlKey || v.shiftKey || v.button !== 0 || (v.preventDefault(), u.push(e.base));
199
+ }
200
+ return (v, x) => (p(), w("div", Ze, [
201
+ g(s(Ke), {
202
+ modelValue: a.value,
203
+ "onUpdate:modelValue": x[0] || (x[0] = (C) => a.value = C),
204
+ target: i.value,
205
+ sortable: !1,
206
+ disabled: e.disabled,
207
+ "add-text": e.addText ?? s(n)("panel.pick-channels"),
208
+ "empty-text": e.emptyText
209
+ }, null, 8, ["modelValue", "target", "disabled", "add-text", "empty-text"]),
210
+ r.value ? (p(), _(s(Oe), {
211
+ key: 0,
212
+ href: b.value,
213
+ size: "sm",
214
+ onClick: k
215
+ }, {
216
+ default: f(() => [
217
+ y(h(s(n)("panel.set-up-channels")), 1)
218
+ ]),
219
+ _: 1
220
+ }, 8, ["href"])) : j("", !0)
221
+ ]));
222
+ }
223
+ }), B = (t, e) => {
224
+ const a = t.__vccOpts || t;
225
+ for (const [l, n] of e)
226
+ a[l] = n;
227
+ return a;
228
+ }, Ye = /* @__PURE__ */ B(Je, [["__scopeId", "data-v-e0a57880"]]);
229
+ function ge() {
230
+ const t = A(null), e = /* @__PURE__ */ new Map();
231
+ return {
232
+ focused: t,
233
+ inserters: e,
234
+ insert: (a) => (e.get(t.value ?? "") ?? e.get("template"))?.(a)
235
+ };
236
+ }
237
+ const we = /* @__PURE__ */ Symbol("wx-notifications-channel");
238
+ function Zt(t, e, a) {
239
+ const l = {
240
+ meta: t,
241
+ values: e,
242
+ id: a,
243
+ provider: m(
244
+ () => t.value?.providers.find((n) => n.key === e.value.provider) ?? null
245
+ ),
246
+ event: m(() => t.value?.events.find((n) => n.key === e.value.event) ?? null),
247
+ ...ge()
248
+ };
249
+ return Ce(we, l), l;
250
+ }
251
+ function X() {
252
+ return Se(we, null) ?? {
253
+ meta: A(null),
254
+ values: A({}),
255
+ id: A(null),
256
+ provider: m(() => null),
257
+ event: m(() => null),
258
+ ...ge()
259
+ };
260
+ }
261
+ const et = "notifications";
262
+ function tt(t) {
263
+ const e = new URLSearchParams();
264
+ for (const [l, n] of Object.entries(t))
265
+ n == null || n === "" || e.set(l, typeof n == "boolean" ? n ? "1" : "0" : String(n));
266
+ const a = e.toString();
267
+ return a === "" ? "" : `?${a}`;
268
+ }
269
+ function ye(t) {
270
+ const e = `${t.apiPath}/${et}`, a = (n) => n.data, l = (n) => n === null ? e : `${e}/channels/${n}`;
271
+ return {
272
+ meta: () => t.http.get(`${e}/meta`).then(a),
273
+ channels: (n = {}) => {
274
+ const i = new URLSearchParams();
275
+ n.trashed && i.set("trashed", "1"), n.event && i.set("event", n.event);
276
+ const r = i.toString();
277
+ return t.http.get(`${e}/channels${r === "" ? "" : `?${r}`}`);
278
+ },
279
+ get: (n) => t.http.get(`${e}/channels/${n}`).then(a),
280
+ create: (n) => t.http.post(`${e}/channels`, { values: n }).then(a),
281
+ save: (n, i) => t.http.put(`${e}/channels/${n}`, { values: i }).then(a),
282
+ remove: (n) => t.http.delete(`${e}/channels/${n}`).then(() => {
283
+ }),
284
+ restore: (n) => t.http.post(`${e}/channels/${n}/restore`, {}).then(a),
285
+ purge: (n) => t.http.delete(`${e}/channels/${n}/purge`).then(() => {
286
+ }),
287
+ copy: (n, i) => t.http.post(`${e}/channels/${n}/copy`, i ? { name: i } : {}).then(a),
288
+ test: (n, i, r) => t.http.post(`${l(n)}/test`, {
289
+ values: i,
290
+ ...r ? { recipient: r } : {}
291
+ }).then((u) => u.data.results),
292
+ preview: (n, i, r) => t.http.post(`${l(n)}/preview`, { values: i, locale: r }).then(a),
293
+ check: (n, i) => t.http.post(`${e}/check`, { values: i, ...n ? { channel: n } : {} }).then(a),
294
+ findRecipients: ({ provider: n, channel: i, token: r }) => t.http.post(
295
+ `${e}/find-recipients`,
296
+ { provider: n, ...i ? { channel: i } : {}, ...r ? { token: r } : {} }
297
+ ).then(a),
298
+ administrators: () => t.http.get(`${e}/administrators`).then(a),
299
+ deliveries: (n = {}) => t.http.get(`${e}/deliveries${tt(n)}`),
300
+ retry: (n) => t.http.post(`${e}/deliveries/${n}/retry`, {}).then(a)
301
+ };
302
+ }
303
+ const nt = {
304
+ key: 3,
305
+ class: "wx-notifications-found"
306
+ }, at = { class: "wx-notifications-found__text" }, lt = /* @__PURE__ */ P({
307
+ name: "WxNotificationsFindChats",
308
+ __name: "FindChatsDialog",
309
+ props: {
310
+ channel: { default: null },
311
+ token: { default: "" },
312
+ chosen: { default: () => [] }
313
+ },
314
+ setup(t) {
315
+ const e = t, { open: a, resolve: l, dismiss: n } = ze(), i = ye(Q());
316
+ U();
317
+ const r = R("webx-notifications"), u = Ge(), b = A([]), k = A(null), v = A(null), x = A(!0), C = A(/* @__PURE__ */ new Set());
318
+ async function N() {
319
+ x.value = !0, v.value = null;
320
+ try {
321
+ const o = await i.findRecipients({
322
+ provider: "telegram",
323
+ channel: e.channel,
324
+ token: e.token.trim() === "" ? void 0 : e.token.trim()
325
+ });
326
+ b.value = o.recipients, k.value = o.hint;
327
+ } catch (o) {
328
+ v.value = u(o);
329
+ } finally {
330
+ x.value = !1;
331
+ }
332
+ }
333
+ ae(() => {
334
+ N();
335
+ });
336
+ const S = m(() => b.value.filter((o) => !e.chosen.includes(o.id)));
337
+ function $(o, d) {
338
+ const c = new Set(C.value);
339
+ d ? c.add(o) : c.delete(o), C.value = c;
340
+ }
341
+ function V() {
342
+ l(S.value.filter((o) => C.value.has(o.id)));
343
+ }
344
+ return (o, d) => (p(), _(s(Fe), {
345
+ open: s(a),
346
+ "onUpdate:open": d[1] || (d[1] = (c) => Ae(a) ? a.value = c : null),
347
+ title: s(r)("panel.find-title"),
348
+ width: 480
349
+ }, {
350
+ footer: f(() => [
351
+ g(s(se), { size: "sm" }, {
352
+ default: f(() => [
353
+ g(s(O), {
354
+ variant: "outline",
355
+ disabled: x.value,
356
+ onClick: N
357
+ }, {
358
+ default: f(() => [
359
+ y(h(s(r)("panel.find-chats")), 1)
360
+ ]),
361
+ _: 1
362
+ }, 8, ["disabled"]),
363
+ g(s(O), {
364
+ variant: "outline",
365
+ onClick: d[0] || (d[0] = (c) => s(n)())
366
+ }, {
367
+ default: f(() => [
368
+ y(h(s(r)("panel.cancel")), 1)
369
+ ]),
370
+ _: 1
371
+ }),
372
+ g(s(O), {
373
+ type: "primary",
374
+ disabled: C.value.size === 0,
375
+ onClick: V
376
+ }, {
377
+ default: f(() => [
378
+ y(h(s(r)("panel.find-add")), 1)
379
+ ]),
380
+ _: 1
381
+ }, 8, ["disabled"])
382
+ ]),
383
+ _: 1
384
+ })
385
+ ]),
386
+ default: f(() => [
387
+ x.value ? (p(), _(s(Ee), {
388
+ key: 0,
389
+ rows: 3
390
+ })) : v.value ? (p(), _(s(H), {
391
+ key: 1,
392
+ type: "danger",
393
+ variant: "soft",
394
+ description: v.value
395
+ }, null, 8, ["description"])) : b.value.length === 0 ? (p(), _(s(Me), {
396
+ key: 2,
397
+ title: s(r)("panel.find-title"),
398
+ description: k.value ?? s(r)("panel.find-help")
399
+ }, null, 8, ["title", "description"])) : (p(), w("ul", nt, [
400
+ (p(!0), w(F, null, L(b.value, (c) => (p(), w("li", {
401
+ key: c.id,
402
+ class: "wx-notifications-found__row"
403
+ }, [
404
+ g(s(Le), {
405
+ "model-value": e.chosen.includes(c.id) || C.value.has(c.id),
406
+ disabled: e.chosen.includes(c.id),
407
+ "onUpdate:modelValue": (T) => $(c.id, T)
408
+ }, {
409
+ default: f(() => [
410
+ D("span", at, [
411
+ g(s(W), { truncate: "" }, {
412
+ default: f(() => [
413
+ y(h(c.title), 1)
414
+ ]),
415
+ _: 2
416
+ }, 1024),
417
+ g(s(W), {
418
+ size: "sm",
419
+ tone: "muted",
420
+ mono: "",
421
+ truncate: ""
422
+ }, {
423
+ default: f(() => [
424
+ y(h([c.id, c.username].filter(Boolean).join(" · ")), 1)
425
+ ]),
426
+ _: 2
427
+ }, 1024)
428
+ ])
429
+ ]),
430
+ _: 2
431
+ }, 1032, ["model-value", "disabled", "onUpdate:modelValue"]),
432
+ g(s(le), null, {
433
+ default: f(() => [
434
+ y(h(s(r)(`panel.chat-${c.type}`)), 1)
435
+ ]),
436
+ _: 2
437
+ }, 1024)
438
+ ]))), 128))
439
+ ]))
440
+ ]),
441
+ _: 1
442
+ }, 8, ["open", "title"]));
443
+ }
444
+ }), st = /* @__PURE__ */ B(lt, [["__scopeId", "data-v-71616d40"]]);
445
+ function it(t) {
446
+ return (t?.variables ?? []).map((e) => ({
447
+ name: e.name,
448
+ label: e.label,
449
+ example: e.example,
450
+ fields: e.fields.length > 0 ? e.fields : void 0
451
+ }));
452
+ }
453
+ function ot(t, e = "value") {
454
+ const a = t.name.endsWith(".*") ? `${t.name.slice(0, -2)}.name` : t.name;
455
+ if ((t.fields?.length ?? 0) > 0) {
456
+ const l = (t.fields ?? []).map((n) => `{{${n.name}}}`).join(" ");
457
+ return `{{#${a}}}
458
+ ${l}
459
+ {{/${a}}}`;
460
+ }
461
+ return e === "has" ? `{{#${a}}}{{${a}}}{{/${a}}}` : e === "empty" ? `{{^${a}}}{{/${a}}}` : `{{${a}}}`;
462
+ }
463
+ function _e(t, e) {
464
+ return (t?.variables ?? []).filter((a) => a.address === e);
465
+ }
466
+ const rt = { class: "wx-notifications-recipients" }, ct = /* @__PURE__ */ P({
467
+ name: "WxNotificationsChatsField",
468
+ __name: "ChatsField",
469
+ props: /* @__PURE__ */ G({
470
+ disabled: { type: Boolean, default: !1 }
471
+ }, {
472
+ modelValue: { default: () => [] },
473
+ modelModifiers: {}
474
+ }),
475
+ emits: ["update:modelValue"],
476
+ setup(t) {
477
+ const e = t, a = K(t, "modelValue");
478
+ U();
479
+ const l = R("webx-notifications"), n = be(), i = X(), r = Pe(st), u = m(() => Array.isArray(a.value) ? a.value : []), b = m(() => _e(i.event.value, "telegram")), k = m(
480
+ () => b.value.filter((o) => !u.value.some((d) => d.variable === o.name))
481
+ );
482
+ function v(o) {
483
+ return b.value.find((d) => d.name === o)?.label ?? `{{${o}}}`;
484
+ }
485
+ function x(o, d) {
486
+ a.value = u.value.map((c, T) => T === o ? { ...c, ...d } : c);
487
+ }
488
+ function C(o) {
489
+ a.value = [...u.value, o];
490
+ }
491
+ function N(o) {
492
+ a.value = u.value.filter((d, c) => c !== o);
493
+ }
494
+ const S = m(() => {
495
+ const o = i.values.value.token;
496
+ return typeof o == "string" ? o : "";
497
+ }), $ = m(
498
+ () => S.value.trim() !== "" || i.id.value !== null && i.values.value.provider === "telegram"
499
+ );
500
+ async function V() {
501
+ if (!$.value) {
502
+ Y.warning(l("panel.find-token"));
503
+ return;
504
+ }
505
+ const o = await r({
506
+ channel: i.id.value,
507
+ token: S.value,
508
+ chosen: u.value.map((d) => d.chat_id ?? "").filter(Boolean)
509
+ });
510
+ !o || o.length === 0 || (a.value = [...u.value, ...o.map((d) => ({ chat_id: d.id, label: d.title }))], Y.success(l("panel.find-added", { count: String(o.length) })));
511
+ }
512
+ return (o, d) => (p(), w("div", rt, [
513
+ u.value.length === 0 ? (p(), _(s(W), {
514
+ key: 0,
515
+ size: "sm",
516
+ tone: "placeholder"
517
+ }, {
518
+ default: f(() => [
519
+ y(h(s(l)("panel.no-recipients")), 1)
520
+ ]),
521
+ _: 1
522
+ })) : j("", !0),
523
+ (p(!0), w(F, null, L(u.value, (c, T) => (p(), w("div", {
524
+ key: T,
525
+ class: "wx-notifications-recipients__row"
526
+ }, [
527
+ c.variable ? (p(), _(s(le), {
528
+ key: 0,
529
+ type: "primary",
530
+ class: "wx-notifications-recipients__addressee"
531
+ }, {
532
+ default: f(() => [
533
+ y(h(s(l)("panel.addressee", { label: v(c.variable) })), 1)
534
+ ]),
535
+ _: 2
536
+ }, 1024)) : (p(), w(F, { key: 1 }, [
537
+ g(s(J), {
538
+ class: "wx-notifications-recipients__id",
539
+ "model-value": c.chat_id ?? "",
540
+ placeholder: s(l)("panel.chat-id"),
541
+ "aria-label": s(l)("panel.chat-id"),
542
+ disabled: e.disabled,
543
+ inputmode: "text",
544
+ "onUpdate:modelValue": (z) => x(T, { chat_id: String(z ?? "") })
545
+ }, null, 8, ["model-value", "placeholder", "aria-label", "disabled", "onUpdate:modelValue"]),
546
+ g(s(J), {
547
+ class: "wx-notifications-recipients__label",
548
+ "model-value": c.label ?? "",
549
+ placeholder: s(l)("panel.chat-label"),
550
+ "aria-label": s(l)("panel.chat-label"),
551
+ disabled: e.disabled,
552
+ "onUpdate:modelValue": (z) => x(T, { label: String(z ?? "") })
553
+ }, null, 8, ["model-value", "placeholder", "aria-label", "disabled", "onUpdate:modelValue"])
554
+ ], 64)),
555
+ e.disabled ? j("", !0) : (p(), _(s(he), fe({
556
+ key: 2,
557
+ icon: "trash",
558
+ tone: "danger",
559
+ title: s(l)("panel.remove")
560
+ }, { ref_for: !0 }, s(n), {
561
+ onClick: (z) => N(T)
562
+ }), null, 16, ["title", "onClick"]))
563
+ ]))), 128)),
564
+ e.disabled ? j("", !0) : (p(), _(s(se), {
565
+ key: 1,
566
+ size: "sm",
567
+ wrap: ""
568
+ }, {
569
+ default: f(() => [
570
+ g(s(O), {
571
+ variant: "outline",
572
+ size: "sm",
573
+ onClick: d[0] || (d[0] = (c) => C({ chat_id: "", label: "" }))
574
+ }, {
575
+ icon: f(() => [
576
+ g(s(q), { name: "plus" })
577
+ ]),
578
+ default: f(() => [
579
+ y(" " + h(s(l)("panel.add-chat")), 1)
580
+ ]),
581
+ _: 1
582
+ }),
583
+ g(s(O), {
584
+ variant: "outline",
585
+ size: "sm",
586
+ onClick: V
587
+ }, {
588
+ icon: f(() => [
589
+ g(s(q), { name: "search" })
590
+ ]),
591
+ default: f(() => [
592
+ y(" " + h(s(l)("panel.find-chats")), 1)
593
+ ]),
594
+ _: 1
595
+ }),
596
+ (p(!0), w(F, null, L(k.value, (c) => (p(), _(s(O), {
597
+ key: c.name,
598
+ variant: "outline",
599
+ size: "sm",
600
+ onClick: (T) => C({ variable: c.name })
601
+ }, {
602
+ default: f(() => [
603
+ y(h(s(l)("panel.addressee", { label: c.label })), 1)
604
+ ]),
605
+ _: 2
606
+ }, 1032, ["onClick"]))), 128))
607
+ ]),
608
+ _: 1
609
+ }))
610
+ ]));
611
+ }
612
+ }), dt = /* @__PURE__ */ B(ct, [["__scopeId", "data-v-22102841"]]), ut = { class: "wx-notifications-recipients" }, pt = /* @__PURE__ */ P({
613
+ name: "WxNotificationsEmailsField",
614
+ __name: "EmailsField",
615
+ props: /* @__PURE__ */ G({
616
+ disabled: { type: Boolean, default: !1 }
617
+ }, {
618
+ modelValue: { default: () => [] },
619
+ modelModifiers: {}
620
+ }),
621
+ emits: ["update:modelValue"],
622
+ setup(t) {
623
+ const e = t, a = K(t, "modelValue");
624
+ U();
625
+ const l = R("webx-notifications"), n = be(), i = X(), r = Q(), u = A([]);
626
+ ae(async () => {
627
+ try {
628
+ u.value = await ye(r).administrators();
629
+ } catch {
630
+ }
631
+ });
632
+ const b = m(() => Array.isArray(a.value) ? a.value : []), k = m(
633
+ () => u.value.map((o) => ({ value: o.id, label: `${o.name} · ${o.email}` }))
634
+ ), v = m(() => _e(i.event.value, "email")), x = m(
635
+ () => v.value.filter((o) => !b.value.some((d) => d.variable === o.name))
636
+ );
637
+ function C(o) {
638
+ return v.value.find((d) => d.name === o)?.label ?? `{{${o}}}`;
639
+ }
640
+ function N(o, d) {
641
+ a.value = b.value.map((c, T) => T === o ? d : c);
642
+ }
643
+ function S(o) {
644
+ a.value = [...b.value, o];
645
+ }
646
+ function $(o) {
647
+ a.value = b.value.filter((d, c) => c !== o);
648
+ }
649
+ function V(o) {
650
+ return k.value.some((d) => d.value === o) ? k.value : [...k.value, { value: o, label: l("panel.admin-unknown", { id: String(o) }) }];
651
+ }
652
+ return (o, d) => (p(), w("div", ut, [
653
+ b.value.length === 0 ? (p(), _(s(W), {
654
+ key: 0,
655
+ size: "sm",
656
+ tone: "placeholder"
657
+ }, {
658
+ default: f(() => [
659
+ y(h(s(l)("panel.no-recipients")), 1)
660
+ ]),
661
+ _: 1
662
+ })) : j("", !0),
663
+ (p(!0), w(F, null, L(b.value, (c, T) => (p(), w("div", {
664
+ key: T,
665
+ class: "wx-notifications-recipients__row"
666
+ }, [
667
+ c.variable ? (p(), _(s(le), {
668
+ key: 0,
669
+ type: "primary",
670
+ class: "wx-notifications-recipients__wide"
671
+ }, {
672
+ default: f(() => [
673
+ y(h(s(l)("panel.addressee", { label: C(c.variable) })), 1)
674
+ ]),
675
+ _: 2
676
+ }, 1024)) : c.admin_id !== void 0 ? (p(), _(s(Re), {
677
+ key: 1,
678
+ class: "wx-notifications-recipients__wide",
679
+ "model-value": c.admin_id,
680
+ options: V(c.admin_id),
681
+ disabled: e.disabled,
682
+ "onUpdate:modelValue": (z) => N(T, { admin_id: Number(z) })
683
+ }, null, 8, ["model-value", "options", "disabled", "onUpdate:modelValue"])) : (p(), _(s(J), {
684
+ key: 2,
685
+ class: "wx-notifications-recipients__wide",
686
+ type: "email",
687
+ "model-value": c.email ?? "",
688
+ placeholder: "manager@site.test",
689
+ disabled: e.disabled,
690
+ "onUpdate:modelValue": (z) => N(T, { email: String(z ?? "") })
691
+ }, null, 8, ["model-value", "disabled", "onUpdate:modelValue"])),
692
+ e.disabled ? j("", !0) : (p(), _(s(he), fe({
693
+ key: 3,
694
+ icon: "trash",
695
+ tone: "danger",
696
+ title: s(l)("panel.remove")
697
+ }, { ref_for: !0 }, s(n), {
698
+ onClick: (z) => $(T)
699
+ }), null, 16, ["title", "onClick"]))
700
+ ]))), 128)),
701
+ e.disabled ? j("", !0) : (p(), _(s(se), {
702
+ key: 1,
703
+ size: "sm",
704
+ wrap: ""
705
+ }, {
706
+ default: f(() => [
707
+ g(s(O), {
708
+ variant: "outline",
709
+ size: "sm",
710
+ disabled: k.value.length === 0,
711
+ onClick: d[0] || (d[0] = (c) => S({ admin_id: Number(k.value[0]?.value) }))
712
+ }, {
713
+ icon: f(() => [
714
+ g(s(q), { name: "user" })
715
+ ]),
716
+ default: f(() => [
717
+ y(" " + h(s(l)("panel.add-admin")), 1)
718
+ ]),
719
+ _: 1
720
+ }, 8, ["disabled"]),
721
+ g(s(O), {
722
+ variant: "outline",
723
+ size: "sm",
724
+ onClick: d[1] || (d[1] = (c) => S({ email: "" }))
725
+ }, {
726
+ icon: f(() => [
727
+ g(s(q), { name: "mail" })
728
+ ]),
729
+ default: f(() => [
730
+ y(" " + h(s(l)("panel.add-email")), 1)
731
+ ]),
732
+ _: 1
733
+ }),
734
+ (p(!0), w(F, null, L(x.value, (c) => (p(), _(s(O), {
735
+ key: c.name,
736
+ variant: "outline",
737
+ size: "sm",
738
+ onClick: (T) => S({ variable: c.name })
739
+ }, {
740
+ default: f(() => [
741
+ y(h(s(l)("panel.addressee", { label: c.label })), 1)
742
+ ]),
743
+ _: 2
744
+ }, 1032, ["onClick"]))), 128))
745
+ ]),
746
+ _: 1
747
+ }))
748
+ ]));
749
+ }
750
+ }), ft = /* @__PURE__ */ B(pt, [["__scopeId", "data-v-6ed21265"]]);
751
+ function ke(t, e) {
752
+ return !t || !e ? null : t.sample[e] ?? t.sample["*"] ?? null;
753
+ }
754
+ function I(t) {
755
+ return t == null ? !0 : typeof t == "string" ? t.trim() === "" : typeof t == "object" ? Object.values(t).every((e) => I(e)) : !1;
756
+ }
757
+ function xe(t, e, a) {
758
+ return {
759
+ ...t,
760
+ template: { ...e.template },
761
+ ...a && e.subject !== null ? { subject: { ...e.subject } } : {}
762
+ };
763
+ }
764
+ function Jt(t, e, a) {
765
+ je(
766
+ () => t.values.value.event,
767
+ (l, n) => {
768
+ if (e.value || l === n) return;
769
+ const i = ke(t.event.value, t.provider.value?.key), r = t.provider.value?.subject ?? !1, u = t.values.value;
770
+ i === null || !I(u.template) || r && !I(u.subject) || (t.values.value = xe(u, i, r), a());
771
+ },
772
+ { flush: "sync" }
773
+ );
774
+ }
775
+ class M extends Error {
776
+ constructor(e, a = {}) {
777
+ super(e), this.key = e, this.replace = a, this.name = "TemplateRefusal";
778
+ }
779
+ key;
780
+ replace;
781
+ }
782
+ const mt = /^[a-z0-9_]+(\.[a-z0-9_]+)?$/;
783
+ function $e(t) {
784
+ return t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
785
+ }
786
+ function ce(t) {
787
+ return t.replace(/[\r\n]+/g, " ");
788
+ }
789
+ function ht(t, e = "") {
790
+ return ie(t, e) ? vt : t === "telegram" ? $e : (a) => a;
791
+ }
792
+ function ie(t, e) {
793
+ return t === "email" && /^\s*<[a-zA-Z]/.test(e);
794
+ }
795
+ function vt(t) {
796
+ return $e(t).replace(/\r\n|\r|\n/g, "<br>");
797
+ }
798
+ function Z(t) {
799
+ const e = document.createElement("textarea");
800
+ return e.innerHTML = t, e.value;
801
+ }
802
+ const bt = "p|h[1-6]|table|ul|ol|blockquote|pre", gt = "tr|div";
803
+ function wt(t) {
804
+ let e = t.replace(/[ \t\r\n\f]+/g, " ");
805
+ return e = e.replace(
806
+ /<a\b[^>]*?\bhref\s*=\s*"([^"]*)"[^>]*>([\s\S]*?)<\/a\s*>/gi,
807
+ (l, n, i) => {
808
+ const r = Z(n), u = Z(i.replace(/<[^>]*>/g, "")).trim();
809
+ return u === "" || u === r ? r : /^(https?:|mailto:)/i.test(r) ? `${i} (${n})` : i;
810
+ }
811
+ ), e = e.replace(/<br\s*\/?>/gi, `
812
+ `), e = e.replace(/<\/t[dh]\s*>\s*(?=<t[dh][\s>])/gi, ": "), e = e.replace(/<li\b[^>]*>/gi, `
813
+ - `), e = e.replace(new RegExp(`<hr\\b[^>]*>|</?(?:${bt})\\b[^>]*>`, "gi"), `
814
+
815
+ `), e = e.replace(new RegExp(`<div\\b[^>]*>|</(?:${gt})\\s*>`, "gi"), `
816
+ `), e = Z(e.replace(/<[^>]*>/g, "")), e.split(`
817
+ `).map((l) => l.replace(/ {2,}/g, " ").trim()).join(`
818
+ `).replace(/\n{3,}/g, `
819
+
820
+ `).trim();
821
+ }
822
+ function yt(t) {
823
+ try {
824
+ return Qe.parse(t, ["{{", "}}"]);
825
+ } catch (e) {
826
+ const a = e instanceof Error ? e.message : String(e), l = /section "([^"]*)"/.exec(a)?.[1] ?? "";
827
+ if (a.startsWith("Unopened section"))
828
+ throw new M("template-unexpected", { section: l });
829
+ if (a.startsWith("Unclosed section"))
830
+ throw new M("template-unclosed", { section: l });
831
+ const n = Number(/at (\d+)/.exec(a)?.[1] ?? t.lastIndexOf("{{")), i = t.slice(n).replace(/^\{\{\{?[#^/!&>=]?/, "").trim();
832
+ throw new M("template-tag", { tag: i });
833
+ }
834
+ }
835
+ function Te(t) {
836
+ for (const e of t) {
837
+ const [a, l] = e;
838
+ if (a === ">") throw new M("template-partial");
839
+ if (a === "=") throw new M("template-delimiters");
840
+ if (a === "text" || a === "!") continue;
841
+ const n = l.trim();
842
+ if (n.startsWith("<")) throw new M("template-partial");
843
+ if (n.startsWith("%") || n.startsWith("$")) throw new M("template-pragma");
844
+ if (!mt.test(n)) throw new M("template-name", { name: n });
845
+ e[4] && Te(e[4]);
846
+ }
847
+ }
848
+ function _t(t) {
849
+ const e = {};
850
+ for (const [a, l] of Object.entries(t)) {
851
+ if (!a.includes(".")) {
852
+ e[a] = l;
853
+ continue;
854
+ }
855
+ const [n, ...i] = a.split("."), r = n, u = e[r];
856
+ (u === void 0 || E(u)) && (e[r] = { ...E(u) ? u : {}, [i.join(".")]: l });
857
+ }
858
+ return e;
859
+ }
860
+ function E(t) {
861
+ return typeof t == "object" && t !== null && !Array.isArray(t);
862
+ }
863
+ function de(t) {
864
+ return t == null || t === !1 || t === "" || t === "0" || t === 0 ? !0 : Array.isArray(t) ? t.length === 0 : E(t) ? Object.keys(t).length === 0 : !1;
865
+ }
866
+ function kt(t, e) {
867
+ const [a, ...l] = e.split(".");
868
+ let n;
869
+ for (let i = t.length - 1; i >= 0; i--) {
870
+ const r = t[i];
871
+ if (E(r) && Object.prototype.hasOwnProperty.call(r, a)) {
872
+ n = r[a];
873
+ break;
874
+ }
875
+ }
876
+ for (const i of l) {
877
+ if (n === "" || n === void 0) return n;
878
+ n = E(n) && Object.prototype.hasOwnProperty.call(n, i) ? n[i] : "";
879
+ }
880
+ return n;
881
+ }
882
+ function xt(t) {
883
+ return typeof t == "string" ? t : typeof t == "number" ? String(t) : t === !0 ? "1" : "";
884
+ }
885
+ function ee(t, e, a) {
886
+ let l = "";
887
+ for (const n of t) {
888
+ const [i, r] = n;
889
+ if (i === "text") {
890
+ l += r;
891
+ continue;
892
+ }
893
+ if (i === "!") continue;
894
+ const u = kt(e, r.trim());
895
+ if (i === "name" || i === "&") {
896
+ l += E(u) || Array.isArray(u) ? "" : a(xt(u));
897
+ continue;
898
+ }
899
+ const b = n[4] ?? [];
900
+ if (i === "#" && !de(u))
901
+ for (const k of Array.isArray(u) ? u : [u])
902
+ l += ee(b, [...e, k], a);
903
+ i === "^" && de(u) && (l += ee(b, e, a));
904
+ }
905
+ return l;
906
+ }
907
+ function te(t, e = [], a = []) {
908
+ for (const l of t) {
909
+ const [n, i] = l;
910
+ if (n === "text" || n === "!") continue;
911
+ const r = i.trim();
912
+ a.push({ name: r, sections: e }), n === "#" && te(l[4] ?? [], [...e, r], a), n === "^" && te(l[4] ?? [], e, a);
913
+ }
914
+ return a;
915
+ }
916
+ function ue(t, e) {
917
+ const [a, ...l] = e.split(".");
918
+ for (const n of [...t].reverse()) {
919
+ if (!E(n) || !Object.prototype.hasOwnProperty.call(n, a)) continue;
920
+ let i = n[a];
921
+ for (const r of l) {
922
+ if (!E(i) || !Object.prototype.hasOwnProperty.call(i, r)) return null;
923
+ i = i[r];
924
+ }
925
+ return i ?? null;
926
+ }
927
+ return null;
928
+ }
929
+ function $t(t, e, a) {
930
+ const l = [t];
931
+ for (const n of a) {
932
+ const i = ue(l, n);
933
+ Array.isArray(i) ? l.push(Object.assign({}, ...i.filter(E))) : E(i) && l.push(i);
934
+ }
935
+ return ue(l, e) !== null;
936
+ }
937
+ function Tt(t, e, a) {
938
+ for (const l of [...a].reverse()) {
939
+ const n = t.variables.find((i) => i.name === l);
940
+ if (n && n.fields.length > 0 && n.fields.some((i) => i.name === e))
941
+ return !0;
942
+ }
943
+ return t.variables.some(
944
+ (l) => l.name === e || l.name.endsWith(".*") && e.startsWith(l.name.slice(0, -1))
945
+ );
946
+ }
947
+ function pe(t, e, a, l) {
948
+ const n = yt(t);
949
+ Te(n);
950
+ const i = _t(e), r = /* @__PURE__ */ new Set();
951
+ for (const u of te(n))
952
+ !$t(i, u.name, u.sections) && !l?.(u.name, u.sections) && r.add(u.name);
953
+ return { text: ee(n, [i], a), unknown: [...r] };
954
+ }
955
+ function Ct(t) {
956
+ const e = {};
957
+ for (const a of t?.variables ?? [])
958
+ a.name.endsWith(".*") || (e[a.name] = a.example);
959
+ return e;
960
+ }
961
+ function St(t) {
962
+ return new DOMParser().parseFromString(`<body>${t}</body>`, "text/html").body.textContent ?? "";
963
+ }
964
+ function At(t) {
965
+ const e = ie(t.provider, t.template), a = ht(t.provider, t.template), l = t.event ?? null, n = l === null ? void 0 : (v, x) => Tt(l, v, x), i = pe(t.template, t.values, a, n);
966
+ let r = null, u = i.unknown;
967
+ if (t.hasSubject) {
968
+ const v = pe(t.subject ?? "", t.values, ce, n);
969
+ r = ce(v.text).trim(), u = [.../* @__PURE__ */ new Set([...u, ...v.unknown])];
970
+ }
971
+ const b = e ? wt(i.text) : t.provider === "telegram" ? St(i.text) : i.text, k = t.limit ?? null;
972
+ if (k !== null && [...b].length > k) {
973
+ const v = `${[...b].slice(0, k - 1).join("")}…`;
974
+ return { subject: r, body: a(v), plain: v, truncated: !0, unknown: u, html: e };
975
+ }
976
+ return { subject: r, body: i.text, plain: b, truncated: !1, unknown: u, html: e };
977
+ }
978
+ const jt = { class: "wx-notifications-template" }, Wt = {
979
+ key: 0,
980
+ class: "wx-notifications-template__variables"
981
+ }, Nt = { class: "wx-notifications-template__chips" }, Vt = { class: "wx-notifications-template__name" }, Ot = {
982
+ key: 2,
983
+ class: "wx-notifications-template__default"
984
+ }, zt = /* @__PURE__ */ P({
985
+ name: "WxNotificationsTemplateField",
986
+ __name: "TemplateField",
987
+ props: /* @__PURE__ */ G({
988
+ localized: { type: Boolean, default: !1 },
989
+ disabled: { type: Boolean, default: void 0 },
990
+ minHeight: { default: "200px" },
991
+ singleLine: { type: Boolean, default: !1 },
992
+ part: { default: "template" },
993
+ chips: { type: Boolean, default: !0 }
994
+ }, {
995
+ modelValue: { default: "" },
996
+ modelModifiers: {}
997
+ }),
998
+ emits: ["update:modelValue"],
999
+ setup(t) {
1000
+ const e = t, a = K(t, "modelValue");
1001
+ U();
1002
+ const l = R("webx-notifications"), n = X(), i = ve(), r = A(null), u = m(() => it(n.event.value)), b = m(
1003
+ () => Ue(u.value, {
1004
+ variable: l("panel.hint-variable"),
1005
+ list: l("panel.hint-list"),
1006
+ field: l("panel.hint-field"),
1007
+ section: l("panel.hint-section"),
1008
+ inverted: l("panel.hint-inverted"),
1009
+ close: l("panel.hint-close"),
1010
+ comment: l("panel.hint-comment"),
1011
+ example: l("panel.hint-example")
1012
+ })
1013
+ ), k = m(() => {
1014
+ const o = a.value;
1015
+ if (o == null) return "";
1016
+ if (typeof o == "string") return o;
1017
+ const d = i.active.value || i.list.value[0]?.code || "";
1018
+ return o[d] ?? "";
1019
+ }), v = m(() => {
1020
+ if (e.singleLine) return "mustache";
1021
+ const o = n.provider.value?.key ?? "";
1022
+ return o === "telegram" || ie(o, k.value) ? "mustache-html" : "mustache";
1023
+ }), x = m(
1024
+ () => Be(k.value, n.event.value === null ? void 0 : u.value)
1025
+ ), C = m(() => {
1026
+ const o = x.value;
1027
+ return [
1028
+ ...o.unclosed.map((d) => l("panel.problem-unclosed", { name: d })),
1029
+ ...o.stray.map((d) => l("panel.problem-stray", { name: d })),
1030
+ ...o.refused.map((d) => l("panel.problem-refused", { tag: d })),
1031
+ ...o.broken ? [l("panel.problem-broken")] : [],
1032
+ ...o.unknown.length > 0 ? [
1033
+ l("panel.problem-unknown", {
1034
+ names: o.unknown.map((d) => `{{${d}}}`).join(", ")
1035
+ })
1036
+ ] : []
1037
+ ];
1038
+ });
1039
+ function N(o) {
1040
+ if ((o.fields?.length ?? 0) > 0)
1041
+ return l("panel.variable-list", {
1042
+ fields: (o.fields ?? []).map((c) => c.name).join(", ")
1043
+ });
1044
+ const d = o.example;
1045
+ return typeof d == "string" || typeof d == "number" ? String(d) : "";
1046
+ }
1047
+ function S(o) {
1048
+ const d = r.value?.view;
1049
+ if (!d) return;
1050
+ const c = d.state.selection.main;
1051
+ d.dispatch({
1052
+ changes: { from: c.from, to: c.to, insert: o },
1053
+ selection: { anchor: c.from + o.length },
1054
+ scrollIntoView: !0
1055
+ }), d.focus();
1056
+ }
1057
+ ae(() => n.inserters.set(e.part, S)), We(() => {
1058
+ n.inserters.get(e.part) === S && n.inserters.delete(e.part);
1059
+ });
1060
+ const $ = m(() => ke(n.event.value, n.provider.value?.key));
1061
+ async function V() {
1062
+ const o = $.value;
1063
+ if (o === null) return;
1064
+ const d = n.values.value, c = n.provider.value?.subject ?? !1;
1065
+ (!I(d.template) || c && !I(d.subject)) && !await He({
1066
+ title: l("panel.default-title"),
1067
+ message: l("panel.default-text"),
1068
+ confirmText: l("panel.default-replace"),
1069
+ cancelText: l("panel.cancel")
1070
+ }) || (n.values.value = xe(n.values.value, o, c), Y.info(l("panel.default-inserted")));
1071
+ }
1072
+ return (o, d) => (p(), w("div", jt, [
1073
+ g(s(Ie), {
1074
+ ref_key: "editor",
1075
+ ref: r,
1076
+ modelValue: a.value,
1077
+ "onUpdate:modelValue": d[0] || (d[0] = (c) => a.value = c),
1078
+ language: v.value,
1079
+ completions: b.value,
1080
+ localized: e.localized,
1081
+ disabled: e.disabled,
1082
+ "line-numbers": !1,
1083
+ "line-wrapping": !e.singleLine,
1084
+ "single-line": e.singleLine,
1085
+ "min-height": e.singleLine ? void 0 : e.minHeight,
1086
+ onFocus: d[1] || (d[1] = (c) => s(n).focused.value = e.part)
1087
+ }, null, 8, ["modelValue", "language", "completions", "localized", "disabled", "line-wrapping", "single-line", "min-height"]),
1088
+ (p(!0), w(F, null, L(C.value, (c) => (p(), _(s(H), {
1089
+ key: c,
1090
+ type: "warning",
1091
+ variant: "soft",
1092
+ description: c
1093
+ }, null, 8, ["description"]))), 128)),
1094
+ e.chips ? (p(), w("div", Wt, [
1095
+ g(s(W), {
1096
+ size: "sm",
1097
+ weight: "medium"
1098
+ }, {
1099
+ default: f(() => [
1100
+ y(h(s(l)("panel.variables")), 1)
1101
+ ]),
1102
+ _: 1
1103
+ }),
1104
+ u.value.length === 0 ? (p(), _(s(W), {
1105
+ key: 0,
1106
+ size: "sm",
1107
+ tone: "muted"
1108
+ }, {
1109
+ default: f(() => [
1110
+ y(h(s(l)("panel.variables-none")), 1)
1111
+ ]),
1112
+ _: 1
1113
+ })) : (p(), w(F, { key: 1 }, [
1114
+ g(s(W), {
1115
+ size: "sm",
1116
+ tone: "muted"
1117
+ }, {
1118
+ default: f(() => [
1119
+ y(h(s(l)("panel.variables-help")), 1)
1120
+ ]),
1121
+ _: 1
1122
+ }),
1123
+ D("div", Nt, [
1124
+ (p(!0), w(F, null, L(u.value, (c) => (p(), _(s(De), {
1125
+ key: c.name,
1126
+ content: [c.label, N(c)].filter(Boolean).join(" — ")
1127
+ }, {
1128
+ default: f(() => [
1129
+ g(s(O), {
1130
+ size: "sm",
1131
+ variant: "outline",
1132
+ class: "wx-notifications-template__chip",
1133
+ disabled: e.disabled,
1134
+ onClick: (T) => s(n).insert(s(ot)(c))
1135
+ }, {
1136
+ default: f(() => [
1137
+ D("span", Vt, h((c.fields?.length ?? 0) > 0 ? `#${c.name}` : c.name), 1)
1138
+ ]),
1139
+ _: 2
1140
+ }, 1032, ["disabled", "onClick"])
1141
+ ]),
1142
+ _: 2
1143
+ }, 1032, ["content"]))), 128))
1144
+ ])
1145
+ ], 64)),
1146
+ $.value ? (p(), w("div", Ot, [
1147
+ g(s(O), {
1148
+ size: "sm",
1149
+ variant: "text",
1150
+ icon: "file-text",
1151
+ disabled: e.disabled,
1152
+ onClick: V
1153
+ }, {
1154
+ default: f(() => [
1155
+ y(h(s(l)("panel.default-insert")), 1)
1156
+ ]),
1157
+ _: 1
1158
+ }, 8, ["disabled"])
1159
+ ])) : j("", !0)
1160
+ ])) : j("", !0)
1161
+ ]));
1162
+ }
1163
+ }), Ft = /* @__PURE__ */ B(zt, [["__scopeId", "data-v-d491fffa"]]);
1164
+ function Yt(t = {}) {
1165
+ const e = t.path ?? "/notifications";
1166
+ return {
1167
+ id: "notifications",
1168
+ path: e,
1169
+ routes: [
1170
+ {
1171
+ path: e,
1172
+ name: "webx.notifications",
1173
+ component: () => import("./NotificationsPage-BkTBIV0B.js"),
1174
+ props: { base: e }
1175
+ },
1176
+ {
1177
+ path: `${e}/channels/new`,
1178
+ name: "webx.notifications.new",
1179
+ component: () => import("./ChannelPage-vxVhttk3.js"),
1180
+ props: { base: e }
1181
+ },
1182
+ {
1183
+ path: `${e}/channels/:id(\\d+)`,
1184
+ name: "webx.notifications.channel",
1185
+ component: () => import("./ChannelPage-vxVhttk3.js"),
1186
+ props: { base: e }
1187
+ }
1188
+ ],
1189
+ types: {
1190
+ "wx-notifications-template": { component: Ft, kind: "field", wide: !0 },
1191
+ "wx-notifications-chats": { component: dt, kind: "field" },
1192
+ "wx-notifications-emails": { component: ft, kind: "field" },
1193
+ "wx-notifications-channels": {
1194
+ component: Ye,
1195
+ kind: "field",
1196
+ bind: (a) => ({ event: a.props?.event, base: e })
1197
+ }
1198
+ }
1199
+ };
1200
+ }
1201
+ const Et = /* @__PURE__ */ new Set([
1202
+ "b",
1203
+ "strong",
1204
+ "i",
1205
+ "em",
1206
+ "u",
1207
+ "ins",
1208
+ "s",
1209
+ "strike",
1210
+ "del",
1211
+ "a",
1212
+ "code",
1213
+ "pre",
1214
+ "blockquote",
1215
+ "tg-spoiler",
1216
+ "span"
1217
+ ]);
1218
+ function ne(t, e, a) {
1219
+ for (const l of Array.from(t.childNodes)) {
1220
+ if (l.nodeType === Node.TEXT_NODE) {
1221
+ e.appendChild(a.createTextNode(l.textContent ?? ""));
1222
+ continue;
1223
+ }
1224
+ if (!(l instanceof Element)) continue;
1225
+ const n = l.tagName.toLowerCase();
1226
+ if (!Et.has(n) || n === "span" && !l.classList.contains("tg-spoiler")) {
1227
+ ne(l, e, a);
1228
+ continue;
1229
+ }
1230
+ const i = a.createElement(n === "tg-spoiler" ? "span" : n);
1231
+ if ((n === "tg-spoiler" || n === "span") && (i.className = "tg-spoiler"), n === "a") {
1232
+ const r = l.getAttribute("href") ?? "";
1233
+ /^(https?:|tg:)/i.test(r) && (i.setAttribute("href", r), i.setAttribute("target", "_blank"), i.setAttribute("rel", "noopener noreferrer"));
1234
+ }
1235
+ ne(l, i, a), e.appendChild(i);
1236
+ }
1237
+ }
1238
+ function Mt(t) {
1239
+ const e = new DOMParser().parseFromString(`<body>${t}</body>`, "text/html"), a = document.implementation.createHTMLDocument(""), l = a.createElement("div");
1240
+ return ne(e.body, l, a), l.innerHTML;
1241
+ }
1242
+ const Lt = {
1243
+ key: 0,
1244
+ class: "wx-notifications-preview__chat"
1245
+ }, Pt = ["innerHTML"], Rt = {
1246
+ key: 1,
1247
+ class: "wx-notifications-preview__bubble"
1248
+ }, Ut = {
1249
+ key: 1,
1250
+ class: "wx-notifications-preview__letter"
1251
+ }, Bt = { class: "wx-notifications-preview__subject" }, It = ["title", "srcdoc"], Dt = {
1252
+ key: 1,
1253
+ class: "wx-notifications-preview__body"
1254
+ }, Ht = /* @__PURE__ */ P({
1255
+ name: "WxNotificationsPreview",
1256
+ __name: "MessagePreview",
1257
+ setup(t) {
1258
+ U();
1259
+ const e = R("webx-notifications"), a = X(), l = ve(), n = m(() => l.active.value || l.list.value[0]?.code || ""), i = m(() => {
1260
+ const $ = a.provider.value;
1261
+ if ($ === null) return null;
1262
+ const V = a.values.value;
1263
+ try {
1264
+ return {
1265
+ message: At({
1266
+ provider: $.key,
1267
+ template: oe(V.template, n.value),
1268
+ subject: oe(V.subject, n.value),
1269
+ hasSubject: $.subject,
1270
+ limit: $.limit,
1271
+ values: Ct(a.event.value),
1272
+ event: a.event.value
1273
+ })
1274
+ };
1275
+ } catch (o) {
1276
+ if (o instanceof M)
1277
+ return { refusal: e(`errors.${o.key}`, o.replace) };
1278
+ throw o;
1279
+ }
1280
+ }), r = m(
1281
+ () => i.value !== null && "message" in i.value ? i.value.message : null
1282
+ ), u = m(
1283
+ () => i.value !== null && "refusal" in i.value ? i.value.refusal : null
1284
+ ), b = m(
1285
+ () => e("panel.preview-unknown", {
1286
+ names: (r.value?.unknown ?? []).map(($) => "{{" + $ + "}}").join(", ")
1287
+ })
1288
+ ), k = m(() => a.provider.value?.key === "telegram"), v = m(
1289
+ () => r.value?.html ? `<!doctype html><html><head><meta charset="utf-8"><style>body{margin:0;padding:16px;background:#fff;color:#111827;font:14px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;}</style></head><body>` + r.value.body + "</body></html>" : ""
1290
+ ), x = A(null), C = A(240);
1291
+ function N() {
1292
+ const $ = x.value?.contentDocument?.body;
1293
+ $ && (C.value = Math.max(80, Math.ceil($.scrollHeight)));
1294
+ }
1295
+ const S = m(
1296
+ () => r.value === null || r.value.truncated ? "" : Mt(r.value.body)
1297
+ );
1298
+ return ($, V) => (p(), _(s(qe), {
1299
+ title: s(e)("panel.preview"),
1300
+ class: "wx-notifications-preview"
1301
+ }, {
1302
+ default: f(() => [
1303
+ g(s(W), {
1304
+ size: "sm",
1305
+ tone: "muted"
1306
+ }, {
1307
+ default: f(() => [
1308
+ y(h(s(a).event.value ? s(e)("panel.preview-help") : s(e)("panel.preview-no-event")), 1)
1309
+ ]),
1310
+ _: 1
1311
+ }),
1312
+ u.value ? (p(), _(s(H), {
1313
+ key: 0,
1314
+ type: "danger",
1315
+ variant: "soft",
1316
+ title: s(e)("panel.preview-refused"),
1317
+ description: u.value
1318
+ }, null, 8, ["title", "description"])) : r.value ? (p(), w(F, { key: 1 }, [
1319
+ k.value ? (p(), w("div", Lt, [
1320
+ r.value.truncated ? (p(), w("div", Rt, h(r.value.plain), 1)) : (p(), w("div", {
1321
+ key: 0,
1322
+ class: "wx-notifications-preview__bubble",
1323
+ innerHTML: S.value
1324
+ }, null, 8, Pt))
1325
+ ])) : (p(), w("div", Ut, [
1326
+ D("div", Bt, [
1327
+ g(s(W), {
1328
+ size: "sm",
1329
+ tone: "muted"
1330
+ }, {
1331
+ default: f(() => [
1332
+ y(h(s(e)("panel.preview-subject")), 1)
1333
+ ]),
1334
+ _: 1
1335
+ }),
1336
+ g(s(W), { weight: "medium" }, {
1337
+ default: f(() => [
1338
+ y(h(r.value.subject || "—"), 1)
1339
+ ]),
1340
+ _: 1
1341
+ })
1342
+ ]),
1343
+ r.value.html ? (p(), w("iframe", {
1344
+ key: 0,
1345
+ ref_key: "frame",
1346
+ ref: x,
1347
+ class: "wx-notifications-preview__frame",
1348
+ sandbox: "allow-same-origin",
1349
+ title: s(e)("panel.preview"),
1350
+ srcdoc: v.value,
1351
+ style: Ne({ height: `${C.value}px` }),
1352
+ onLoad: N
1353
+ }, null, 44, It)) : (p(), w("div", Dt, h(r.value.body), 1))
1354
+ ])),
1355
+ r.value.plain.trim() === "" ? (p(), _(s(W), {
1356
+ key: 2,
1357
+ size: "sm",
1358
+ tone: "muted"
1359
+ }, {
1360
+ default: f(() => [
1361
+ y(h(s(e)("panel.preview-empty")), 1)
1362
+ ]),
1363
+ _: 1
1364
+ })) : j("", !0),
1365
+ r.value.truncated ? (p(), _(s(H), {
1366
+ key: 3,
1367
+ type: "warning",
1368
+ variant: "soft",
1369
+ description: s(e)("panel.preview-truncated", { limit: String(s(a).provider.value?.limit ?? "") })
1370
+ }, null, 8, ["description"])) : j("", !0),
1371
+ r.value.unknown.length > 0 && s(a).event.value ? (p(), _(s(W), {
1372
+ key: 4,
1373
+ size: "sm",
1374
+ tone: "muted"
1375
+ }, {
1376
+ default: f(() => [
1377
+ y(h(b.value), 1)
1378
+ ]),
1379
+ _: 1
1380
+ })) : j("", !0)
1381
+ ], 64)) : j("", !0)
1382
+ ]),
1383
+ _: 1
1384
+ }, 8, ["title"]));
1385
+ }
1386
+ }), en = /* @__PURE__ */ B(Ht, [["__scopeId", "data-v-2e2a2dc3"]]), tn = me(() => import("./NotificationsPage-BkTBIV0B.js")), nn = me(() => import("./ChannelPage-vxVhttk3.js"));
1387
+ export {
1388
+ Ye as C,
1389
+ ft as E,
1390
+ en as M,
1391
+ et as N,
1392
+ M as T,
1393
+ nn as W,
1394
+ B as _,
1395
+ dt as a,
1396
+ tn as b,
1397
+ ye as c,
1398
+ Ft as d,
1399
+ _e as e,
1400
+ Jt as f,
1401
+ ht as g,
1402
+ $e as h,
1403
+ Ct as i,
1404
+ Xe as j,
1405
+ pe as k,
1406
+ ot as l,
1407
+ X as m,
1408
+ Yt as n,
1409
+ Zt as p,
1410
+ At as r,
1411
+ ke as s,
1412
+ Mt as t,
1413
+ U as u,
1414
+ it as v
1415
+ };
1416
+ //# sourceMappingURL=index-P5vFp-2X.js.map