@webx-ui/module-notifications 0.3.0 → 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.
@@ -2,7 +2,7 @@ import { defineComponent as ne, ref as v, computed as f, openBlock as o, createB
2
2
  import { useRoute as Ce, useRouter as Te, onBeforeRouteLeave as Ve } from "vue-router";
3
3
  import { useModal as Be, WxDialog as Ae, WxText as ae, WxFormItem as Me, WxSelect as je, WxAlert as W, WxSpace as Oe, WxButton as K, useLocales as De, createModal as Ee, confirm as te, WxSkeleton as Le, WxBadge as qe, WxActionBar as Pe, toast as p } from "@webx-ui/core";
4
4
  import { useAdmin as ie, useTranslate as se, useErrorText as re, provideHistorySubject as Ke, useBodyKeys as Re, WxScreenHead as Ue, WxScreen as ze, WxSaveState as Je } from "@webx-ui/module-admin";
5
- import { c as oe, u as ue, p as Fe, f as He, M as Ie, s as Ge, _ as Qe } from "./index-Bki9dkMd.js";
5
+ import { c as oe, u as ue, p as Fe, f as He, M as Ie, s as Ge, _ as Qe } from "./index-P5vFp-2X.js";
6
6
  const Xe = /* @__PURE__ */ ne({
7
7
  name: "WxNotificationsTestDialog",
8
8
  __name: "TestDialog",
@@ -428,4 +428,4 @@ const Xe = /* @__PURE__ */ ne({
428
428
  export {
429
429
  ia as default
430
430
  };
431
- //# sourceMappingURL=ChannelPage-DB6cyt1W.js.map
431
+ //# sourceMappingURL=ChannelPage-vxVhttk3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelPage-DB6cyt1W.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 { fillOnEvent, sampleOf } from './defaults'\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 default template. */\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 sample = sampleOf(\n found.events.find((one) => one.key === event),\n provider,\n )\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: sample ? { ...sample.template } : { [locale]: '' },\n subject: sample?.subject ? { ...sample.subject } : { [locale]: '' },\n }\n}\n\n// An event chosen for a channel whose message is still empty brings its default template.\nfillOnEvent(context, loading, () => toast.info(t('panel.default-inserted')))\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","sample","sampleOf","locale","settings","fillOnEvent","toast","administrators","load","made","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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"}
1
+ {"version":3,"file":"ChannelPage-vxVhttk3.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 { fillOnEvent, sampleOf } from './defaults'\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 default template. */\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 sample = sampleOf(\n found.events.find((one) => one.key === event),\n provider,\n )\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: sample ? { ...sample.template } : { [locale]: '' },\n subject: sample?.subject ? { ...sample.subject } : { [locale]: '' },\n }\n}\n\n// An event chosen for a channel whose message is still empty brings its default template.\nfillOnEvent(context, loading, () => toast.info(t('panel.default-inserted')))\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","sample","sampleOf","locale","settings","fillOnEvent","toast","administrators","load","made","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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"}
@@ -2,7 +2,7 @@ import { defineComponent as le, ref as m, computed as f, openBlock as p, createB
2
2
  import { useRoute as ze, useRouter as Ce } from "vue-router";
3
3
  import { useModal as Ne, WxDialog as $e, WxText as v, WxFormItem as A, WxSegmented as Be, WxSelect as E, WxSpace as Se, WxButton as Q, createModal as Te, WxAlert as Ue, WxTable as X, WxSwitch as Y, WxBadge as R, WxIcon as Me, toast as d, confirm as Z } from "@webx-ui/core";
4
4
  import { useTranslate as ne, useAdmin as je, useErrorText as qe, rowMenuWidth as ee, WxListScreen as Re, WxRowMenu as ae, WxDate as te } from "@webx-ui/module-admin";
5
- import { u as ie, c as Ae, _ as De } from "./index-Bki9dkMd.js";
5
+ import { u as ie, c as Ae, _ as De } from "./index-P5vFp-2X.js";
6
6
  const Fe = /* @__PURE__ */ le({
7
7
  name: "WxNotificationsNewChannel",
8
8
  __name: "NewChannelDialog",
@@ -666,4 +666,4 @@ const Fe = /* @__PURE__ */ le({
666
666
  export {
667
667
  ea as default
668
668
  };
669
- //# sourceMappingURL=NotificationsPage-CtP9bFgU.js.map
669
+ //# sourceMappingURL=NotificationsPage-BkTBIV0B.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationsPage-CtP9bFgU.js","sources":["../src/NewChannelDialog.vue","../src/NotificationsPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport {\n useModal,\n WxButton,\n WxDialog,\n WxFormItem,\n WxSegmented,\n WxSelect,\n WxSpace,\n WxText,\n} from '@webx-ui/core'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { useNotificationsMessages } from './i18n'\nimport type { NotificationsMeta } from './types'\n\n/**\n * \"New channel\" (§10.2): the kind first — a channel of another kind is another channel — and the\n * event if it is for one, which is what fills the template with the event's sample.\n */\ndefineOptions({ name: 'WxNotificationsNewChannel' })\n\nconst props = defineProps<{ meta: NotificationsMeta }>()\n\nconst { open, resolve, dismiss } = useModal<{ provider: string; event: string | null }>()\n\nuseNotificationsMessages()\n\nconst t = useTranslate('webx-notifications')\n\nconst provider = ref(props.meta.providers[0]?.key ?? '')\nconst event = ref<string | null>(null)\n\nconst providers = computed(() =>\n props.meta.providers.map((one) => ({ value: one.key, label: one.label, icon: one.icon })),\n)\n\nconst events = computed(() => [\n { value: '', label: t('panel.any-event') },\n ...props.meta.events.map((one) => ({ value: one.key, label: one.label })),\n])\n\nfunction go(): void {\n resolve({ provider: provider.value, event: event.value === '' ? null : event.value })\n}\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('panel.new-title')\" :width=\"460\">\n <wx-text size=\"sm\" tone=\"muted\">{{ t('panel.new-help') }}</wx-text>\n\n <wx-form-item :label=\"t('panel.new-provider')\">\n <wx-segmented v-model=\"provider\" :options=\"providers\" />\n </wx-form-item>\n\n <wx-form-item :label=\"t('panel.new-event')\">\n <wx-select\n :model-value=\"event ?? ''\"\n :options=\"events\"\n @update:model-value=\"(value) => (event = value === '' ? null : String(value))\"\n />\n </wx-form-item>\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\" :disabled=\"provider === ''\" @click=\"go\">\n {{ t('panel.new-create') }}\n </wx-button>\n </wx-space>\n </template>\n </wx-dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport {\n confirm,\n createModal,\n toast,\n WxAlert,\n WxBadge,\n WxFormItem,\n WxIcon,\n WxSelect,\n WxSwitch,\n WxTable,\n WxText,\n type IconName,\n type TabItem,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport {\n rowMenuWidth,\n useAdmin,\n useErrorText,\n useTranslate,\n WxDate,\n WxListScreen,\n WxRowMenu,\n type RowAction,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport { createNotificationsApi } from './api'\nimport { useNotificationsMessages } from './i18n'\nimport NewChannelDialog from './NewChannelDialog.vue'\nimport type {\n ChannelRow,\n DeliveriesPage,\n DeliveryRow,\n DeliveryStatus,\n NotificationsMeta,\n} from './types'\n\n/**\n * The section (§10.1): the channels, the log of what they sent, and the bin — three views of one\n * list screen, the open one in the address (`?view=log`), so a link to the log is a link to it.\n *\n * A channel opens on a page of its own: its form is long, and the preview beside it needs the\n * width a pane next to a list would take away.\n */\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/notifications' })\n\nconst admin = useAdmin()\nconst api = createNotificationsApi(admin)\nconst route = useRoute()\nconst router = useRouter()\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 canManage = computed(() => admin.can('notifications.manage'))\n\nconst title = computed(\n () =>\n admin.state.manifest?.modules.find((module) => module.id === 'notifications')?.title ??\n t('module.title'),\n)\n\ntype View = '' | 'log' | 'bin'\n\nconst view = computed<View>({\n get: () => {\n const asked = route.query.view\n\n return asked === 'log' || asked === 'bin' ? asked : ''\n },\n set: (value) => {\n void router.replace({\n query: { ...route.query, view: value === '' ? undefined : value, page: undefined },\n })\n },\n})\n\nconst meta = ref<NotificationsMeta | null>(null)\nconst channels = ref<ChannelRow[]>([])\nconst bin = ref<ChannelRow[]>([])\nconst environment = ref('production')\nconst loading = ref(true)\n\nconst views = computed<TabItem[]>(() => [\n { value: '', label: t('panel.channels'), badge: channels.value.length },\n { value: 'log', label: t('panel.log') },\n { value: 'bin', label: t('panel.bin'), badge: bin.value.length || undefined },\n])\n\nasync function loadChannels(): Promise<void> {\n loading.value = true\n\n try {\n const [live, trashed] = await Promise.all([api.channels(), api.channels({ trashed: true })])\n\n channels.value = live.data\n bin.value = trashed.data\n environment.value = live.environment\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nvoid loadChannels()\napi\n .meta()\n .then((found) => (meta.value = found))\n .catch(() => undefined)\n\nconst create = createModal<{ provider: string; event: string | null }, { meta: NotificationsMeta }>(\n NewChannelDialog,\n)\n\nasync function add(): Promise<void> {\n if (meta.value === null) return\n\n const chosen = await create({ meta: meta.value })\n\n if (!chosen) return\n\n void router.push({\n path: `${props.base}/channels/new`,\n query: { provider: chosen.provider, ...(chosen.event ? { event: chosen.event } : {}) },\n })\n}\n\nfunction open(row: ChannelRow): void {\n void router.push(`${props.base}/channels/${row.id}`)\n}\n\nasync function toggle(row: ChannelRow, enabled: boolean): Promise<void> {\n try {\n const detail = await api.save(row.id, { enabled })\n\n channels.value = channels.value.map((one) => (one.id === row.id ? detail.channel : one))\n toast.success(enabled ? t('panel.enabled') : t('panel.disabled'))\n } catch (error) {\n // Switching on a channel that is not complete is refused in the server's words (§3.3).\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n toast.danger(body?.errors ? Object.values(body.errors).flat().join(' ') : message(error))\n }\n}\n\nasync function copy(row: ChannelRow): Promise<void> {\n try {\n const detail = await api.copy(row.id)\n\n toast.success(t('panel.copied', { name: detail.channel.name }))\n await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function remove(row: ChannelRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.delete-title', { title: row.name }),\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 await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function restore(row: ChannelRow): Promise<void> {\n try {\n await api.restore(row.id)\n toast.success(t('panel.restored'))\n await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function purge(row: ChannelRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.purge-title', { title: row.name }),\n message: t('panel.purge-text'),\n confirmText: t('panel.purge'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.purge(row.id)\n toast.success(t('panel.purged'))\n await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction actionsFor(row: ChannelRow): RowAction[] {\n if (view.value === 'bin') {\n return canManage.value\n ? [\n {\n key: 'restore',\n label: t('panel.restore'),\n icon: 'refresh',\n run: () => void restore(row),\n },\n {\n key: 'purge',\n label: t('panel.purge'),\n icon: 'trash',\n danger: true,\n run: () => void purge(row),\n },\n ]\n : []\n }\n\n return [\n { key: 'edit', label: t('panel.edit'), icon: 'edit', run: () => open(row) },\n ...(canManage.value\n ? [\n {\n key: 'copy',\n label: t('panel.copy'),\n icon: 'copy' as IconName,\n run: () => void copy(row),\n },\n {\n key: 'delete',\n label: t('panel.delete'),\n icon: 'trash' as IconName,\n danger: true,\n run: () => void remove(row),\n },\n ]\n : []),\n ]\n}\n\n/*\n * The name and the menu stay at every width; the event goes first, then the last delivery and the\n * count — on a phone a row is the name, the switch and the `···`.\n */\nconst channelColumns = computed<TableColumn<ChannelRow>[]>(() => [\n { key: 'name', label: t('module.channel'), minWidth: 160 },\n { key: 'event', label: t('panel.new-event'), width: 200, hideBelow: 720 },\n { key: 'last_delivery', label: t('panel.column-status'), width: 170, hideBelow: 560 },\n ...(view.value === 'bin'\n ? []\n : [{ key: 'enabled', label: '', width: 64, align: 'center' as const }]),\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n])\n\nconst rows = computed(() => (view.value === 'bin' ? bin.value : channels.value))\n\nfunction iconOf(row: { icon?: string | null; provider: string }): IconName {\n return (row.icon ?? (row.provider === 'telegram' ? 'send' : 'mail')) as IconName\n}\n\n/* ---------------------------------------------------------------------------- the log ----- */\n\nconst page = ref<DeliveriesPage | null>(null)\nconst logLoading = ref(false)\nconst status = ref<DeliveryStatus | ''>('')\nconst channelFilter = ref<number | ''>('')\nconst withTests = ref(true)\nconst lastState = ref<TableState | undefined>(undefined)\n\nasync function loadLog(state?: TableState): Promise<void> {\n lastState.value = state ?? lastState.value\n logLoading.value = true\n\n try {\n page.value = await api.deliveries({\n page: lastState.value?.page ?? 1,\n per_page: lastState.value?.perPage,\n status: status.value === '' ? null : status.value,\n channel: channelFilter.value === '' ? null : channelFilter.value,\n tests: withTests.value,\n })\n environment.value = page.value.environment\n } catch (error) {\n toast.danger(message(error))\n } finally {\n logLoading.value = false\n }\n}\n\nwatch(\n view,\n (next) => {\n if (next === 'log') void loadLog()\n },\n { immediate: true },\n)\n\nwatch(\n [status, channelFilter, withTests],\n () => void loadLog({ ...(lastState.value ?? {}), page: 1 } as TableState),\n)\n\nconst filtersCount = computed(\n () => Number(status.value !== '') + Number(channelFilter.value !== '') + Number(!withTests.value),\n)\n\nconst statusOptions = computed(() => [\n { value: '', label: t('panel.all-statuses') },\n ...(['queued', 'sent', 'failed', 'skipped'] as const).map((value) => ({\n value,\n label: t(`module.statuses.${value}`),\n })),\n])\n\nconst channelOptions = computed(() => [\n { value: '', label: t('panel.all-channels') },\n ...channels.value.map((one) => ({ value: one.id, label: one.name })),\n])\n\nconst logColumns = computed<TableColumn<DeliveryRow>[]>(() => [\n { key: 'created_at', label: t('panel.column-when'), width: 150 },\n { key: 'recipient', label: t('panel.column-recipient'), minWidth: 160 },\n { key: 'channel_name', label: t('panel.column-channel'), width: 180, hideBelow: 760 },\n { key: 'status', label: t('panel.column-status'), width: 140 },\n { key: 'attempts', label: t('panel.column-attempts'), width: 90, align: 'right', hideBelow: 900 },\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n])\n\nconst tone: Record<DeliveryStatus, 'success' | 'danger' | 'warning' | 'default'> = {\n sent: 'success',\n failed: 'danger',\n queued: 'warning',\n skipped: 'default',\n}\n\nasync function retry(row: DeliveryRow): Promise<void> {\n try {\n await api.retry(row.id)\n toast.success(t('panel.retried'))\n await loadLog()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction logActionsFor(row: DeliveryRow): RowAction[] {\n const list: RowAction[] = []\n\n if (row.subject_url) {\n list.push({\n key: 'open',\n label: t('panel.open-subject'),\n icon: 'external-link',\n href: row.subject_url,\n target: '_self',\n })\n }\n\n if (row.channel_id !== null) {\n list.push({\n key: 'channel',\n label: t('panel.edit'),\n icon: 'edit',\n run: () => void router.push(`${props.base}/channels/${row.channel_id}`),\n })\n }\n\n if (row.retryable && canManage.value) {\n list.push({\n key: 'retry',\n label: t('panel.retry'),\n icon: 'refresh',\n run: () => void retry(row),\n })\n }\n\n return list\n}\n\nfunction why(row: DeliveryRow): string | null {\n if (row.error) return row.error\n if (row.reason) return t(`module.reasons.${row.reason}`)\n\n return null\n}\n\nconst actions = computed<ScreenAction[]>(() =>\n canManage.value\n ? [\n {\n key: 'new',\n label: t('panel.new'),\n icon: 'plus',\n primary: true,\n disabled: meta.value === null,\n run: () => void add(),\n },\n ]\n : [],\n)\n</script>\n\n<template>\n <wx-list-screen v-model:view=\"view\" :title=\"title\" :views=\"views\" :actions=\"actions\">\n <!-- Over the rows and not over the tabs: it is about what the channels do, not about a view. -->\n <div v-if=\"environment !== 'production'\" class=\"wx-notifications-list__note\">\n <wx-alert type=\"info\" variant=\"soft\" :description=\"t('panel.environment', { environment })\" />\n </div>\n\n <wx-table\n v-if=\"view !== 'log'\"\n :data=\"rows\"\n :columns=\"channelColumns\"\n row-key=\"id\"\n hover\n clickable\n flush\n layout=\"fixed\"\n :loading=\"loading\"\n :cards-below=\"0\"\n :pagination=\"false\"\n :empty-text=\"view === 'bin' ? t('panel.empty-bin') : t('panel.empty-channels-text')\"\n :aria-label=\"title\"\n @row-click=\"(row: ChannelRow) => view !== 'bin' && open(row)\"\n >\n <template #cell-name=\"{ row }\">\n <span class=\"wx-notifications-list__name\">\n <wx-icon :name=\"iconOf(row)\" class=\"wx-notifications-list__icon\" />\n <span class=\"wx-notifications-list__text\">\n <wx-text truncate weight=\"medium\">{{ row.name }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" truncate>\n {{ row.provider_label }} ·\n {{ t('panel.recipients', { count: String(row.recipients) }) }}\n </wx-text>\n </span>\n </span>\n </template>\n\n <template #cell-event=\"{ row }\">\n <wx-badge v-if=\"!row.event_declared\" type=\"warning\">{{\n t('panel.event-undeclared')\n }}</wx-badge>\n <wx-text v-else size=\"sm\" :tone=\"row.event ? 'default' : 'muted'\" truncate>\n {{ row.event_label ?? t('panel.any-event') }}\n </wx-text>\n </template>\n\n <template #cell-last_delivery=\"{ row }\">\n <span v-if=\"row.last_delivery\" class=\"wx-notifications-list__last\">\n <wx-badge :type=\"tone[row.last_delivery.status]\" dot>\n {{ t(`module.statuses.${row.last_delivery.status}`) }}\n </wx-badge>\n <wx-date :value=\"row.last_delivery.at\" class=\"wx-notifications-list__when\" />\n </span>\n <wx-text v-else size=\"sm\" tone=\"muted\">{{ t('panel.never-sent') }}</wx-text>\n </template>\n\n <template #cell-enabled=\"{ row }\">\n <span @click.stop>\n <wx-switch\n :model-value=\"row.enabled\"\n :disabled=\"!canManage\"\n :aria-label=\"t('panel.enable')\"\n size=\"sm\"\n @update:model-value=\"(on) => toggle(row, Boolean(on))\"\n />\n </span>\n </template>\n\n <template #cell-actions=\"{ row }\">\n <span @click.stop>\n <wx-row-menu :actions=\"actionsFor(row)\" :label=\"row.name\" />\n </span>\n </template>\n </wx-table>\n\n <wx-table\n v-else\n :data=\"page\"\n :columns=\"logColumns\"\n row-key=\"id\"\n hover\n flush\n layout=\"fixed\"\n expandable\n :loading=\"logLoading\"\n :cards-below=\"0\"\n :filters-count=\"filtersCount\"\n :filters-label=\"t('panel.filters')\"\n :empty-text=\"t('panel.log-empty')\"\n :aria-label=\"t('panel.log')\"\n @state-change=\"loadLog\"\n >\n <template #filters>\n <wx-form-item :label=\"t('panel.column-status')\">\n <wx-select v-model=\"status\" :options=\"statusOptions\" size=\"sm\" />\n </wx-form-item>\n <wx-form-item :label=\"t('panel.column-channel')\">\n <wx-select v-model=\"channelFilter\" :options=\"channelOptions\" size=\"sm\" />\n </wx-form-item>\n <wx-switch v-model=\"withTests\" size=\"sm\">{{ t('panel.with-tests') }}</wx-switch>\n </template>\n\n <template #cell-created_at=\"{ row }\">\n <wx-date :value=\"row.sent_at ?? row.created_at\" />\n </template>\n\n <template #cell-recipient=\"{ row }\">\n <span class=\"wx-notifications-list__text\">\n <wx-text truncate>{{ row.recipient_label ?? row.recipient }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" truncate>\n {{ row.event_label ?? row.event }}\n </wx-text>\n </span>\n </template>\n\n <template #cell-channel_name=\"{ row }\">\n <wx-text size=\"sm\" truncate :tone=\"row.channel_id === null ? 'muted' : 'default'\">\n {{ row.channel_name }}{{ row.channel_id === null ? ` (${t('panel.channel-gone')})` : '' }}\n </wx-text>\n </template>\n\n <template #cell-status=\"{ row }\">\n <span class=\"wx-notifications-list__last\">\n <wx-badge :type=\"tone[row.status]\" dot>{{ t(`module.statuses.${row.status}`) }}</wx-badge>\n <wx-badge v-if=\"row.is_test\">{{ t('panel.test-mark') }}</wx-badge>\n </span>\n </template>\n\n <template #cell-attempts=\"{ row }\">\n <wx-text size=\"sm\">{{ row.attempts }}</wx-text>\n </template>\n\n <template #cell-actions=\"{ row }\">\n <wx-row-menu :actions=\"logActionsFor(row)\" :label=\"row.recipient\" />\n </template>\n\n <template #expanded=\"{ row }\">\n <div class=\"wx-notifications-list__details\">\n <wx-text v-if=\"why(row)\" size=\"sm\" :tone=\"row.status === 'failed' ? 'danger' : 'muted'\">\n {{ why(row) }}\n </wx-text>\n <wx-text v-if=\"row.unknown_variables.length > 0\" size=\"sm\" tone=\"muted\">\n {{ t('panel.unknown-variables', { names: row.unknown_variables.join(', ') }) }}\n </wx-text>\n <wx-text v-if=\"row.truncated\" size=\"sm\" tone=\"muted\">{{ t('panel.cut-mark') }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" mono>{{ row.recipient }}</wx-text>\n </div>\n </template>\n </wx-table>\n </wx-list-screen>\n</template>\n\n<style scoped>\n.wx-notifications-list__note {\n padding: var(--wx-space-12) var(--wx-space-16) 0;\n}\n\n.wx-notifications-list__name {\n display: flex;\n align-items: center;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-notifications-list__icon {\n flex: none;\n color: var(--wx-text-muted);\n}\n\n.wx-notifications-list__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.wx-notifications-list__last {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-notifications-list__when {\n font-size: var(--wx-font-size-sm);\n color: var(--wx-text-muted);\n}\n\n.wx-notifications-list__details {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n padding: var(--wx-space-8) var(--wx-space-16);\n}\n</style>\n"],"names":["props","__props","open","resolve","dismiss","useModal","useNotificationsMessages","t","useTranslate","provider","ref","event","providers","computed","one","events","go","_createBlock","_unref","WxDialog","$event","_createVNode","WxSpace","WxButton","WxText","WxFormItem","WxSegmented","WxSelect","_cache","value","admin","useAdmin","api","createNotificationsApi","route","useRoute","router","useRouter","message","useErrorText","canManage","title","module","view","asked","meta","channels","bin","environment","loading","views","loadChannels","live","trashed","error","toast","found","create","createModal","NewChannelDialog","add","chosen","row","toggle","enabled","detail","body","copy","remove","confirm","restore","purge","actionsFor","channelColumns","rowMenuWidth","rows","iconOf","page","logLoading","status","channelFilter","withTests","lastState","loadLog","state","watch","next","filtersCount","statusOptions","channelOptions","logColumns","tone","retry","logActionsFor","list","why","actions","WxListScreen","_openBlock","_createElementBlock","_hoisted_1","WxAlert","WxTable","_withCtx","_createElementVNode","_hoisted_2","WxIcon","_hoisted_3","_createTextVNode","_toDisplayString","WxBadge","_hoisted_4","WxDate","WxSwitch","on","WxRowMenu","_hoisted_5","_hoisted_6","_hoisted_7"],"mappings":"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"}
1
+ {"version":3,"file":"NotificationsPage-BkTBIV0B.js","sources":["../src/NewChannelDialog.vue","../src/NotificationsPage.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport {\n useModal,\n WxButton,\n WxDialog,\n WxFormItem,\n WxSegmented,\n WxSelect,\n WxSpace,\n WxText,\n} from '@webx-ui/core'\nimport { useTranslate } from '@webx-ui/module-admin'\nimport { useNotificationsMessages } from './i18n'\nimport type { NotificationsMeta } from './types'\n\n/**\n * \"New channel\" (§10.2): the kind first — a channel of another kind is another channel — and the\n * event if it is for one, which is what fills the template with the event's sample.\n */\ndefineOptions({ name: 'WxNotificationsNewChannel' })\n\nconst props = defineProps<{ meta: NotificationsMeta }>()\n\nconst { open, resolve, dismiss } = useModal<{ provider: string; event: string | null }>()\n\nuseNotificationsMessages()\n\nconst t = useTranslate('webx-notifications')\n\nconst provider = ref(props.meta.providers[0]?.key ?? '')\nconst event = ref<string | null>(null)\n\nconst providers = computed(() =>\n props.meta.providers.map((one) => ({ value: one.key, label: one.label, icon: one.icon })),\n)\n\nconst events = computed(() => [\n { value: '', label: t('panel.any-event') },\n ...props.meta.events.map((one) => ({ value: one.key, label: one.label })),\n])\n\nfunction go(): void {\n resolve({ provider: provider.value, event: event.value === '' ? null : event.value })\n}\n</script>\n\n<template>\n <wx-dialog v-model:open=\"open\" :title=\"t('panel.new-title')\" :width=\"460\">\n <wx-text size=\"sm\" tone=\"muted\">{{ t('panel.new-help') }}</wx-text>\n\n <wx-form-item :label=\"t('panel.new-provider')\">\n <wx-segmented v-model=\"provider\" :options=\"providers\" />\n </wx-form-item>\n\n <wx-form-item :label=\"t('panel.new-event')\">\n <wx-select\n :model-value=\"event ?? ''\"\n :options=\"events\"\n @update:model-value=\"(value) => (event = value === '' ? null : String(value))\"\n />\n </wx-form-item>\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\" :disabled=\"provider === ''\" @click=\"go\">\n {{ t('panel.new-create') }}\n </wx-button>\n </wx-space>\n </template>\n </wx-dialog>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'\nimport {\n confirm,\n createModal,\n toast,\n WxAlert,\n WxBadge,\n WxFormItem,\n WxIcon,\n WxSelect,\n WxSwitch,\n WxTable,\n WxText,\n type IconName,\n type TabItem,\n type TableColumn,\n type TableState,\n} from '@webx-ui/core'\nimport {\n rowMenuWidth,\n useAdmin,\n useErrorText,\n useTranslate,\n WxDate,\n WxListScreen,\n WxRowMenu,\n type RowAction,\n type ScreenAction,\n} from '@webx-ui/module-admin'\nimport { createNotificationsApi } from './api'\nimport { useNotificationsMessages } from './i18n'\nimport NewChannelDialog from './NewChannelDialog.vue'\nimport type {\n ChannelRow,\n DeliveriesPage,\n DeliveryRow,\n DeliveryStatus,\n NotificationsMeta,\n} from './types'\n\n/**\n * The section (§10.1): the channels, the log of what they sent, and the bin — three views of one\n * list screen, the open one in the address (`?view=log`), so a link to the log is a link to it.\n *\n * A channel opens on a page of its own: its form is long, and the preview beside it needs the\n * width a pane next to a list would take away.\n */\nconst props = withDefaults(defineProps<{ base?: string }>(), { base: '/notifications' })\n\nconst admin = useAdmin()\nconst api = createNotificationsApi(admin)\nconst route = useRoute()\nconst router = useRouter()\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 canManage = computed(() => admin.can('notifications.manage'))\n\nconst title = computed(\n () =>\n admin.state.manifest?.modules.find((module) => module.id === 'notifications')?.title ??\n t('module.title'),\n)\n\ntype View = '' | 'log' | 'bin'\n\nconst view = computed<View>({\n get: () => {\n const asked = route.query.view\n\n return asked === 'log' || asked === 'bin' ? asked : ''\n },\n set: (value) => {\n void router.replace({\n query: { ...route.query, view: value === '' ? undefined : value, page: undefined },\n })\n },\n})\n\nconst meta = ref<NotificationsMeta | null>(null)\nconst channels = ref<ChannelRow[]>([])\nconst bin = ref<ChannelRow[]>([])\nconst environment = ref('production')\nconst loading = ref(true)\n\nconst views = computed<TabItem[]>(() => [\n { value: '', label: t('panel.channels'), badge: channels.value.length },\n { value: 'log', label: t('panel.log') },\n { value: 'bin', label: t('panel.bin'), badge: bin.value.length || undefined },\n])\n\nasync function loadChannels(): Promise<void> {\n loading.value = true\n\n try {\n const [live, trashed] = await Promise.all([api.channels(), api.channels({ trashed: true })])\n\n channels.value = live.data\n bin.value = trashed.data\n environment.value = live.environment\n } catch (error) {\n toast.danger(message(error))\n } finally {\n loading.value = false\n }\n}\n\nvoid loadChannels()\napi\n .meta()\n .then((found) => (meta.value = found))\n .catch(() => undefined)\n\nconst create = createModal<{ provider: string; event: string | null }, { meta: NotificationsMeta }>(\n NewChannelDialog,\n)\n\nasync function add(): Promise<void> {\n if (meta.value === null) return\n\n const chosen = await create({ meta: meta.value })\n\n if (!chosen) return\n\n void router.push({\n path: `${props.base}/channels/new`,\n query: { provider: chosen.provider, ...(chosen.event ? { event: chosen.event } : {}) },\n })\n}\n\nfunction open(row: ChannelRow): void {\n void router.push(`${props.base}/channels/${row.id}`)\n}\n\nasync function toggle(row: ChannelRow, enabled: boolean): Promise<void> {\n try {\n const detail = await api.save(row.id, { enabled })\n\n channels.value = channels.value.map((one) => (one.id === row.id ? detail.channel : one))\n toast.success(enabled ? t('panel.enabled') : t('panel.disabled'))\n } catch (error) {\n // Switching on a channel that is not complete is refused in the server's words (§3.3).\n const body = (error as { body?: { errors?: Record<string, string[]> } }).body\n\n toast.danger(body?.errors ? Object.values(body.errors).flat().join(' ') : message(error))\n }\n}\n\nasync function copy(row: ChannelRow): Promise<void> {\n try {\n const detail = await api.copy(row.id)\n\n toast.success(t('panel.copied', { name: detail.channel.name }))\n await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function remove(row: ChannelRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.delete-title', { title: row.name }),\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 await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function restore(row: ChannelRow): Promise<void> {\n try {\n await api.restore(row.id)\n toast.success(t('panel.restored'))\n await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nasync function purge(row: ChannelRow): Promise<void> {\n const agreed = await confirm({\n title: t('panel.purge-title', { title: row.name }),\n message: t('panel.purge-text'),\n confirmText: t('panel.purge'),\n cancelText: t('panel.cancel'),\n tone: 'danger',\n })\n\n if (!agreed) return\n\n try {\n await api.purge(row.id)\n toast.success(t('panel.purged'))\n await loadChannels()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction actionsFor(row: ChannelRow): RowAction[] {\n if (view.value === 'bin') {\n return canManage.value\n ? [\n {\n key: 'restore',\n label: t('panel.restore'),\n icon: 'refresh',\n run: () => void restore(row),\n },\n {\n key: 'purge',\n label: t('panel.purge'),\n icon: 'trash',\n danger: true,\n run: () => void purge(row),\n },\n ]\n : []\n }\n\n return [\n { key: 'edit', label: t('panel.edit'), icon: 'edit', run: () => open(row) },\n ...(canManage.value\n ? [\n {\n key: 'copy',\n label: t('panel.copy'),\n icon: 'copy' as IconName,\n run: () => void copy(row),\n },\n {\n key: 'delete',\n label: t('panel.delete'),\n icon: 'trash' as IconName,\n danger: true,\n run: () => void remove(row),\n },\n ]\n : []),\n ]\n}\n\n/*\n * The name and the menu stay at every width; the event goes first, then the last delivery and the\n * count — on a phone a row is the name, the switch and the `···`.\n */\nconst channelColumns = computed<TableColumn<ChannelRow>[]>(() => [\n { key: 'name', label: t('module.channel'), minWidth: 160 },\n { key: 'event', label: t('panel.new-event'), width: 200, hideBelow: 720 },\n { key: 'last_delivery', label: t('panel.column-status'), width: 170, hideBelow: 560 },\n ...(view.value === 'bin'\n ? []\n : [{ key: 'enabled', label: '', width: 64, align: 'center' as const }]),\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n])\n\nconst rows = computed(() => (view.value === 'bin' ? bin.value : channels.value))\n\nfunction iconOf(row: { icon?: string | null; provider: string }): IconName {\n return (row.icon ?? (row.provider === 'telegram' ? 'send' : 'mail')) as IconName\n}\n\n/* ---------------------------------------------------------------------------- the log ----- */\n\nconst page = ref<DeliveriesPage | null>(null)\nconst logLoading = ref(false)\nconst status = ref<DeliveryStatus | ''>('')\nconst channelFilter = ref<number | ''>('')\nconst withTests = ref(true)\nconst lastState = ref<TableState | undefined>(undefined)\n\nasync function loadLog(state?: TableState): Promise<void> {\n lastState.value = state ?? lastState.value\n logLoading.value = true\n\n try {\n page.value = await api.deliveries({\n page: lastState.value?.page ?? 1,\n per_page: lastState.value?.perPage,\n status: status.value === '' ? null : status.value,\n channel: channelFilter.value === '' ? null : channelFilter.value,\n tests: withTests.value,\n })\n environment.value = page.value.environment\n } catch (error) {\n toast.danger(message(error))\n } finally {\n logLoading.value = false\n }\n}\n\nwatch(\n view,\n (next) => {\n if (next === 'log') void loadLog()\n },\n { immediate: true },\n)\n\nwatch(\n [status, channelFilter, withTests],\n () => void loadLog({ ...(lastState.value ?? {}), page: 1 } as TableState),\n)\n\nconst filtersCount = computed(\n () => Number(status.value !== '') + Number(channelFilter.value !== '') + Number(!withTests.value),\n)\n\nconst statusOptions = computed(() => [\n { value: '', label: t('panel.all-statuses') },\n ...(['queued', 'sent', 'failed', 'skipped'] as const).map((value) => ({\n value,\n label: t(`module.statuses.${value}`),\n })),\n])\n\nconst channelOptions = computed(() => [\n { value: '', label: t('panel.all-channels') },\n ...channels.value.map((one) => ({ value: one.id, label: one.name })),\n])\n\nconst logColumns = computed<TableColumn<DeliveryRow>[]>(() => [\n { key: 'created_at', label: t('panel.column-when'), width: 150 },\n { key: 'recipient', label: t('panel.column-recipient'), minWidth: 160 },\n { key: 'channel_name', label: t('panel.column-channel'), width: 180, hideBelow: 760 },\n { key: 'status', label: t('panel.column-status'), width: 140 },\n { key: 'attempts', label: t('panel.column-attempts'), width: 90, align: 'right', hideBelow: 900 },\n { key: 'actions', label: '', width: rowMenuWidth, align: 'right' },\n])\n\nconst tone: Record<DeliveryStatus, 'success' | 'danger' | 'warning' | 'default'> = {\n sent: 'success',\n failed: 'danger',\n queued: 'warning',\n skipped: 'default',\n}\n\nasync function retry(row: DeliveryRow): Promise<void> {\n try {\n await api.retry(row.id)\n toast.success(t('panel.retried'))\n await loadLog()\n } catch (error) {\n toast.danger(message(error))\n }\n}\n\nfunction logActionsFor(row: DeliveryRow): RowAction[] {\n const list: RowAction[] = []\n\n if (row.subject_url) {\n list.push({\n key: 'open',\n label: t('panel.open-subject'),\n icon: 'external-link',\n href: row.subject_url,\n target: '_self',\n })\n }\n\n if (row.channel_id !== null) {\n list.push({\n key: 'channel',\n label: t('panel.edit'),\n icon: 'edit',\n run: () => void router.push(`${props.base}/channels/${row.channel_id}`),\n })\n }\n\n if (row.retryable && canManage.value) {\n list.push({\n key: 'retry',\n label: t('panel.retry'),\n icon: 'refresh',\n run: () => void retry(row),\n })\n }\n\n return list\n}\n\nfunction why(row: DeliveryRow): string | null {\n if (row.error) return row.error\n if (row.reason) return t(`module.reasons.${row.reason}`)\n\n return null\n}\n\nconst actions = computed<ScreenAction[]>(() =>\n canManage.value\n ? [\n {\n key: 'new',\n label: t('panel.new'),\n icon: 'plus',\n primary: true,\n disabled: meta.value === null,\n run: () => void add(),\n },\n ]\n : [],\n)\n</script>\n\n<template>\n <wx-list-screen v-model:view=\"view\" :title=\"title\" :views=\"views\" :actions=\"actions\">\n <!-- Over the rows and not over the tabs: it is about what the channels do, not about a view. -->\n <div v-if=\"environment !== 'production'\" class=\"wx-notifications-list__note\">\n <wx-alert type=\"info\" variant=\"soft\" :description=\"t('panel.environment', { environment })\" />\n </div>\n\n <wx-table\n v-if=\"view !== 'log'\"\n :data=\"rows\"\n :columns=\"channelColumns\"\n row-key=\"id\"\n hover\n clickable\n flush\n layout=\"fixed\"\n :loading=\"loading\"\n :cards-below=\"0\"\n :pagination=\"false\"\n :empty-text=\"view === 'bin' ? t('panel.empty-bin') : t('panel.empty-channels-text')\"\n :aria-label=\"title\"\n @row-click=\"(row: ChannelRow) => view !== 'bin' && open(row)\"\n >\n <template #cell-name=\"{ row }\">\n <span class=\"wx-notifications-list__name\">\n <wx-icon :name=\"iconOf(row)\" class=\"wx-notifications-list__icon\" />\n <span class=\"wx-notifications-list__text\">\n <wx-text truncate weight=\"medium\">{{ row.name }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" truncate>\n {{ row.provider_label }} ·\n {{ t('panel.recipients', { count: String(row.recipients) }) }}\n </wx-text>\n </span>\n </span>\n </template>\n\n <template #cell-event=\"{ row }\">\n <wx-badge v-if=\"!row.event_declared\" type=\"warning\">{{\n t('panel.event-undeclared')\n }}</wx-badge>\n <wx-text v-else size=\"sm\" :tone=\"row.event ? 'default' : 'muted'\" truncate>\n {{ row.event_label ?? t('panel.any-event') }}\n </wx-text>\n </template>\n\n <template #cell-last_delivery=\"{ row }\">\n <span v-if=\"row.last_delivery\" class=\"wx-notifications-list__last\">\n <wx-badge :type=\"tone[row.last_delivery.status]\" dot>\n {{ t(`module.statuses.${row.last_delivery.status}`) }}\n </wx-badge>\n <wx-date :value=\"row.last_delivery.at\" class=\"wx-notifications-list__when\" />\n </span>\n <wx-text v-else size=\"sm\" tone=\"muted\">{{ t('panel.never-sent') }}</wx-text>\n </template>\n\n <template #cell-enabled=\"{ row }\">\n <span @click.stop>\n <wx-switch\n :model-value=\"row.enabled\"\n :disabled=\"!canManage\"\n :aria-label=\"t('panel.enable')\"\n size=\"sm\"\n @update:model-value=\"(on) => toggle(row, Boolean(on))\"\n />\n </span>\n </template>\n\n <template #cell-actions=\"{ row }\">\n <span @click.stop>\n <wx-row-menu :actions=\"actionsFor(row)\" :label=\"row.name\" />\n </span>\n </template>\n </wx-table>\n\n <wx-table\n v-else\n :data=\"page\"\n :columns=\"logColumns\"\n row-key=\"id\"\n hover\n flush\n layout=\"fixed\"\n expandable\n :loading=\"logLoading\"\n :cards-below=\"0\"\n :filters-count=\"filtersCount\"\n :filters-label=\"t('panel.filters')\"\n :empty-text=\"t('panel.log-empty')\"\n :aria-label=\"t('panel.log')\"\n @state-change=\"loadLog\"\n >\n <template #filters>\n <wx-form-item :label=\"t('panel.column-status')\">\n <wx-select v-model=\"status\" :options=\"statusOptions\" size=\"sm\" />\n </wx-form-item>\n <wx-form-item :label=\"t('panel.column-channel')\">\n <wx-select v-model=\"channelFilter\" :options=\"channelOptions\" size=\"sm\" />\n </wx-form-item>\n <wx-switch v-model=\"withTests\" size=\"sm\">{{ t('panel.with-tests') }}</wx-switch>\n </template>\n\n <template #cell-created_at=\"{ row }\">\n <wx-date :value=\"row.sent_at ?? row.created_at\" />\n </template>\n\n <template #cell-recipient=\"{ row }\">\n <span class=\"wx-notifications-list__text\">\n <wx-text truncate>{{ row.recipient_label ?? row.recipient }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" truncate>\n {{ row.event_label ?? row.event }}\n </wx-text>\n </span>\n </template>\n\n <template #cell-channel_name=\"{ row }\">\n <wx-text size=\"sm\" truncate :tone=\"row.channel_id === null ? 'muted' : 'default'\">\n {{ row.channel_name }}{{ row.channel_id === null ? ` (${t('panel.channel-gone')})` : '' }}\n </wx-text>\n </template>\n\n <template #cell-status=\"{ row }\">\n <span class=\"wx-notifications-list__last\">\n <wx-badge :type=\"tone[row.status]\" dot>{{ t(`module.statuses.${row.status}`) }}</wx-badge>\n <wx-badge v-if=\"row.is_test\">{{ t('panel.test-mark') }}</wx-badge>\n </span>\n </template>\n\n <template #cell-attempts=\"{ row }\">\n <wx-text size=\"sm\">{{ row.attempts }}</wx-text>\n </template>\n\n <template #cell-actions=\"{ row }\">\n <wx-row-menu :actions=\"logActionsFor(row)\" :label=\"row.recipient\" />\n </template>\n\n <template #expanded=\"{ row }\">\n <div class=\"wx-notifications-list__details\">\n <wx-text v-if=\"why(row)\" size=\"sm\" :tone=\"row.status === 'failed' ? 'danger' : 'muted'\">\n {{ why(row) }}\n </wx-text>\n <wx-text v-if=\"row.unknown_variables.length > 0\" size=\"sm\" tone=\"muted\">\n {{ t('panel.unknown-variables', { names: row.unknown_variables.join(', ') }) }}\n </wx-text>\n <wx-text v-if=\"row.truncated\" size=\"sm\" tone=\"muted\">{{ t('panel.cut-mark') }}</wx-text>\n <wx-text size=\"sm\" tone=\"muted\" mono>{{ row.recipient }}</wx-text>\n </div>\n </template>\n </wx-table>\n </wx-list-screen>\n</template>\n\n<style scoped>\n.wx-notifications-list__note {\n padding: var(--wx-space-12) var(--wx-space-16) 0;\n}\n\n.wx-notifications-list__name {\n display: flex;\n align-items: center;\n gap: var(--wx-space-12);\n min-width: 0;\n}\n\n.wx-notifications-list__icon {\n flex: none;\n color: var(--wx-text-muted);\n}\n\n.wx-notifications-list__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n}\n\n.wx-notifications-list__last {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--wx-space-6);\n min-width: 0;\n}\n\n.wx-notifications-list__when {\n font-size: var(--wx-font-size-sm);\n color: var(--wx-text-muted);\n}\n\n.wx-notifications-list__details {\n display: flex;\n flex-direction: column;\n gap: var(--wx-space-4);\n padding: var(--wx-space-8) var(--wx-space-16);\n}\n</style>\n"],"names":["props","__props","open","resolve","dismiss","useModal","useNotificationsMessages","t","useTranslate","provider","ref","event","providers","computed","one","events","go","_createBlock","_unref","WxDialog","$event","_createVNode","WxSpace","WxButton","WxText","WxFormItem","WxSegmented","WxSelect","_cache","value","admin","useAdmin","api","createNotificationsApi","route","useRoute","router","useRouter","message","useErrorText","canManage","title","module","view","asked","meta","channels","bin","environment","loading","views","loadChannels","live","trashed","error","toast","found","create","createModal","NewChannelDialog","add","chosen","row","toggle","enabled","detail","body","copy","remove","confirm","restore","purge","actionsFor","channelColumns","rowMenuWidth","rows","iconOf","page","logLoading","status","channelFilter","withTests","lastState","loadLog","state","watch","next","filtersCount","statusOptions","channelOptions","logColumns","tone","retry","logActionsFor","list","why","actions","WxListScreen","_openBlock","_createElementBlock","_hoisted_1","WxAlert","WxTable","_withCtx","_createElementVNode","_hoisted_2","WxIcon","_hoisted_3","_createTextVNode","_toDisplayString","WxBadge","_hoisted_4","WxDate","WxSwitch","on","WxRowMenu","_hoisted_5","_hoisted_6","_hoisted_7"],"mappings":"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"}