@adatechnology/notification-ui 0.1.0-rc.5 → 0.1.0-rc.7
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-QBQ62VZ3.js → chunk-7XDQ76IV.js} +263 -44
- package/dist/chunk-7XDQ76IV.js.map +1 -0
- package/dist/headless--T3Ry0h4.d.ts +468 -0
- package/dist/headless.d.ts +5 -333
- package/dist/headless.js +1 -1
- package/dist/index.d.ts +186 -3
- package/dist/index.js +1040 -190
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1701 -7
- package/dist/styles.css.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-QBQ62VZ3.js.map +0 -1
package/dist/headless.d.ts
CHANGED
|
@@ -1,333 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import * as _adatechnology_notification_contracts from '@adatechnology/notification-contracts';
|
|
7
|
-
import { NotificationSummary, NotificationPreference, PreviewViewportSpec, RenderedTemplatePreview, NotificationTemplate, TemplateVariableDefinition, TemplateVariableDiff } from '@adatechnology/notification-contracts';
|
|
8
|
-
|
|
9
|
-
var ptBR = {
|
|
10
|
-
"bell.label": "Notificações",
|
|
11
|
-
"bell.unreadSuffix": "não lidas",
|
|
12
|
-
"list.title": "Caixa de entrada",
|
|
13
|
-
"list.unread": "não lidas",
|
|
14
|
-
"list.empty": "Nenhuma notificação por aqui.",
|
|
15
|
-
"list.loading": "Carregando…",
|
|
16
|
-
"list.error": "Não foi possível carregar suas notificações.",
|
|
17
|
-
"list.retry": "Tentar de novo",
|
|
18
|
-
"list.loadMore": "Carregar mais",
|
|
19
|
-
"list.markAllAsRead": "Marcar todas como lidas",
|
|
20
|
-
"item.markAsRead": "Marcar como lida",
|
|
21
|
-
"item.delete": "Excluir",
|
|
22
|
-
"item.unread": "Não lida",
|
|
23
|
-
"preferences.title": "Preferências de notificação",
|
|
24
|
-
"preferences.description": "Escolha por onde você quer ser avisado em cada assunto.",
|
|
25
|
-
"preferences.save": "Salvar preferências",
|
|
26
|
-
"preferences.saved": "Preferências salvas.",
|
|
27
|
-
"preferences.error": "Não foi possível salvar. Tente de novo.",
|
|
28
|
-
"preferences.empty": "Nenhuma preferência configurada ainda.",
|
|
29
|
-
"preferences.quietHours": "Silêncio entre",
|
|
30
|
-
"preferences.quietHoursTo": "e",
|
|
31
|
-
"channel.inbox": "No app",
|
|
32
|
-
"channel.push": "Push",
|
|
33
|
-
"channel.email": "E-mail",
|
|
34
|
-
"channel.whatsapp": "WhatsApp",
|
|
35
|
-
"channel.sms": "SMS",
|
|
36
|
-
"workspace.title": "Notificações",
|
|
37
|
-
"workspace.description": "O que foi avisado, e por quais canais.",
|
|
38
|
-
"workspace.settingsLink": "Configurações",
|
|
39
|
-
"settings.title": "Configurações de notificação",
|
|
40
|
-
"settings.description": "Por onde avisar, e o texto exato que chega.",
|
|
41
|
-
"settings.channelsTitle": "Canais",
|
|
42
|
-
"settings.channelsHint": "Desligar um canal não apaga o histórico — o aviso deixa de sair por ali daqui em diante.",
|
|
43
|
-
"settings.templatesTitle": "Mensagens",
|
|
44
|
-
"settings.templatesHint": "Uma versão nova é criada a cada gravação; a anterior fica no histórico.",
|
|
45
|
-
"settings.templatesEmpty": "Nenhuma mensagem cadastrada.",
|
|
46
|
-
"settings.pickTemplate": "Escolha uma mensagem para editar.",
|
|
47
|
-
"settings.subject": "Título",
|
|
48
|
-
"settings.subjectHint": "O que aparece na lista. Vazio, o título é derivado da primeira linha do texto.",
|
|
49
|
-
"settings.body": "Texto",
|
|
50
|
-
"settings.previewTitle": "Como o destinatário vê",
|
|
51
|
-
"settings.save": "Salvar nova versão",
|
|
52
|
-
"settings.saving": "Salvando…",
|
|
53
|
-
"settings.unchanged": "Nada mudou ainda.",
|
|
54
|
-
"settings.close": "Fechar",
|
|
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"
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
79
|
-
*
|
|
80
|
-
* Nenhum texto visível vive em tag ou prop (`web.md` §6). O host sobrescreve chaves pontuais via
|
|
81
|
-
* `messageOverrides` sem precisar fornecer um locale inteiro.
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
type NotificationMessages = typeof ptBR;
|
|
85
|
-
type NotificationLocale = 'pt-BR' | 'en';
|
|
86
|
-
declare const DEFAULT_LOCALE: NotificationLocale;
|
|
87
|
-
declare function resolveMessages(locale: NotificationLocale): NotificationMessages;
|
|
88
|
-
|
|
89
|
-
type NotificationTheme = {
|
|
90
|
-
/** Classe aplicada na raiz de cada componente — é por onde o host injeta os tokens dele. */
|
|
91
|
-
readonly rootClassName?: string;
|
|
92
|
-
readonly components?: Partial<Record<string, string>>;
|
|
93
|
-
};
|
|
94
|
-
type NotificationContextValue = {
|
|
95
|
-
readonly client: NotificationClient;
|
|
96
|
-
/**
|
|
97
|
-
* O idioma resolvido, e não só os textos dele: data e número não vivem no arquivo de locale —
|
|
98
|
-
* quem os formata é `Intl`, e `Intl` precisa da tag do idioma. Sem isto o item da lista teria de
|
|
99
|
-
* chutar um locale fixo, e a inbox mostraria "5 minutes ago" numa tela em português.
|
|
100
|
-
*/
|
|
101
|
-
readonly locale: NotificationLocale;
|
|
102
|
-
readonly messages: NotificationMessages;
|
|
103
|
-
readonly theme: NotificationTheme;
|
|
104
|
-
/** Polling de fallback quando o SSE não está disponível (segundos); `0` desliga. */
|
|
105
|
-
readonly pollIntervalSeconds: number;
|
|
106
|
-
};
|
|
107
|
-
type NotificationProviderProps = {
|
|
108
|
-
readonly client: NotificationClient;
|
|
109
|
-
readonly locale?: NotificationLocale;
|
|
110
|
-
/** Sobrescreve textos pontuais sem trocar o locale inteiro. */
|
|
111
|
-
readonly messageOverrides?: Partial<NotificationMessages>;
|
|
112
|
-
readonly theme?: NotificationTheme;
|
|
113
|
-
readonly pollIntervalSeconds?: number;
|
|
114
|
-
readonly children: ReactNode;
|
|
115
|
-
};
|
|
116
|
-
declare function NotificationProvider({ client, locale, messageOverrides, theme, pollIntervalSeconds, children, }: NotificationProviderProps): react.JSX.Element;
|
|
117
|
-
declare function useNotificationContext(): NotificationContextValue;
|
|
118
|
-
|
|
119
|
-
type UseNotificationsOptions = {
|
|
120
|
-
readonly category?: string;
|
|
121
|
-
readonly read?: boolean;
|
|
122
|
-
readonly perPage?: number;
|
|
123
|
-
};
|
|
124
|
-
declare function useNotifications(options?: UseNotificationsOptions): _tanstack_react_query.UseInfiniteQueryResult<_tanstack_react_query.InfiniteData<_adatechnology_notification_client.ListNotificationsPage, unknown>, Error>;
|
|
125
|
-
declare function useUnreadCount(): _tanstack_react_query.UseQueryResult<number, Error>;
|
|
126
|
-
declare function useMarkAsRead(): _tanstack_react_query.UseMutationResult<NotificationSummary, Error, string, {
|
|
127
|
-
previousCount: number | undefined;
|
|
128
|
-
id: string;
|
|
129
|
-
}>;
|
|
130
|
-
declare function useMarkAllAsRead(): _tanstack_react_query.UseMutationResult<number, Error, void, unknown>;
|
|
131
|
-
declare function useDeleteNotification(): _tanstack_react_query.UseMutationResult<void, Error, string, unknown>;
|
|
132
|
-
/** Achata as páginas do infinite query — a lista quase sempre quer o array direto. */
|
|
133
|
-
declare function flattenNotificationPages(pages: readonly {
|
|
134
|
-
data: readonly NotificationSummary[];
|
|
135
|
-
}[] | undefined): readonly NotificationSummary[];
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
139
|
-
*/
|
|
140
|
-
type UseNotificationStreamOptions = {
|
|
141
|
-
/** Desligado por omissão: abrir SSE é decisão do host, que sabe se o backend expõe a rota. */
|
|
142
|
-
readonly enabled?: boolean;
|
|
143
|
-
readonly onEvent?: (event: {
|
|
144
|
-
event: string;
|
|
145
|
-
data: unknown;
|
|
146
|
-
}) => void;
|
|
147
|
-
};
|
|
148
|
-
/**
|
|
149
|
-
* Liga o SSE do inbox ao cache do TanStack: cada evento invalida as chaves, e o badge e a lista
|
|
150
|
-
* atualizam juntos. `useEffect` aqui é o uso correto do hook — sincronizar com um sistema externo
|
|
151
|
-
* (`react.md`, "useEffect só para sincronizar com sistemas externos"), não transformar dado.
|
|
152
|
-
*/
|
|
153
|
-
declare function useNotificationStream(options?: UseNotificationStreamOptions): void;
|
|
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
|
-
|
|
186
|
-
declare function usePreferences(): _tanstack_react_query.UseQueryResult<NoInfer<readonly NotificationPreference[]>, Error>;
|
|
187
|
-
declare function useUpdatePreferences(): _tanstack_react_query.UseMutationResult<readonly NotificationPreference[], Error, readonly NotificationPreference[], unknown>;
|
|
188
|
-
declare function useTemplates(): _tanstack_react_query.UseQueryResult<NoInfer<readonly _adatechnology_notification_contracts.NotificationTemplate[]>, Error>;
|
|
189
|
-
/**
|
|
190
|
-
* Salva uma VERSÃO nova do template. É o que a tela de configuração usa para o lojista mudar a copy
|
|
191
|
-
* sem deploy.
|
|
192
|
-
*
|
|
193
|
-
* Invalida em vez de escrever no cache: o servidor decide o número da versão, então o objeto salvo
|
|
194
|
-
* traz um campo que o otimista não teria como prever — e mostrar "versão 3" quando o banco gravou 4
|
|
195
|
-
* confunde exatamente quem está tentando conferir o que salvou.
|
|
196
|
-
*/
|
|
197
|
-
declare function useUpsertTemplate(): _tanstack_react_query.UseMutationResult<_adatechnology_notification_contracts.NotificationTemplate, Error, {
|
|
198
|
-
locale: string;
|
|
199
|
-
channel: "inbox" | "push" | "email" | "whatsapp" | "sms";
|
|
200
|
-
key: string;
|
|
201
|
-
body: string;
|
|
202
|
-
active: boolean;
|
|
203
|
-
subject?: string | undefined;
|
|
204
|
-
whatsappTemplateName?: string | undefined;
|
|
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>;
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
220
|
-
*
|
|
221
|
-
* Chaves centralizadas: o sino e a lista leem o mesmo `unreadCount`, e uma invalidação precisa
|
|
222
|
-
* atingir os dois. Chave montada inline em cada hook é como badge e lista passam a mostrar
|
|
223
|
-
* números diferentes.
|
|
224
|
-
*/
|
|
225
|
-
declare const NOTIFICATION_QUERY_KEYS: {
|
|
226
|
-
readonly all: readonly ["notifications"];
|
|
227
|
-
readonly list: (filters: {
|
|
228
|
-
category?: string;
|
|
229
|
-
read?: boolean;
|
|
230
|
-
}) => readonly ["notifications", "list", {
|
|
231
|
-
category?: string;
|
|
232
|
-
read?: boolean;
|
|
233
|
-
}];
|
|
234
|
-
readonly unreadCount: () => readonly ["notifications", "unread-count"];
|
|
235
|
-
readonly preferences: () => readonly ["notifications", "preferences"];
|
|
236
|
-
readonly templates: () => readonly ["notifications", "templates"];
|
|
237
|
-
readonly templateVariables: () => readonly ["notifications", "template-variables"];
|
|
238
|
-
readonly categoryPolicies: () => readonly ["notifications", "category-policies"];
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
243
|
-
*
|
|
244
|
-
* Quando o aviso chegou, dito do jeito que se diz em voz alta.
|
|
245
|
-
*
|
|
246
|
-
* `Intl` faz o trabalho de idioma — o pacote não guarda "há", "ago" nem nome de mês em lugar nenhum,
|
|
247
|
-
* o que manteria `web.md` §6 de pé e ainda assim quebraria no primeiro locale novo. O que é decisão
|
|
248
|
-
* nossa são as faixas: segundo, minuto, hora, dia, e a virada para data absoluta.
|
|
249
|
-
*/
|
|
250
|
-
declare function formatNotificationTime(isoTimestamp: string, locale: string, now: Date): string;
|
|
251
|
-
/** O instante inteiro, para o `title` — é a hora que o texto relativo esconde. */
|
|
252
|
-
declare function formatNotificationTimestamp(isoTimestamp: string, locale: string): string;
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
256
|
-
*
|
|
257
|
-
* A lógica do editor de template, que estava reimplementada no host.
|
|
258
|
-
*
|
|
259
|
-
* Ela veio de `quickcart/modules/notifications/hooks/useNotificationSettings.hook.ts` — 207 linhas
|
|
260
|
-
* que o segundo produto reescreveria, com as mesmas quatro decisões sutis para redescobrir. Elas
|
|
261
|
-
* são o motivo de isto ser pacote e não exemplo:
|
|
262
|
-
*
|
|
263
|
-
* 1. **Versão ativa mais alta.** A rota devolve o histórico inteiro, correto para auditoria; na tela
|
|
264
|
-
* isso faz a mesma mensagem aparecer três vezes e ninguém sabe qual está no ar.
|
|
265
|
-
* 2. **Seleção pelo id, não pelo objeto.** Salvar cria versão nova no servidor; segurando o objeto,
|
|
266
|
-
* o editor mostra a versão que já não é a ativa e a gravação seguinte parte de um texto velho.
|
|
267
|
-
* 3. **Campo vazio é ausência.** Gravar `subject: ''` faz o renderer tratar como subject existente e
|
|
268
|
-
* derivar título vazio, em vez de cair no fallback que usa o corpo.
|
|
269
|
-
* 4. **Preview pelo `renderTemplate` do contracts**, o mesmo do envio. Reimplementar a interpolação
|
|
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.
|
|
275
|
-
*/
|
|
276
|
-
|
|
277
|
-
type TemplateDraft = {
|
|
278
|
-
readonly key: string;
|
|
279
|
-
readonly channel: string;
|
|
280
|
-
readonly locale: string;
|
|
281
|
-
readonly subject: string;
|
|
282
|
-
readonly body: string;
|
|
283
|
-
readonly whatsappTemplateName: string;
|
|
284
|
-
};
|
|
285
|
-
type TemplateDraftField = 'subject' | 'body';
|
|
286
|
-
type TemplatePreviewFrame = PreviewViewportSpec & {
|
|
287
|
-
readonly rendered: RenderedTemplatePreview;
|
|
288
|
-
};
|
|
289
|
-
type UseTemplateEditorParams = {
|
|
290
|
-
/**
|
|
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.
|
|
293
|
-
*/
|
|
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;
|
|
298
|
-
};
|
|
299
|
-
type UseTemplateEditorResult = {
|
|
300
|
-
readonly templates: readonly NotificationTemplate[];
|
|
301
|
-
readonly isLoading: boolean;
|
|
302
|
-
readonly isSaving: boolean;
|
|
303
|
-
readonly isDeactivating: boolean;
|
|
304
|
-
readonly error: string | undefined;
|
|
305
|
-
readonly selected: NotificationTemplate | undefined;
|
|
306
|
-
readonly draft: TemplateDraft | undefined;
|
|
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;
|
|
316
|
-
readonly isDirty: boolean;
|
|
317
|
-
readonly canSave: boolean;
|
|
318
|
-
select: (template: NotificationTemplate) => void;
|
|
319
|
-
startNew: () => void;
|
|
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;
|
|
327
|
-
save: () => void;
|
|
328
|
-
deactivate: (id: string) => void;
|
|
329
|
-
clear: () => void;
|
|
330
|
-
};
|
|
331
|
-
declare function useTemplateEditor(params?: UseTemplateEditorParams): UseTemplateEditorResult;
|
|
332
|
-
|
|
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 };
|
|
1
|
+
export { D as DEFAULT_LOCALE, N as NOTIFICATION_QUERY_KEYS, a as NotificationContextValue, b as NotificationLocale, c as NotificationMessages, d as NotificationProvider, e as NotificationProviderProps, f as NotificationTheme, k as TemplateDraft, l as TemplateDraftField, m as TemplatePreviewFrame, U as UseCategoryPoliciesResult, q as UseNotificationStreamOptions, r as UseNotificationsOptions, s as UseTemplateEditorParams, t as UseTemplateEditorResult, u as flattenNotificationPages, v as formatNotificationTime, w as formatNotificationTimestamp, x as resolveMessages, y as useCategoryPolicies, z as useDeactivateTemplate, A as useDeleteNotification, B as useMarkAllAsRead, C as useMarkAsRead, E as useNotificationContext, F as useNotificationStream, G as useNotifications, H as usePreferences, I as useTemplateEditor, J as useTemplateVariables, K as useTemplates, L as useUnreadCount, M as useUpdatePreferences, O as useUpsertTemplate } from './headless--T3Ry0h4.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
import '@adatechnology/notification-client';
|
|
4
|
+
import '@tanstack/react-query';
|
|
5
|
+
import '@adatechnology/notification-contracts';
|
package/dist/headless.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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';
|
|
1
|
+
export { D as DEFAULT_LOCALE, N as NOTIFICATION_QUERY_KEYS, a as NotificationContextValue, b as NotificationLocale, c as NotificationMessages, d as NotificationProvider, e as NotificationProviderProps, f as NotificationTheme, S as SORT_DIRECTIONS, g as SortDirection, T as TEMPLATE_COLUMNS, h as TEMPLATE_SORT_FIELDS, i as TEMPLATE_VIEWS, j as TemplateColumn, k as TemplateDraft, l as TemplateDraftField, m as TemplatePreviewFrame, n as TemplateSort, o as TemplateSortField, p as TemplateView, U as UseCategoryPoliciesResult, q as UseNotificationStreamOptions, r as UseNotificationsOptions, s as UseTemplateEditorParams, t as UseTemplateEditorResult, u as flattenNotificationPages, v as formatNotificationTime, w as formatNotificationTimestamp, x as resolveMessages, y as useCategoryPolicies, z as useDeactivateTemplate, A as useDeleteNotification, B as useMarkAllAsRead, C as useMarkAsRead, E as useNotificationContext, F as useNotificationStream, G as useNotifications, H as usePreferences, I as useTemplateEditor, J as useTemplateVariables, K as useTemplates, L as useUnreadCount, M as useUpdatePreferences, O as useUpsertTemplate } from './headless--T3Ry0h4.js';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
import { NotificationSummary, NotificationTemplate } from '@adatechnology/notification-contracts';
|
|
@@ -92,6 +92,15 @@ type NotificationCategoryOption = {
|
|
|
92
92
|
readonly label: string;
|
|
93
93
|
readonly hint?: string;
|
|
94
94
|
};
|
|
95
|
+
/** O laudo do validador, na forma mínima que a tela precisa desenhar. */
|
|
96
|
+
type EmailHtmlReport = {
|
|
97
|
+
readonly isValid: boolean;
|
|
98
|
+
readonly problems: readonly {
|
|
99
|
+
readonly code: string;
|
|
100
|
+
readonly severity: string;
|
|
101
|
+
readonly message: string;
|
|
102
|
+
}[];
|
|
103
|
+
};
|
|
95
104
|
type NotificationSettingsWorkspaceProps = {
|
|
96
105
|
readonly labels?: Partial<Record<string, string>>;
|
|
97
106
|
/** Os canais que ESTE produto oferece — o pacote despacha em cinco e não opina sobre quais usar. */
|
|
@@ -114,12 +123,186 @@ type NotificationSettingsWorkspaceProps = {
|
|
|
114
123
|
readonly value: string;
|
|
115
124
|
readonly onChange: (value: string) => void;
|
|
116
125
|
}) => ReactNode;
|
|
126
|
+
/**
|
|
127
|
+
* Confere o documento contra o que cliente de e-mail realmente faz (script, folha externa, imagem
|
|
128
|
+
* em `data:`, tabela desbalanceada). Ausente, nenhum aviso aparece.
|
|
129
|
+
*/
|
|
130
|
+
readonly validateEmailHtml?: (html: string) => EmailHtmlReport;
|
|
117
131
|
/** Substitui o cabeçalho padrão — a página que já tem título próprio evita o segundo `<h1>`. */
|
|
118
132
|
readonly renderHeader?: () => ReactNode;
|
|
119
133
|
/** Ações do produto no cabeçalho. */
|
|
120
134
|
readonly renderHeaderActions?: () => ReactNode;
|
|
121
135
|
readonly className?: string;
|
|
136
|
+
/**
|
|
137
|
+
* Nome do produto no preview: e o remetente do e-mail e o app do push. O pacote nao sabe de
|
|
138
|
+
* quem e a marca, e "Aviso" generico faria o preview mentir sobre o que a pessoa ve.
|
|
139
|
+
*/
|
|
140
|
+
readonly senderName?: string;
|
|
141
|
+
/** Rótulo humano de uma categoria (`auth` → "Acesso"). Ausente, mostra a própria chave. */
|
|
142
|
+
readonly categoryLabelOf?: (category: string) => string;
|
|
143
|
+
};
|
|
144
|
+
declare function NotificationSettingsWorkspace({ labels: labelsOverride, channels, categories, previewPayload, templateLabelOf, renderChannelFields, validateEmailHtml, renderHeader, renderHeaderActions, className, senderName, categoryLabelOf, }: NotificationSettingsWorkspaceProps): react.JSX.Element;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
148
|
+
*
|
|
149
|
+
* Campo de código com realce, numeração de linha e laudo do linter.
|
|
150
|
+
*
|
|
151
|
+
* Técnica de sobreposição, e não um editor de verdade: um `<pre>` colorido embaixo e o `<textarea>`
|
|
152
|
+
* transparente em cima, com a MESMA métrica de texto e a rolagem sincronizada. Custa alinhamento
|
|
153
|
+
* milimétrico, e paga não trazendo um CodeMirror (~200KB) para dentro de um pacote de UI que hoje
|
|
154
|
+
* pesa duas dependências — e não perdendo nada do `<textarea>`: seleção, desfazer, corretor,
|
|
155
|
+
* leitor de tela e o cursor que o editor usa para inserir variável continuam nativos.
|
|
156
|
+
*/
|
|
157
|
+
type HtmlCodeFieldProblem = {
|
|
158
|
+
readonly code: string;
|
|
159
|
+
readonly severity: string;
|
|
160
|
+
readonly message: string;
|
|
161
|
+
};
|
|
162
|
+
type HtmlCodeFieldProps = {
|
|
163
|
+
readonly value: string;
|
|
164
|
+
readonly rows?: number;
|
|
165
|
+
readonly onChange: (value: string) => void;
|
|
166
|
+
readonly onSelect?: (cursorIndex: number) => void;
|
|
167
|
+
readonly onFocus?: () => void;
|
|
168
|
+
/** Ausente, nenhum laudo aparece — o campo vira só realce. */
|
|
169
|
+
readonly problems?: readonly HtmlCodeFieldProblem[];
|
|
170
|
+
};
|
|
171
|
+
declare function HtmlCodeField({ value, rows, onChange, onSelect, onFocus, problems }: HtmlCodeFieldProps): react.JSX.Element;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
175
|
+
*
|
|
176
|
+
* Realce de HTML como DADOS, nunca como string de markup.
|
|
177
|
+
*
|
|
178
|
+
* A tentação aqui é montar `<span class=...>` numa string e jogar em `dangerouslySetInnerHTML` —
|
|
179
|
+
* é o caminho mais curto e é como quase toda biblioteca de realce faz. Num editor esse caminho
|
|
180
|
+
* passa por cima do texto que a pessoa acabou de digitar: o realce vira o vetor de injeção do
|
|
181
|
+
* próprio conteúdo que ele deveria só colorir. Devolver tokens deixa o React criar nó de texto, e
|
|
182
|
+
* a questão simplesmente não existe.
|
|
183
|
+
*/
|
|
184
|
+
declare const HTML_TOKEN: {
|
|
185
|
+
readonly TAG: "tag";
|
|
186
|
+
readonly NAME: "name";
|
|
187
|
+
readonly ATTRIBUTE: "attribute";
|
|
188
|
+
readonly VALUE: "value";
|
|
189
|
+
readonly COMMENT: "comment";
|
|
190
|
+
readonly DOCTYPE: "doctype";
|
|
191
|
+
readonly VARIABLE: "variable";
|
|
192
|
+
readonly TEXT: "text";
|
|
193
|
+
};
|
|
194
|
+
type HtmlTokenKind = (typeof HTML_TOKEN)[keyof typeof HTML_TOKEN];
|
|
195
|
+
type HtmlToken = {
|
|
196
|
+
readonly kind: HtmlTokenKind;
|
|
197
|
+
readonly text: string;
|
|
198
|
+
};
|
|
199
|
+
declare function tokenizeHtml(source: string): readonly HtmlToken[];
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
203
|
+
*
|
|
204
|
+
* A caixa de mensagem com barra de formatação.
|
|
205
|
+
*
|
|
206
|
+
* A seleção é assunto do DOM, e por isso ela mora aqui e não no `useTemplateEditor`: o hook guarda
|
|
207
|
+
* o rascunho, este componente guarda onde o cursor está. Depois de cada botão a seleção é
|
|
208
|
+
* reposicionada à mão — sem isso o cursor pula para o fim do texto a cada clique, e quem estava
|
|
209
|
+
* corrigindo o meio de uma frase perde o lugar.
|
|
210
|
+
*/
|
|
211
|
+
type MessageBodyFieldProps = {
|
|
212
|
+
readonly value: string;
|
|
213
|
+
readonly rows?: number;
|
|
214
|
+
readonly onChange: (value: string) => void;
|
|
215
|
+
readonly onSelect?: (cursorIndex: number) => void;
|
|
216
|
+
readonly onFocus?: () => void;
|
|
217
|
+
readonly labelOf: (key: string) => string;
|
|
122
218
|
};
|
|
123
|
-
declare function
|
|
219
|
+
declare function MessageBodyField({ value, rows, onChange, onSelect, onFocus, labelOf }: MessageBodyFieldProps): react.JSX.Element;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
223
|
+
*
|
|
224
|
+
* A barra da caixa de mensagem: negrito, itálico, tachado, monoespaçado e emoji.
|
|
225
|
+
*
|
|
226
|
+
* Ela escreve MARCAÇÃO no texto, não HTML. A convenção é a do WhatsApp (`conversation-flow.md` §4)
|
|
227
|
+
* e vale para todos os canais — quem escreve o fluxo escreve uma vez, e o canal que não a entende
|
|
228
|
+
* nativamente traduz na renderização. Um editor rico que cuspisse `<b>` obrigaria o mesmo texto a
|
|
229
|
+
* existir duas vezes, e a segunda cópia sempre atrasa em relação à primeira.
|
|
230
|
+
*/
|
|
231
|
+
type MessageToolbarProps = {
|
|
232
|
+
/** Aplica o delimitador na seleção corrente do campo. */
|
|
233
|
+
readonly onMark: (delimiter: string) => void;
|
|
234
|
+
readonly onInsert: (text: string) => void;
|
|
235
|
+
/** Rótulos acessíveis, por formato. Nada aqui é literal (web.md §6). */
|
|
236
|
+
readonly labelOf: (key: string) => string;
|
|
237
|
+
};
|
|
238
|
+
declare function MessageToolbar({ onMark, onInsert, labelOf }: MessageToolbarProps): react.JSX.Element;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
242
|
+
*
|
|
243
|
+
* Formatação e emoji da caixa de mensagem.
|
|
244
|
+
*
|
|
245
|
+
* A marcação é a do WhatsApp — `*negrito*`, `_itálico_` — e ela é ÚNICA para todos os canais
|
|
246
|
+
* (`conversation-flow.md` §4): quem escreve o fluxo escreve uma vez, e o canal que não entende a
|
|
247
|
+
* convenção nativamente traduz na renderização. Um editor rico que cuspisse `<b>` obrigaria o texto
|
|
248
|
+
* a existir duas vezes, e a segunda sempre atrasa em relação à primeira.
|
|
249
|
+
*
|
|
250
|
+
* Os delimitadores são simétricos de propósito: envolver a seleção e desfazer o envolvimento é a
|
|
251
|
+
* mesma operação com o mesmo par, e é isso que deixa o botão alternar em vez de acumular asterisco.
|
|
252
|
+
*/
|
|
253
|
+
declare const MESSAGE_FORMAT: {
|
|
254
|
+
readonly BOLD: "bold";
|
|
255
|
+
readonly ITALIC: "italic";
|
|
256
|
+
readonly STRIKETHROUGH: "strikethrough";
|
|
257
|
+
readonly MONOSPACE: "monospace";
|
|
258
|
+
};
|
|
259
|
+
type MessageFormat = (typeof MESSAGE_FORMAT)[keyof typeof MESSAGE_FORMAT];
|
|
260
|
+
type MessageFormatMark = {
|
|
261
|
+
readonly format: MessageFormat;
|
|
262
|
+
readonly delimiter: string;
|
|
263
|
+
};
|
|
264
|
+
declare const MESSAGE_FORMAT_MARKS: readonly MessageFormatMark[];
|
|
265
|
+
/**
|
|
266
|
+
* Paleta curada, e não um seletor com todos os emoji do Unicode.
|
|
267
|
+
*
|
|
268
|
+
* O mesmo emoji precisa significar a mesma coisa em todo o produto (`conversation-flow.md` §3), e
|
|
269
|
+
* uma grade infinita garante o contrário: cada pessoa escolhe um símbolo diferente para "confirmar".
|
|
270
|
+
* Vinte e quatro cobrem aviso, dinheiro, prazo e atendimento — o que estes produtos realmente dizem.
|
|
271
|
+
*/
|
|
272
|
+
declare const MESSAGE_EMOJI: readonly string[];
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Copyright (c) 2026 Ada Technology. MIT License.
|
|
276
|
+
*/
|
|
277
|
+
type ApplyMarkParams = {
|
|
278
|
+
readonly text: string;
|
|
279
|
+
readonly delimiter: string;
|
|
280
|
+
readonly selectionStart: number;
|
|
281
|
+
readonly selectionEnd: number;
|
|
282
|
+
};
|
|
283
|
+
type ApplyMarkResult = {
|
|
284
|
+
readonly text: string;
|
|
285
|
+
/** Onde o cursor precisa ficar depois — sem isto, ele volta para o começo a cada clique. */
|
|
286
|
+
readonly selectionStart: number;
|
|
287
|
+
readonly selectionEnd: number;
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
* Envolve a seleção com o delimitador — ou DESFAZ, se ela já estiver envolvida.
|
|
291
|
+
*
|
|
292
|
+
* O botão alterna, e não acumula: clicar duas vezes em negrito com o mesmo trecho selecionado
|
|
293
|
+
* devolve o texto original. Sem isso, `**texto**` vira literal na conversa, porque a convenção do
|
|
294
|
+
* WhatsApp não aninha — o segundo par cancela o primeiro e o cliente mostra os asteriscos.
|
|
295
|
+
*
|
|
296
|
+
* Seleção vazia insere o par e põe o cursor no meio: é o comportamento de quem clica em negrito
|
|
297
|
+
* ANTES de escrever, que é metade das vezes.
|
|
298
|
+
*/
|
|
299
|
+
declare function applyMark({ text, delimiter, selectionStart, selectionEnd }: ApplyMarkParams): ApplyMarkResult;
|
|
300
|
+
/** Insere no cursor, substituindo o que estiver selecionado — o que todo campo de texto faz. */
|
|
301
|
+
declare function insertAt({ text, insertion, selectionStart, selectionEnd, }: {
|
|
302
|
+
readonly text: string;
|
|
303
|
+
readonly insertion: string;
|
|
304
|
+
readonly selectionStart: number;
|
|
305
|
+
readonly selectionEnd: number;
|
|
306
|
+
}): ApplyMarkResult;
|
|
124
307
|
|
|
125
|
-
export { NotificationBell, type NotificationBellProps, type NotificationCategoryOption, type NotificationChannelOption, NotificationItem, type NotificationItemProps, NotificationList, type NotificationListProps, NotificationSettingsWorkspace, type NotificationSettingsWorkspaceProps, NotificationsWorkspace, type NotificationsWorkspaceProps, PreferencesPanel, type PreferencesPanelProps };
|
|
308
|
+
export { HTML_TOKEN, HtmlCodeField, type HtmlCodeFieldProblem, type HtmlCodeFieldProps, type HtmlToken, type HtmlTokenKind, MESSAGE_EMOJI, MESSAGE_FORMAT, MESSAGE_FORMAT_MARKS, MessageBodyField, type MessageBodyFieldProps, type MessageFormat, type MessageFormatMark, MessageToolbar, type MessageToolbarProps, NotificationBell, type NotificationBellProps, type NotificationCategoryOption, type NotificationChannelOption, NotificationItem, type NotificationItemProps, NotificationList, type NotificationListProps, NotificationSettingsWorkspace, type NotificationSettingsWorkspaceProps, NotificationsWorkspace, type NotificationsWorkspaceProps, PreferencesPanel, type PreferencesPanelProps, applyMark, insertAt, tokenizeHtml };
|