@adatechnology/notification-ui 0.1.0-rc.3 → 0.1.0-rc.5
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/{chunk-I6WQKOCP.js → chunk-QBQ62VZ3.js} +218 -29
- package/dist/chunk-QBQ62VZ3.js.map +1 -0
- package/dist/headless.d.ts +98 -6
- package/dist/headless.js +7 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +178 -32
- package/dist/index.js.map +1 -1
- package/dist/styles.css +103 -0
- package/dist/styles.css.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-I6WQKOCP.js.map +0 -1
package/dist/headless.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as _adatechnology_notification_client from '@adatechnology/notification
|
|
|
4
4
|
import { NotificationClient } from '@adatechnology/notification-client';
|
|
5
5
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
6
6
|
import * as _adatechnology_notification_contracts from '@adatechnology/notification-contracts';
|
|
7
|
-
import { NotificationSummary, NotificationPreference,
|
|
7
|
+
import { NotificationSummary, NotificationPreference, PreviewViewportSpec, RenderedTemplatePreview, NotificationTemplate, TemplateVariableDefinition, TemplateVariableDiff } from '@adatechnology/notification-contracts';
|
|
8
8
|
|
|
9
9
|
var ptBR = {
|
|
10
10
|
"bell.label": "Notificações",
|
|
@@ -52,7 +52,26 @@ var ptBR = {
|
|
|
52
52
|
"settings.saving": "Salvando…",
|
|
53
53
|
"settings.unchanged": "Nada mudou ainda.",
|
|
54
54
|
"settings.close": "Fechar",
|
|
55
|
-
"settings.version": "v"
|
|
55
|
+
"settings.version": "v",
|
|
56
|
+
"settings.newTemplate": "Nova mensagem",
|
|
57
|
+
"settings.remove": "Remover",
|
|
58
|
+
"settings.key": "Chave da notificação",
|
|
59
|
+
"settings.keyHint": "Não muda depois de criada — é por ela que o envio acha a mensagem.",
|
|
60
|
+
"settings.channel": "Canal",
|
|
61
|
+
"settings.locale": "Idioma",
|
|
62
|
+
"settings.variablesTitle": "Variáveis",
|
|
63
|
+
"settings.variablesHint": "Clique para inserir no ponto onde o cursor estava.",
|
|
64
|
+
"settings.unknownVariables": "Variáveis que não existem nesta notificação:",
|
|
65
|
+
"settings.viewport.desktop": "Computador",
|
|
66
|
+
"settings.viewport.mobile": "Celular",
|
|
67
|
+
"settings.constraint.title": "Assunto passa do limite do canal:",
|
|
68
|
+
"settings.constraint.body": "Texto passa do limite do canal:",
|
|
69
|
+
"settings.tab.messages": "Mensagens",
|
|
70
|
+
"settings.tab.routing": "Roteamento",
|
|
71
|
+
"settings.policiesTitle": "Canais permitidos por assunto",
|
|
72
|
+
"settings.policiesHint": "Decisão da empresa. Canal desligado aqui não sai, mesmo que o destinatário tenha pedido.",
|
|
73
|
+
"settings.savePolicies": "Salvar roteamento",
|
|
74
|
+
"settings.discard": "Descartar"
|
|
56
75
|
};
|
|
57
76
|
|
|
58
77
|
/**
|
|
@@ -133,6 +152,37 @@ type UseNotificationStreamOptions = {
|
|
|
133
152
|
*/
|
|
134
153
|
declare function useNotificationStream(options?: UseNotificationStreamOptions): void;
|
|
135
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
157
|
+
*
|
|
158
|
+
* O roteamento: por quais canais cada categoria PODE sair, decidido pela empresa.
|
|
159
|
+
*
|
|
160
|
+
* É a camada que faltava. O chamador já podia enumerar canais em cada `sendNotification`, e quem
|
|
161
|
+
* recebe já tinha preferência — mas "cobrança nunca sai por SMS" não cabia em nenhum dos dois:
|
|
162
|
+
* o primeiro espalha a decisão por todo o código, o segundo deixa ela na mão do destinatário.
|
|
163
|
+
*
|
|
164
|
+
* O modelo aqui é de teto, não de piso: desligar barra o canal para todo mundo; ligar apenas
|
|
165
|
+
* permite, e a preferência de quem recebe continua valendo por cima.
|
|
166
|
+
*/
|
|
167
|
+
type UseCategoryPoliciesResult = {
|
|
168
|
+
readonly isLoading: boolean;
|
|
169
|
+
readonly isSaving: boolean;
|
|
170
|
+
readonly error: string | undefined;
|
|
171
|
+
readonly isDirty: boolean;
|
|
172
|
+
/** Linha ausente é permitido — o mesmo default do servidor, para a tela não mentir. */
|
|
173
|
+
isAllowed: (params: {
|
|
174
|
+
category: string;
|
|
175
|
+
channel: string;
|
|
176
|
+
}) => boolean;
|
|
177
|
+
toggle: (params: {
|
|
178
|
+
category: string;
|
|
179
|
+
channel: string;
|
|
180
|
+
}) => void;
|
|
181
|
+
save: () => void;
|
|
182
|
+
reset: () => void;
|
|
183
|
+
};
|
|
184
|
+
declare function useCategoryPolicies(): UseCategoryPoliciesResult;
|
|
185
|
+
|
|
136
186
|
declare function usePreferences(): _tanstack_react_query.UseQueryResult<NoInfer<readonly NotificationPreference[]>, Error>;
|
|
137
187
|
declare function useUpdatePreferences(): _tanstack_react_query.UseMutationResult<readonly NotificationPreference[], Error, readonly NotificationPreference[], unknown>;
|
|
138
188
|
declare function useTemplates(): _tanstack_react_query.UseQueryResult<NoInfer<readonly _adatechnology_notification_contracts.NotificationTemplate[]>, Error>;
|
|
@@ -153,6 +203,17 @@ declare function useUpsertTemplate(): _tanstack_react_query.UseMutationResult<_a
|
|
|
153
203
|
subject?: string | undefined;
|
|
154
204
|
whatsappTemplateName?: string | undefined;
|
|
155
205
|
}, unknown>;
|
|
206
|
+
/**
|
|
207
|
+
* O catálogo é config do host: muda com deploy, não com uso. `staleTime: Infinity` evita refetch a
|
|
208
|
+
* cada foco de janela por um dado que não muda durante a sessão.
|
|
209
|
+
*/
|
|
210
|
+
declare function useTemplateVariables(): _tanstack_react_query.UseQueryResult<NoInfer<Readonly<Record<string, readonly _adatechnology_notification_contracts.TemplateVariableDefinition[]>>>, Error>;
|
|
211
|
+
/**
|
|
212
|
+
* Desativa o template. Invalida a lista pelo mesmo motivo do upsert: o servidor derruba TODAS as
|
|
213
|
+
* versões ativas da identidade, e um cache otimista que removesse só a linha clicada mostraria a
|
|
214
|
+
* versão anterior de volta na tela.
|
|
215
|
+
*/
|
|
216
|
+
declare function useDeactivateTemplate(): _tanstack_react_query.UseMutationResult<void, Error, string, unknown>;
|
|
156
217
|
|
|
157
218
|
/**
|
|
158
219
|
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
@@ -173,6 +234,8 @@ declare const NOTIFICATION_QUERY_KEYS: {
|
|
|
173
234
|
readonly unreadCount: () => readonly ["notifications", "unread-count"];
|
|
174
235
|
readonly preferences: () => readonly ["notifications", "preferences"];
|
|
175
236
|
readonly templates: () => readonly ["notifications", "templates"];
|
|
237
|
+
readonly templateVariables: () => readonly ["notifications", "template-variables"];
|
|
238
|
+
readonly categoryPolicies: () => readonly ["notifications", "category-policies"];
|
|
176
239
|
};
|
|
177
240
|
|
|
178
241
|
/**
|
|
@@ -205,6 +268,10 @@ declare function formatNotificationTimestamp(isoTimestamp: string, locale: strin
|
|
|
205
268
|
* derivar título vazio, em vez de cair no fallback que usa o corpo.
|
|
206
269
|
* 4. **Preview pelo `renderTemplate` do contracts**, o mesmo do envio. Reimplementar a interpolação
|
|
207
270
|
* dá um preview que confere hoje e mente quando o renderer mudar.
|
|
271
|
+
*
|
|
272
|
+
* A criação de template novo trouxe uma quinta: **a identidade é imutável depois de criada**.
|
|
273
|
+
* `key`+`channel`+`locale` é o que o `sendNotification` procura; deixar editar num template
|
|
274
|
+
* existente não seria edição, seria criar outro e deixar o antigo órfão no ar.
|
|
208
275
|
*/
|
|
209
276
|
|
|
210
277
|
type TemplateDraft = {
|
|
@@ -215,27 +282,52 @@ type TemplateDraft = {
|
|
|
215
282
|
readonly body: string;
|
|
216
283
|
readonly whatsappTemplateName: string;
|
|
217
284
|
};
|
|
285
|
+
type TemplateDraftField = 'subject' | 'body';
|
|
286
|
+
type TemplatePreviewFrame = PreviewViewportSpec & {
|
|
287
|
+
readonly rendered: RenderedTemplatePreview;
|
|
288
|
+
};
|
|
218
289
|
type UseTemplateEditorParams = {
|
|
219
290
|
/**
|
|
220
|
-
* Valores de exemplo do preview.
|
|
221
|
-
*
|
|
291
|
+
* Valores de exemplo do preview. Hoje o padrão vem do catálogo de variáveis do servidor; isto
|
|
292
|
+
* continua existindo para o produto sobrescrever um exemplo pontual sem mexer no catálogo.
|
|
222
293
|
*/
|
|
223
294
|
readonly previewPayload?: Readonly<Record<string, unknown>>;
|
|
295
|
+
/** Canal e locale de um template novo, antes de o operador escolher. */
|
|
296
|
+
readonly defaultChannel?: string;
|
|
297
|
+
readonly defaultLocale?: string;
|
|
224
298
|
};
|
|
225
299
|
type UseTemplateEditorResult = {
|
|
226
300
|
readonly templates: readonly NotificationTemplate[];
|
|
227
301
|
readonly isLoading: boolean;
|
|
228
302
|
readonly isSaving: boolean;
|
|
303
|
+
readonly isDeactivating: boolean;
|
|
229
304
|
readonly error: string | undefined;
|
|
230
305
|
readonly selected: NotificationTemplate | undefined;
|
|
231
306
|
readonly draft: TemplateDraft | undefined;
|
|
232
|
-
|
|
307
|
+
/** `true` enquanto o rascunho é um template que ainda não existe no servidor. */
|
|
308
|
+
readonly isNew: boolean;
|
|
309
|
+
/** Identidade travada — `false` só durante a criação. */
|
|
310
|
+
readonly isIdentityLocked: boolean;
|
|
311
|
+
/** Os dois quadros do preview, na ordem em que a tela desenha. */
|
|
312
|
+
readonly previews: readonly TemplatePreviewFrame[];
|
|
313
|
+
/** As variáveis que esta `key` declara. Vazio quando o catálogo não conhece a chave. */
|
|
314
|
+
readonly variables: readonly TemplateVariableDefinition[];
|
|
315
|
+
readonly variableDiff: TemplateVariableDiff;
|
|
233
316
|
readonly isDirty: boolean;
|
|
317
|
+
readonly canSave: boolean;
|
|
234
318
|
select: (template: NotificationTemplate) => void;
|
|
319
|
+
startNew: () => void;
|
|
235
320
|
update: (patch: Partial<TemplateDraft>) => void;
|
|
321
|
+
/** Insere `{{nome}}` na posição do cursor. O operador nunca digita o nome à mão. */
|
|
322
|
+
insertVariable: (params: {
|
|
323
|
+
name: string;
|
|
324
|
+
field: TemplateDraftField;
|
|
325
|
+
cursorIndex: number;
|
|
326
|
+
}) => void;
|
|
236
327
|
save: () => void;
|
|
328
|
+
deactivate: (id: string) => void;
|
|
237
329
|
clear: () => void;
|
|
238
330
|
};
|
|
239
331
|
declare function useTemplateEditor(params?: UseTemplateEditorParams): UseTemplateEditorResult;
|
|
240
332
|
|
|
241
|
-
export { DEFAULT_LOCALE, NOTIFICATION_QUERY_KEYS, type NotificationContextValue, type NotificationLocale, type NotificationMessages, NotificationProvider, type NotificationProviderProps, type NotificationTheme, type TemplateDraft, type UseNotificationStreamOptions, type UseNotificationsOptions, type UseTemplateEditorParams, type UseTemplateEditorResult, flattenNotificationPages, formatNotificationTime, formatNotificationTimestamp, resolveMessages, useDeleteNotification, useMarkAllAsRead, useMarkAsRead, useNotificationContext, useNotificationStream, useNotifications, usePreferences, useTemplateEditor, useTemplates, useUnreadCount, useUpdatePreferences, useUpsertTemplate };
|
|
333
|
+
export { DEFAULT_LOCALE, NOTIFICATION_QUERY_KEYS, type NotificationContextValue, type NotificationLocale, type NotificationMessages, NotificationProvider, type NotificationProviderProps, type NotificationTheme, type TemplateDraft, type TemplateDraftField, type TemplatePreviewFrame, type UseCategoryPoliciesResult, type UseNotificationStreamOptions, type UseNotificationsOptions, type UseTemplateEditorParams, type UseTemplateEditorResult, flattenNotificationPages, formatNotificationTime, formatNotificationTimestamp, resolveMessages, useCategoryPolicies, useDeactivateTemplate, useDeleteNotification, useMarkAllAsRead, useMarkAsRead, useNotificationContext, useNotificationStream, useNotifications, usePreferences, useTemplateEditor, useTemplateVariables, useTemplates, useUnreadCount, useUpdatePreferences, useUpsertTemplate };
|
package/dist/headless.js
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
formatNotificationTime,
|
|
7
7
|
formatNotificationTimestamp,
|
|
8
8
|
resolveMessages,
|
|
9
|
+
useCategoryPolicies,
|
|
10
|
+
useDeactivateTemplate,
|
|
9
11
|
useDeleteNotification,
|
|
10
12
|
useMarkAllAsRead,
|
|
11
13
|
useMarkAsRead,
|
|
@@ -14,11 +16,12 @@ import {
|
|
|
14
16
|
useNotifications,
|
|
15
17
|
usePreferences,
|
|
16
18
|
useTemplateEditor,
|
|
19
|
+
useTemplateVariables,
|
|
17
20
|
useTemplates,
|
|
18
21
|
useUnreadCount,
|
|
19
22
|
useUpdatePreferences,
|
|
20
23
|
useUpsertTemplate
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-QBQ62VZ3.js";
|
|
22
25
|
export {
|
|
23
26
|
DEFAULT_LOCALE,
|
|
24
27
|
NOTIFICATION_QUERY_KEYS,
|
|
@@ -27,6 +30,8 @@ export {
|
|
|
27
30
|
formatNotificationTime,
|
|
28
31
|
formatNotificationTimestamp,
|
|
29
32
|
resolveMessages,
|
|
33
|
+
useCategoryPolicies,
|
|
34
|
+
useDeactivateTemplate,
|
|
30
35
|
useDeleteNotification,
|
|
31
36
|
useMarkAllAsRead,
|
|
32
37
|
useMarkAsRead,
|
|
@@ -35,6 +40,7 @@ export {
|
|
|
35
40
|
useNotifications,
|
|
36
41
|
usePreferences,
|
|
37
42
|
useTemplateEditor,
|
|
43
|
+
useTemplateVariables,
|
|
38
44
|
useTemplates,
|
|
39
45
|
useUnreadCount,
|
|
40
46
|
useUpdatePreferences,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DEFAULT_LOCALE, NOTIFICATION_QUERY_KEYS, NotificationContextValue, NotificationLocale, NotificationMessages, NotificationProvider, NotificationProviderProps, NotificationTheme, TemplateDraft, UseNotificationStreamOptions, UseNotificationsOptions, UseTemplateEditorParams, UseTemplateEditorResult, flattenNotificationPages, formatNotificationTime, formatNotificationTimestamp, resolveMessages, useDeleteNotification, useMarkAllAsRead, useMarkAsRead, useNotificationContext, useNotificationStream, useNotifications, usePreferences, useTemplateEditor, useTemplates, useUnreadCount, useUpdatePreferences, useUpsertTemplate } from './headless.js';
|
|
1
|
+
export { DEFAULT_LOCALE, NOTIFICATION_QUERY_KEYS, NotificationContextValue, NotificationLocale, NotificationMessages, NotificationProvider, NotificationProviderProps, NotificationTheme, TemplateDraft, TemplateDraftField, TemplatePreviewFrame, UseCategoryPoliciesResult, UseNotificationStreamOptions, UseNotificationsOptions, UseTemplateEditorParams, UseTemplateEditorResult, flattenNotificationPages, formatNotificationTime, formatNotificationTimestamp, resolveMessages, useCategoryPolicies, useDeactivateTemplate, useDeleteNotification, useMarkAllAsRead, useMarkAsRead, useNotificationContext, useNotificationStream, useNotifications, usePreferences, useTemplateEditor, useTemplateVariables, useTemplates, useUnreadCount, useUpdatePreferences, useUpsertTemplate } from './headless.js';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
import { NotificationSummary, NotificationTemplate } from '@adatechnology/notification-contracts';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
formatNotificationTime,
|
|
7
7
|
formatNotificationTimestamp,
|
|
8
8
|
resolveMessages,
|
|
9
|
+
useCategoryPolicies,
|
|
10
|
+
useDeactivateTemplate,
|
|
9
11
|
useDeleteNotification,
|
|
10
12
|
useMarkAllAsRead,
|
|
11
13
|
useMarkAsRead,
|
|
@@ -14,11 +16,12 @@ import {
|
|
|
14
16
|
useNotifications,
|
|
15
17
|
usePreferences,
|
|
16
18
|
useTemplateEditor,
|
|
19
|
+
useTemplateVariables,
|
|
17
20
|
useTemplates,
|
|
18
21
|
useUnreadCount,
|
|
19
22
|
useUpdatePreferences,
|
|
20
23
|
useUpsertTemplate
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-QBQ62VZ3.js";
|
|
22
25
|
|
|
23
26
|
// src/components/NotificationBell.tsx
|
|
24
27
|
import { Bell } from "lucide-react";
|
|
@@ -295,6 +298,7 @@ function NotificationsWorkspace({
|
|
|
295
298
|
}
|
|
296
299
|
|
|
297
300
|
// src/components/NotificationSettingsWorkspace.tsx
|
|
301
|
+
import { useState as useState2 } from "react";
|
|
298
302
|
import { Fragment, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
299
303
|
function NotificationSettingsWorkspace({
|
|
300
304
|
labels: labelsOverride,
|
|
@@ -311,7 +315,19 @@ function NotificationSettingsWorkspace({
|
|
|
311
315
|
const label = (key) => labelsOverride?.[key] ?? messages[key] ?? key;
|
|
312
316
|
const preferencesQuery = usePreferences();
|
|
313
317
|
const updatePreferences = useUpdatePreferences();
|
|
314
|
-
const editor = useTemplateEditor(
|
|
318
|
+
const editor = useTemplateEditor({
|
|
319
|
+
...previewPayload ? { previewPayload } : {},
|
|
320
|
+
...channels[0] ? { defaultChannel: channels[0].id } : {}
|
|
321
|
+
});
|
|
322
|
+
const [cursor, setCursor] = useState2({
|
|
323
|
+
field: "body",
|
|
324
|
+
cursorIndex: 0
|
|
325
|
+
});
|
|
326
|
+
function rememberCursor(field, cursorIndex) {
|
|
327
|
+
setCursor({ field, cursorIndex: cursorIndex ?? 0 });
|
|
328
|
+
}
|
|
329
|
+
const policies = useCategoryPolicies();
|
|
330
|
+
const [tab, setTab] = useState2("messages");
|
|
315
331
|
function isEnabled(category, channel) {
|
|
316
332
|
const row = (preferencesQuery.data ?? []).find(
|
|
317
333
|
(preference) => preference.category === category && preference.channel === channel
|
|
@@ -336,7 +352,42 @@ function NotificationSettingsWorkspace({
|
|
|
336
352
|
] }),
|
|
337
353
|
renderHeaderActions?.()
|
|
338
354
|
] }),
|
|
339
|
-
/* @__PURE__ */
|
|
355
|
+
/* @__PURE__ */ jsx6("div", { className: "adn-settings__tabs", role: "tablist", children: ["messages", "routing"].map((id) => /* @__PURE__ */ jsx6(
|
|
356
|
+
"button",
|
|
357
|
+
{
|
|
358
|
+
type: "button",
|
|
359
|
+
role: "tab",
|
|
360
|
+
"aria-selected": tab === id,
|
|
361
|
+
className: tab === id ? "adn-settings__tab adn-settings__tab--active" : "adn-settings__tab",
|
|
362
|
+
onClick: () => setTab(id),
|
|
363
|
+
children: label(`settings.tab.${id}`)
|
|
364
|
+
},
|
|
365
|
+
id
|
|
366
|
+
)) }),
|
|
367
|
+
tab === "routing" && /* @__PURE__ */ jsxs6("section", { className: "adn-settings__policies", children: [
|
|
368
|
+
/* @__PURE__ */ jsx6("h2", { className: "adn-settings__section-title", children: label("settings.policiesTitle") }),
|
|
369
|
+
/* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.policiesHint") }),
|
|
370
|
+
categories.map((category) => /* @__PURE__ */ jsxs6("div", { className: "adn-settings__category", children: [
|
|
371
|
+
/* @__PURE__ */ jsx6("p", { className: "adn-settings__category-title", children: category.label }),
|
|
372
|
+
/* @__PURE__ */ jsx6("div", { className: "adn-settings__category-channels", children: channels.map((channel) => /* @__PURE__ */ jsxs6("label", { className: "adn-settings__toggle", children: [
|
|
373
|
+
/* @__PURE__ */ jsx6(
|
|
374
|
+
"input",
|
|
375
|
+
{
|
|
376
|
+
type: "checkbox",
|
|
377
|
+
checked: policies.isAllowed({ category: category.id, channel: channel.id }),
|
|
378
|
+
onChange: () => policies.toggle({ category: category.id, channel: channel.id })
|
|
379
|
+
}
|
|
380
|
+
),
|
|
381
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__channel-label", children: channel.label })
|
|
382
|
+
] }, channel.id)) })
|
|
383
|
+
] }, category.id)),
|
|
384
|
+
policies.error && /* @__PURE__ */ jsx6("p", { className: "adn-settings__error", children: policies.error }),
|
|
385
|
+
/* @__PURE__ */ jsxs6("div", { className: "adn-settings__actions", children: [
|
|
386
|
+
/* @__PURE__ */ jsx6("button", { type: "button", onClick: policies.save, disabled: !policies.isDirty || policies.isSaving, children: policies.isSaving ? label("settings.saving") : label("settings.savePolicies") }),
|
|
387
|
+
policies.isDirty && /* @__PURE__ */ jsx6("button", { type: "button", onClick: policies.reset, children: label("settings.discard") })
|
|
388
|
+
] })
|
|
389
|
+
] }),
|
|
390
|
+
tab === "routing" && /* @__PURE__ */ jsxs6("section", { className: "adn-settings__channels", children: [
|
|
340
391
|
/* @__PURE__ */ jsx6("h2", { className: "adn-settings__section-title", children: label("settings.channelsTitle") }),
|
|
341
392
|
/* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.channelsHint") }),
|
|
342
393
|
categories.map((category) => /* @__PURE__ */ jsxs6("div", { className: "adn-settings__category", children: [
|
|
@@ -359,33 +410,49 @@ function NotificationSettingsWorkspace({
|
|
|
359
410
|
] }, channel.id)) })
|
|
360
411
|
] }, category.id))
|
|
361
412
|
] }),
|
|
362
|
-
/* @__PURE__ */ jsxs6("div", { className: "adn-settings__templates", children: [
|
|
413
|
+
tab === "messages" && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__templates", children: [
|
|
363
414
|
/* @__PURE__ */ jsxs6("section", { className: "adn-settings__template-list", children: [
|
|
364
|
-
/* @__PURE__ */ jsxs6("header", { children: [
|
|
365
|
-
/* @__PURE__ */
|
|
366
|
-
|
|
415
|
+
/* @__PURE__ */ jsxs6("header", { className: "adn-settings__list-header", children: [
|
|
416
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
417
|
+
/* @__PURE__ */ jsx6("h2", { className: "adn-settings__section-title", children: label("settings.templatesTitle") }),
|
|
418
|
+
/* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.templatesHint") })
|
|
419
|
+
] }),
|
|
420
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "adn-settings__new", onClick: editor.startNew, children: label("settings.newTemplate") })
|
|
367
421
|
] }),
|
|
368
422
|
editor.isLoading && /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("list.loading") }),
|
|
369
423
|
!editor.isLoading && editor.templates.length === 0 && /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.templatesEmpty") }),
|
|
370
|
-
/* @__PURE__ */ jsx6("ul", { children: editor.templates.map((template) => /* @__PURE__ */
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
/* @__PURE__ */
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
424
|
+
/* @__PURE__ */ jsx6("ul", { children: editor.templates.map((template) => /* @__PURE__ */ jsxs6("li", { className: "adn-settings__row", children: [
|
|
425
|
+
/* @__PURE__ */ jsxs6(
|
|
426
|
+
"button",
|
|
427
|
+
{
|
|
428
|
+
type: "button",
|
|
429
|
+
onClick: () => editor.select(template),
|
|
430
|
+
className: editor.selected?.id === template.id ? "adn-settings__row--active" : void 0,
|
|
431
|
+
children: [
|
|
432
|
+
/* @__PURE__ */ jsxs6("span", { className: "adn-settings__row-main", children: [
|
|
433
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__row-title", children: templateLabelOf?.(template) ?? template.key }),
|
|
434
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__row-body", children: template.body })
|
|
435
|
+
] }),
|
|
436
|
+
/* @__PURE__ */ jsx6("span", { className: `adn-settings__badge adn-settings__badge--${template.channel}`, children: label(`channel.${template.channel}`) }),
|
|
437
|
+
/* @__PURE__ */ jsxs6("span", { className: "adn-settings__version", children: [
|
|
438
|
+
label("settings.version"),
|
|
439
|
+
template.version
|
|
440
|
+
] })
|
|
441
|
+
]
|
|
442
|
+
}
|
|
443
|
+
),
|
|
444
|
+
/* @__PURE__ */ jsx6(
|
|
445
|
+
"button",
|
|
446
|
+
{
|
|
447
|
+
type: "button",
|
|
448
|
+
className: "adn-settings__remove",
|
|
449
|
+
"aria-label": `${label("settings.remove")} ${template.key}`,
|
|
450
|
+
disabled: editor.isDeactivating,
|
|
451
|
+
onClick: () => editor.deactivate(template.id),
|
|
452
|
+
children: label("settings.remove")
|
|
453
|
+
}
|
|
454
|
+
)
|
|
455
|
+
] }, template.id)) })
|
|
389
456
|
] }),
|
|
390
457
|
/* @__PURE__ */ jsxs6("section", { className: "adn-settings__editor", children: [
|
|
391
458
|
!editor.draft && /* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.pickTemplate") }),
|
|
@@ -404,6 +471,63 @@ function NotificationSettingsWorkspace({
|
|
|
404
471
|
] }),
|
|
405
472
|
/* @__PURE__ */ jsx6("button", { type: "button", onClick: editor.clear, children: label("settings.close") })
|
|
406
473
|
] }),
|
|
474
|
+
!editor.isIdentityLocked && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__identity", children: [
|
|
475
|
+
/* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
|
|
476
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.key") }),
|
|
477
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: label("settings.keyHint") }),
|
|
478
|
+
/* @__PURE__ */ jsx6("input", { value: editor.draft.key, onChange: (event) => editor.update({ key: event.target.value }) })
|
|
479
|
+
] }),
|
|
480
|
+
/* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
|
|
481
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.channel") }),
|
|
482
|
+
/* @__PURE__ */ jsx6(
|
|
483
|
+
"select",
|
|
484
|
+
{
|
|
485
|
+
value: editor.draft.channel,
|
|
486
|
+
onChange: (event) => editor.update({ channel: event.target.value }),
|
|
487
|
+
children: channels.map((channel) => /* @__PURE__ */ jsx6("option", { value: channel.id, children: channel.label }, channel.id))
|
|
488
|
+
}
|
|
489
|
+
)
|
|
490
|
+
] }),
|
|
491
|
+
/* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
|
|
492
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.locale") }),
|
|
493
|
+
/* @__PURE__ */ jsx6(
|
|
494
|
+
"input",
|
|
495
|
+
{
|
|
496
|
+
value: editor.draft.locale,
|
|
497
|
+
onChange: (event) => editor.update({ locale: event.target.value })
|
|
498
|
+
}
|
|
499
|
+
)
|
|
500
|
+
] })
|
|
501
|
+
] }),
|
|
502
|
+
editor.variables.length > 0 && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__variables", children: [
|
|
503
|
+
/* @__PURE__ */ jsx6("p", { className: "adn-settings__field-label", children: label("settings.variablesTitle") }),
|
|
504
|
+
/* @__PURE__ */ jsx6("p", { className: "adn-settings__hint", children: label("settings.variablesHint") }),
|
|
505
|
+
/* @__PURE__ */ jsx6("ul", { children: editor.variables.map((variable) => {
|
|
506
|
+
const used = editor.variableDiff.used.includes(variable.name);
|
|
507
|
+
const missing = editor.variableDiff.missingRequired.includes(variable.name);
|
|
508
|
+
return /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsxs6(
|
|
509
|
+
"button",
|
|
510
|
+
{
|
|
511
|
+
type: "button",
|
|
512
|
+
className: [
|
|
513
|
+
"adn-settings__variable",
|
|
514
|
+
used ? "adn-settings__variable--used" : "",
|
|
515
|
+
missing ? "adn-settings__variable--missing" : ""
|
|
516
|
+
].filter(Boolean).join(" "),
|
|
517
|
+
onClick: () => editor.insertVariable({ ...cursor, name: variable.name }),
|
|
518
|
+
children: [
|
|
519
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__variable-name", children: `{{${variable.name}}}` }),
|
|
520
|
+
/* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: variable.example })
|
|
521
|
+
]
|
|
522
|
+
}
|
|
523
|
+
) }, variable.name);
|
|
524
|
+
}) })
|
|
525
|
+
] }),
|
|
526
|
+
editor.variableDiff.unknown.length > 0 && /* @__PURE__ */ jsxs6("p", { className: "adn-settings__error", children: [
|
|
527
|
+
label("settings.unknownVariables"),
|
|
528
|
+
" ",
|
|
529
|
+
editor.variableDiff.unknown.join(", ")
|
|
530
|
+
] }),
|
|
407
531
|
/* @__PURE__ */ jsxs6("label", { className: "adn-settings__field", children: [
|
|
408
532
|
/* @__PURE__ */ jsx6("span", { className: "adn-settings__field-label", children: label("settings.subject") }),
|
|
409
533
|
/* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: label("settings.subjectHint") }),
|
|
@@ -411,7 +535,8 @@ function NotificationSettingsWorkspace({
|
|
|
411
535
|
"input",
|
|
412
536
|
{
|
|
413
537
|
value: editor.draft.subject,
|
|
414
|
-
onChange: (event) => editor.update({ subject: event.target.value })
|
|
538
|
+
onChange: (event) => editor.update({ subject: event.target.value }),
|
|
539
|
+
onSelect: (event) => rememberCursor("subject", event.currentTarget.selectionStart)
|
|
415
540
|
}
|
|
416
541
|
)
|
|
417
542
|
] }),
|
|
@@ -422,7 +547,8 @@ function NotificationSettingsWorkspace({
|
|
|
422
547
|
{
|
|
423
548
|
rows: 4,
|
|
424
549
|
value: editor.draft.body,
|
|
425
|
-
onChange: (event) => editor.update({ body: event.target.value })
|
|
550
|
+
onChange: (event) => editor.update({ body: event.target.value }),
|
|
551
|
+
onSelect: (event) => rememberCursor("body", event.currentTarget.selectionStart)
|
|
426
552
|
}
|
|
427
553
|
)
|
|
428
554
|
] }),
|
|
@@ -431,14 +557,31 @@ function NotificationSettingsWorkspace({
|
|
|
431
557
|
value: editor.draft.whatsappTemplateName,
|
|
432
558
|
onChange: (value) => editor.update({ whatsappTemplateName: value })
|
|
433
559
|
}),
|
|
434
|
-
editor.
|
|
560
|
+
editor.previews.length > 0 && /* @__PURE__ */ jsxs6("div", { className: "adn-settings__previews", children: [
|
|
435
561
|
/* @__PURE__ */ jsx6("p", { className: "adn-settings__preview-title", children: label("settings.previewTitle") }),
|
|
436
|
-
/* @__PURE__ */ jsx6("
|
|
437
|
-
|
|
562
|
+
/* @__PURE__ */ jsx6("div", { className: "adn-settings__preview-frames", children: editor.previews.map((frame) => /* @__PURE__ */ jsxs6("figure", { className: "adn-settings__preview", children: [
|
|
563
|
+
/* @__PURE__ */ jsxs6("figcaption", { className: "adn-settings__hint", children: [
|
|
564
|
+
label(`settings.viewport.${frame.viewport}`),
|
|
565
|
+
" \xB7 ",
|
|
566
|
+
frame.width,
|
|
567
|
+
"px"
|
|
568
|
+
] }),
|
|
569
|
+
/* @__PURE__ */ jsxs6("div", { className: "adn-settings__preview-frame", style: { width: frame.width }, children: [
|
|
570
|
+
/* @__PURE__ */ jsx6("p", { className: "adn-settings__preview-subject", children: frame.rendered.title }),
|
|
571
|
+
/* @__PURE__ */ jsx6("p", { className: "adn-settings__preview-body", children: frame.rendered.body })
|
|
572
|
+
] }),
|
|
573
|
+
frame.rendered.constraints.filter((constraint) => constraint.exceeded).map((constraint) => /* @__PURE__ */ jsxs6("p", { className: "adn-settings__preview-warning", children: [
|
|
574
|
+
label(`settings.constraint.${constraint.field}`),
|
|
575
|
+
" ",
|
|
576
|
+
constraint.actual,
|
|
577
|
+
"/",
|
|
578
|
+
constraint.limit
|
|
579
|
+
] }, constraint.field))
|
|
580
|
+
] }, frame.viewport)) })
|
|
438
581
|
] }),
|
|
439
582
|
editor.error && /* @__PURE__ */ jsx6("p", { className: "adn-settings__error", children: editor.error }),
|
|
440
583
|
/* @__PURE__ */ jsxs6("div", { className: "adn-settings__actions", children: [
|
|
441
|
-
/* @__PURE__ */ jsx6("button", { type: "button", onClick: editor.save, disabled: !editor.isDirty || editor.isSaving, children: editor.isSaving ? label("settings.saving") : label("settings.save") }),
|
|
584
|
+
/* @__PURE__ */ jsx6("button", { type: "button", onClick: editor.save, disabled: !editor.isDirty || !editor.canSave || editor.isSaving, children: editor.isSaving ? label("settings.saving") : label("settings.save") }),
|
|
442
585
|
!editor.isDirty && /* @__PURE__ */ jsx6("span", { className: "adn-settings__hint", children: label("settings.unchanged") })
|
|
443
586
|
] })
|
|
444
587
|
] })
|
|
@@ -460,6 +603,8 @@ export {
|
|
|
460
603
|
formatNotificationTime,
|
|
461
604
|
formatNotificationTimestamp,
|
|
462
605
|
resolveMessages,
|
|
606
|
+
useCategoryPolicies,
|
|
607
|
+
useDeactivateTemplate,
|
|
463
608
|
useDeleteNotification,
|
|
464
609
|
useMarkAllAsRead,
|
|
465
610
|
useMarkAsRead,
|
|
@@ -468,6 +613,7 @@ export {
|
|
|
468
613
|
useNotifications,
|
|
469
614
|
usePreferences,
|
|
470
615
|
useTemplateEditor,
|
|
616
|
+
useTemplateVariables,
|
|
471
617
|
useTemplates,
|
|
472
618
|
useUnreadCount,
|
|
473
619
|
useUpdatePreferences,
|