@webx-ui/module-notifications 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChannelPage-C47YoMPO.js → ChannelPage-DB6cyt1W.js} +148 -144
- package/dist/ChannelPage-DB6cyt1W.js.map +1 -0
- package/dist/MessagePreview.d.ts +3 -1
- package/dist/{NotificationsPage-qWdhMayl.js → NotificationsPage-CtP9bFgU.js} +2 -2
- package/dist/{NotificationsPage-qWdhMayl.js.map → NotificationsPage-CtP9bFgU.js.map} +1 -1
- package/dist/TemplateField.d.ts +9 -0
- package/dist/context.d.ts +10 -0
- package/dist/defaults.d.ts +25 -0
- package/dist/index-Bki9dkMd.js +1414 -0
- package/dist/index-Bki9dkMd.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/render.d.ts +9 -1
- package/dist/style.css +1 -1
- package/dist/types.d.ts +10 -5
- package/package.json +4 -4
- package/dist/ChannelPage-C47YoMPO.js.map +0 -1
- package/dist/index-DIeEPPSh.js +0 -1279
- package/dist/index-DIeEPPSh.js.map +0 -1
|
@@ -0,0 +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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"}
|
package/dist/MessagePreview.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
|
|
2
|
+
frame: HTMLIFrameElement;
|
|
3
|
+
}, HTMLElement>;
|
|
2
4
|
export default _default;
|
|
@@ -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-
|
|
5
|
+
import { u as ie, c as Ae, _ as De } from "./index-Bki9dkMd.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-
|
|
669
|
+
//# sourceMappingURL=NotificationsPage-CtP9bFgU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationsPage-qWdhMayl.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-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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"}
|
package/dist/TemplateField.d.ts
CHANGED
|
@@ -3,6 +3,12 @@ type __VLS_Props = {
|
|
|
3
3
|
localized?: boolean;
|
|
4
4
|
disabled?: boolean;
|
|
5
5
|
minHeight?: string;
|
|
6
|
+
/** One line, for the subject. */
|
|
7
|
+
singleLine?: boolean;
|
|
8
|
+
/** What of the message this is: the variables under the template write into the last one. */
|
|
9
|
+
part?: string;
|
|
10
|
+
/** The variables and the default template under the field. */
|
|
11
|
+
chips?: boolean;
|
|
6
12
|
};
|
|
7
13
|
type __VLS_PublicProps = {
|
|
8
14
|
modelValue?: string | LocalizedValue | null;
|
|
@@ -15,6 +21,9 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
|
|
|
15
21
|
disabled: boolean;
|
|
16
22
|
minHeight: string;
|
|
17
23
|
localized: boolean;
|
|
24
|
+
singleLine: boolean;
|
|
25
|
+
part: string;
|
|
26
|
+
chips: boolean;
|
|
18
27
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
19
28
|
editor: {
|
|
20
29
|
view: import('@codemirror/view').EditorView | null;
|
package/dist/context.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ import { NotificationEvent, NotificationProvider, NotificationsMeta } from './ty
|
|
|
6
6
|
* the event chosen in it, which decide what the template suggests and which addressees there
|
|
7
7
|
* are, and the record itself, which "Find chats" asks the saved token of.
|
|
8
8
|
*
|
|
9
|
+
* The template fields of the form — the template and the subject — tell it which of them the
|
|
10
|
+
* caret was in last, so that a variable clicked under the template goes where the person was
|
|
11
|
+
* typing, the subject included.
|
|
12
|
+
*
|
|
9
13
|
* Provided by the channel's page; a field drawn anywhere else gets an empty one and works as a
|
|
10
14
|
* plain field — a template with only Mustache's syntax to suggest, chats without a search.
|
|
11
15
|
*/
|
|
@@ -16,6 +20,12 @@ export interface ChannelContext {
|
|
|
16
20
|
id: Ref<number | null>;
|
|
17
21
|
provider: ComputedRef<NotificationProvider | null>;
|
|
18
22
|
event: ComputedRef<NotificationEvent | null>;
|
|
23
|
+
/** The template field the caret was in last: `template`, `subject`. */
|
|
24
|
+
focused: Ref<string | null>;
|
|
25
|
+
/** Each template field's way of putting text where its caret is, by part. */
|
|
26
|
+
inserters: Map<string, (snippet: string) => void>;
|
|
27
|
+
/** Into the field the caret was in last, else the template. */
|
|
28
|
+
insert: (snippet: string) => void;
|
|
19
29
|
}
|
|
20
30
|
export declare function provideChannel(meta: Ref<NotificationsMeta | null>, values: Ref<ScreenModel>, id: Ref<number | null>): ChannelContext;
|
|
21
31
|
export declare function useChannel(): ChannelContext;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { ScreenModel } from '@webx-ui/schema';
|
|
3
|
+
import { ChannelContext } from './context';
|
|
4
|
+
import { EventSample, NotificationEvent } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* The default template of an event (`EventDefinition::samplesFor()`): what a channel of a provider
|
|
7
|
+
* starts with, and what "Insert the default template" puts back — the subject and the template in
|
|
8
|
+
* every language the event has words in.
|
|
9
|
+
*/
|
|
10
|
+
export declare function sampleOf(event: NotificationEvent | null | undefined, provider: string | null | undefined): EventSample | null;
|
|
11
|
+
/** Nothing written in any language: what may be filled without asking. */
|
|
12
|
+
export declare function blankText(value: unknown): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* The form's values with the default template in place of the message: every language the
|
|
15
|
+
* template had is replaced, not only the ones the sample has — what is kept would be half one
|
|
16
|
+
* message and half another.
|
|
17
|
+
*/
|
|
18
|
+
export declare function withSample(values: ScreenModel, sample: EventSample, subject: boolean): ScreenModel;
|
|
19
|
+
/**
|
|
20
|
+
* An event chosen for a channel whose message is still empty brings its default template along —
|
|
21
|
+
* nothing to lose. A message already written is kept: "Insert the default template" under it
|
|
22
|
+
* asks first. Synchronous, so that the values a page puts in while `busy` loading are told apart
|
|
23
|
+
* from a choice made in the form.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fillOnEvent(context: ChannelContext, busy: Ref<boolean>, filled: () => void): void;
|