@adatechnology/conversations-ui 0.4.2 → 0.5.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/README.md +169 -0
- package/dist/{ConversationSimulatorPanel-DnXElfY8.d.ts → ConversationSimulatorPanel-CrfFjiWh.d.ts} +2 -268
- package/dist/{chunk-PJNR6UMN.js → chunk-CBYEHPX6.js} +1 -63
- package/dist/{chunk-HMCOTZAX.js → chunk-HOKNKXIT.js} +1 -1
- package/dist/{chunk-4P5KMWOI.js → chunk-JXJCPN34.js} +327 -522
- package/dist/chunk-MRVFFJEH.js +64 -0
- package/dist/chunk-RJMSM3YA.js +249 -0
- package/dist/chunk-WSFGNR5R.js +55 -0
- package/dist/flows/index.js +5 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +783 -807
- package/dist/participant/index.d.ts +162 -0
- package/dist/participant/index.js +1448 -0
- package/dist/preview/index.d.ts +4 -2
- package/dist/preview/index.js +4 -2
- package/dist/quickReply.types-B4gmZsSr.d.ts +274 -0
- package/dist/styles.css +591 -0
- package/package.json +8 -4
- package/src/ChannelIcon.tsx +2 -0
- package/src/MessageBubble.test.tsx +2 -2
- package/src/MessageText.test.tsx +59 -0
- package/src/MessageText.tsx +20 -12
- package/src/MessageTextCopiedBadge.tsx +7 -0
- package/src/StatusTicks.test.tsx +30 -0
- package/src/StatusTicks.tsx +24 -9
- package/src/buildOutput.test.ts +41 -0
- package/src/channelCapability.test.ts +17 -0
- package/src/conversationChannel.test.ts +30 -1
- package/src/conversationChannel.ts +19 -1
- package/src/participant/ParticipantAttachmentItem.tsx +77 -0
- package/src/participant/ParticipantComposer.test.tsx +97 -0
- package/src/participant/ParticipantComposer.tsx +167 -0
- package/src/participant/ParticipantConversations.test.tsx +90 -0
- package/src/participant/ParticipantConversations.tsx +42 -0
- package/src/participant/ParticipantConversationsScreen.tsx +67 -0
- package/src/participant/ParticipantInbox.test.tsx +147 -0
- package/src/participant/ParticipantInbox.tsx +168 -0
- package/src/participant/ParticipantLoadState.tsx +27 -0
- package/src/participant/ParticipantMessageBubble.test.tsx +165 -0
- package/src/participant/ParticipantMessageBubble.tsx +185 -0
- package/src/participant/ParticipantThread.test.tsx +132 -0
- package/src/participant/ParticipantThread.tsx +174 -0
- package/src/participant/ParticipantThreadScreen.tsx +135 -0
- package/src/participant/bindAttachmentUrlResolver.test.ts +25 -0
- package/src/participant/bindAttachmentUrlResolver.ts +7 -0
- package/src/participant/index.ts +25 -0
- package/src/participant/participant.types.ts +43 -0
- package/src/participant/participantApi.types.ts +59 -0
- package/src/participant/participantAttachmentUrl.test.ts +32 -0
- package/src/participant/participantAttachmentUrl.ts +10 -0
- package/src/participant/participantBubbleActions.test.ts +44 -0
- package/src/participant/participantBubbleActions.ts +40 -0
- package/src/participant/participantDrafts.test.ts +65 -0
- package/src/participant/participantDrafts.ts +50 -0
- package/src/participant/participantFileValidation.test.ts +86 -0
- package/src/participant/participantFileValidation.ts +72 -0
- package/src/participant/participantFixtures.test-helper.ts +41 -0
- package/src/participant/participantGrouping.test.ts +138 -0
- package/src/participant/participantGrouping.ts +77 -0
- package/src/participant/participantInboxState.test.ts +69 -0
- package/src/participant/participantInboxState.ts +74 -0
- package/src/participant/participantLabels.ts +86 -0
- package/src/participant/participantLoadView.test.ts +23 -0
- package/src/participant/participantLoadView.ts +21 -0
- package/src/participant/participantMessages.test.ts +128 -0
- package/src/participant/participantMessages.ts +73 -0
- package/src/participant/participantNewMessages.test.ts +54 -0
- package/src/participant/participantNewMessages.ts +29 -0
- package/src/participant/participantQuickReply.test.ts +23 -0
- package/src/participant/participantQuickReply.ts +6 -0
- package/src/participant/participantScroll.test.ts +69 -0
- package/src/participant/participantScroll.ts +43 -0
- package/src/participant/participantSendController.test.ts +201 -0
- package/src/participant/participantSendController.ts +134 -0
- package/src/participant/participantSendStates.ts +31 -0
- package/src/participant/participantTheme.ts +20 -0
- package/src/participant/participantThreadState.test.ts +75 -0
- package/src/participant/participantThreadState.ts +59 -0
- package/src/participant/shouldMarkRead.test.ts +24 -0
- package/src/participant/shouldMarkRead.ts +16 -0
- package/src/participant/useDocumentVisibility.ts +18 -0
- package/src/participant/useParticipantConversationView.ts +60 -0
- package/src/participant/useParticipantDraft.ts +45 -0
- package/src/participant/useParticipantInbox.ts +57 -0
- package/src/participant/useParticipantMarkRead.ts +26 -0
- package/src/participant/useParticipantRevalidation.ts +36 -0
- package/src/participant/useParticipantSend.ts +84 -0
- package/src/participant/useParticipantThread.ts +116 -0
- package/src/participant/useParticipantThreadScroll.ts +26 -0
- package/src/participant/useStickToBottom.ts +77 -0
- package/src/preview/ConversationSimulatorPanel.tsx +8 -0
- package/src/styles.css +160 -0
- package/src/types.ts +3 -1
package/dist/preview/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { M as MessagePayload
|
|
2
|
-
|
|
1
|
+
import { M as MessagePayload } from '../quickReply.types-B4gmZsSr.js';
|
|
2
|
+
import { C as ConversationSummary, a as ConversationEventSource, b as ConversationsApi, L as ListConversationsParams, c as ConversationPage, S as SSEProvider, d as ConversationDocument, e as SendPreviewMediaParams, P as PreviewUploadedMedia, f as PreviewWebhookClient, R as ResolveMediaUrl } from '../ConversationSimulatorPanel-CrfFjiWh.js';
|
|
3
|
+
export { A as AudioRecorderButton, g as AudioRecorderButtonLabels, h as AudioRecorderButtonProps, i as ConversationPreview, j as ConversationPreviewProps, k as ConversationSimulatorClient, l as ConversationSimulatorPanel, m as ConversationSimulatorPanelLabels, n as ConversationSimulatorPanelProps, o as CreatePreviewMediaUploaderParams, p as CreatePreviewWebhookClientParams, D as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, q as DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS, r as DEFAULT_MEDIA_UPLOAD_PATH, s as PreviewInProductionError, t as PreviewMediaUploadRejectedError, u as PreviewMediaUploadRequest, v as PreviewUploadedMedia, w as PreviewWebhookRejectedError, x as SIMULATOR_FILE_MEDIA_KINDS, y as SendSimulatorMediaParams, z as SimulatorMediaKind, T as ToSimulatorClientParams, B as acceptsMediaKind, E as assertPreviewEnvironment, F as createPreviewMediaPoster, G as createPreviewMediaUploader, H as createPreviewWebhookClient, I as isConversationSimulatorClient, J as mediaKindOf, K as mediaTypeOf, M as signPreviewPayload, N as simulatorPanelLabelsOf, O as toConversationSimulatorClient } from '../ConversationSimulatorPanel-CrfFjiWh.js';
|
|
3
4
|
import { InteractiveReplyOption } from '@adatechnology/meta-whatsapp-contracts/testing';
|
|
4
5
|
import * as react from 'react';
|
|
5
6
|
export { PREVIEW_MEDIA_ID_PREFIX } from '@adatechnology/meta-whatsapp-contracts';
|
|
7
|
+
import '@adatechnology/conversation-contracts';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Estado em memória que alimenta o preview de atendimento humano. Mock de API e mock de SSE
|
package/dist/preview/index.js
CHANGED
|
@@ -16,8 +16,10 @@ import {
|
|
|
16
16
|
mediaTypeOf,
|
|
17
17
|
simulatorPanelLabelsOf,
|
|
18
18
|
toConversationSimulatorClient
|
|
19
|
-
} from "../chunk-
|
|
20
|
-
import "../chunk-
|
|
19
|
+
} from "../chunk-JXJCPN34.js";
|
|
20
|
+
import "../chunk-MRVFFJEH.js";
|
|
21
|
+
import "../chunk-RJMSM3YA.js";
|
|
22
|
+
import "../chunk-CBYEHPX6.js";
|
|
21
23
|
|
|
22
24
|
// src/preview/previewStore.ts
|
|
23
25
|
var GLOBAL_CHANNEL = "global";
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { MessageDeliveryStatus, ConversationChannel as ConversationChannel$1 } from '@adatechnology/conversation-contracts';
|
|
2
|
+
|
|
3
|
+
interface ConversationsUIConfig {
|
|
4
|
+
apiBaseUrl: string;
|
|
5
|
+
theme?: ConversationsTheme;
|
|
6
|
+
features?: ConversationsFeatures;
|
|
7
|
+
}
|
|
8
|
+
interface ConversationsTheme {
|
|
9
|
+
primaryColor?: string;
|
|
10
|
+
backgroundColor?: string;
|
|
11
|
+
bubbleSent?: string;
|
|
12
|
+
bubbleReceived?: string;
|
|
13
|
+
textPrimary?: string;
|
|
14
|
+
textSecondary?: string;
|
|
15
|
+
}
|
|
16
|
+
interface ConversationsFeatures {
|
|
17
|
+
audio?: boolean;
|
|
18
|
+
documents?: boolean;
|
|
19
|
+
emoji?: boolean;
|
|
20
|
+
darkMode?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Recorte do bloco `interactive` da Meta que a UI precisa para desenhar o menu. Fica solto (e não
|
|
24
|
+
* espelhando o contrato inteiro) porque o que chega do banco é o payload cru já enviado ao
|
|
25
|
+
* WhatsApp: qualquer campo que a UI não conheça é ignorado, nunca causa erro de render.
|
|
26
|
+
*/
|
|
27
|
+
interface InteractiveOption {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
}
|
|
32
|
+
interface InteractiveSection {
|
|
33
|
+
title?: string;
|
|
34
|
+
rows?: InteractiveOption[];
|
|
35
|
+
}
|
|
36
|
+
interface InteractivePayload {
|
|
37
|
+
type?: 'button' | 'list' | string;
|
|
38
|
+
header?: {
|
|
39
|
+
text?: string;
|
|
40
|
+
};
|
|
41
|
+
body?: {
|
|
42
|
+
text?: string;
|
|
43
|
+
};
|
|
44
|
+
footer?: {
|
|
45
|
+
text?: string;
|
|
46
|
+
};
|
|
47
|
+
action?: {
|
|
48
|
+
/** Rótulo do botão que abre a lista — só existe em `type: 'list'`. */
|
|
49
|
+
button?: string;
|
|
50
|
+
sections?: InteractiveSection[];
|
|
51
|
+
buttons?: {
|
|
52
|
+
reply?: InteractiveOption;
|
|
53
|
+
}[];
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Como o cliente respondeu a um menu: por botão ou por item de lista. */
|
|
57
|
+
type InteractiveSelection = {
|
|
58
|
+
readonly kind: 'button' | 'list';
|
|
59
|
+
readonly option: InteractiveOption;
|
|
60
|
+
};
|
|
61
|
+
interface MessagePayload {
|
|
62
|
+
id: string;
|
|
63
|
+
type: 'text' | 'image' | 'video' | 'audio' | 'document' | 'sticker' | 'template' | 'interactive';
|
|
64
|
+
/** Payload cru da mensagem. Em `type: 'interactive'`, carrega o menu que o cliente vê. */
|
|
65
|
+
payload?: InteractivePayload | null;
|
|
66
|
+
content?: string;
|
|
67
|
+
caption?: string;
|
|
68
|
+
mediaUrl?: string;
|
|
69
|
+
base64?: string;
|
|
70
|
+
uploadId?: string;
|
|
71
|
+
mediaId?: string;
|
|
72
|
+
mimeType?: string;
|
|
73
|
+
filename?: string;
|
|
74
|
+
sizeBytes?: number;
|
|
75
|
+
direction: 'inbound' | 'outbound';
|
|
76
|
+
sender: 'bot' | 'customer' | 'agent';
|
|
77
|
+
timestamp: string;
|
|
78
|
+
status?: MessageDeliveryStatus;
|
|
79
|
+
readAt?: string;
|
|
80
|
+
agentName?: string | null;
|
|
81
|
+
templateName?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Veredito de moderação vindo do backend — a UI só exibe, nunca calcula. Dicionário no browser
|
|
84
|
+
* seria peso morto e daria veredito diferente por versão de cliente.
|
|
85
|
+
*
|
|
86
|
+
* `null`/ausente = não avaliado (moderação desligada, ou mensagem anterior ao recurso), que é
|
|
87
|
+
* diferente de avaliado e limpo.
|
|
88
|
+
*/
|
|
89
|
+
moderation?: {
|
|
90
|
+
isOffensive: boolean;
|
|
91
|
+
terms: string[];
|
|
92
|
+
} | null;
|
|
93
|
+
/**
|
|
94
|
+
* Transcrição do áudio, vinda do backend — a UI só exibe, nunca transcreve. Rodar STT no browser
|
|
95
|
+
* exigiria baixar modelo por aba e daria resultado diferente por versão de cliente.
|
|
96
|
+
*
|
|
97
|
+
* `null`/ausente = não avaliado, que é diferente de `'done'` com texto vazio (áudio em silêncio,
|
|
98
|
+
* já processado). É essa distinção que decide se o balão oferece "transcrever" ou "sem fala
|
|
99
|
+
* detectada".
|
|
100
|
+
*/
|
|
101
|
+
transcription?: MessageTranscription | null;
|
|
102
|
+
isFirstInGroup?: boolean;
|
|
103
|
+
isLastInGroup?: boolean;
|
|
104
|
+
}
|
|
105
|
+
type TranscriptionStatus = 'pending' | 'done' | 'failed' | 'unsupported';
|
|
106
|
+
/**
|
|
107
|
+
* Quando transcrever, escolhido nas configurações da empresa. Espelha o
|
|
108
|
+
* `TranscriptionMode` de `@adatechnology/meta-whatsapp-contracts`; declarado aqui para o pacote de
|
|
109
|
+
* UI não obrigar quem só desenha telas a instalar os contratos do backend.
|
|
110
|
+
*/
|
|
111
|
+
type TranscriptionMode = 'auto' | 'onDemand';
|
|
112
|
+
interface MessageTranscription {
|
|
113
|
+
status: TranscriptionStatus;
|
|
114
|
+
text?: string | null;
|
|
115
|
+
/** ISO 639-1 ou nome do idioma, conforme o engine. Exibido como dica, não interpretado. */
|
|
116
|
+
language?: string | null;
|
|
117
|
+
engine?: string | null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Canal de origem da conversa e o que cada um permite.
|
|
122
|
+
*
|
|
123
|
+
* Existe porque as regras que a inbox precisa respeitar não são do WhatsApp, são **de cada canal**:
|
|
124
|
+
* a janela de sessão, o jeito de reabrir a conversa e o formato do identificador do contato mudam
|
|
125
|
+
* entre WhatsApp, Messenger, Instagram e chat de site. Tratar a regra do WhatsApp como universal
|
|
126
|
+
* faria a UI bloquear o composer num chat de site, onde janela nenhuma existe.
|
|
127
|
+
*
|
|
128
|
+
* `whatsapp` é o padrão em todo lugar: instalações que ainda não informam canal continuam
|
|
129
|
+
* funcionando exatamente como antes.
|
|
130
|
+
*/
|
|
131
|
+
|
|
132
|
+
declare const CONVERSATION_CHANNEL: {
|
|
133
|
+
readonly WHATSAPP: "whatsapp";
|
|
134
|
+
readonly MESSENGER: "messenger";
|
|
135
|
+
readonly INSTAGRAM: "instagram";
|
|
136
|
+
readonly APP: "app";
|
|
137
|
+
readonly PORTAL: "portal";
|
|
138
|
+
readonly WEBCHAT: "webchat";
|
|
139
|
+
readonly EMAIL: "email";
|
|
140
|
+
};
|
|
141
|
+
/** O que o contrato conhece, mais os dois canais da Meta que a UI já servia antes dele. */
|
|
142
|
+
type ConversationChannel = ConversationChannel$1 | 'messenger' | 'instagram';
|
|
143
|
+
declare const DEFAULT_CONVERSATION_CHANNEL: ConversationChannel;
|
|
144
|
+
/** Como o canal reabre uma conversa fora da janela de sessão. */
|
|
145
|
+
declare const REOPEN_MECHANISM: {
|
|
146
|
+
readonly TEMPLATE: "template";
|
|
147
|
+
readonly TAG: "tag";
|
|
148
|
+
readonly NONE: "none";
|
|
149
|
+
};
|
|
150
|
+
type ReopenMechanism = (typeof REOPEN_MECHANISM)[keyof typeof REOPEN_MECHANISM];
|
|
151
|
+
/** Natureza do identificador do contato — decide como exibi-lo. */
|
|
152
|
+
declare const HANDLE_KIND: {
|
|
153
|
+
readonly PHONE: "phone";
|
|
154
|
+
readonly USERNAME: "username";
|
|
155
|
+
readonly SESSION: "session";
|
|
156
|
+
readonly EMAIL: "email";
|
|
157
|
+
};
|
|
158
|
+
type HandleKind = (typeof HANDLE_KIND)[keyof typeof HANDLE_KIND];
|
|
159
|
+
/**
|
|
160
|
+
* Só o que é **exibição** do canal — rótulo, ícone, como reabrir, como mostrar o identificador.
|
|
161
|
+
* Capacidade de **comportamento** (confirma leitura, tem janela e de quantas horas, aceita anexo e
|
|
162
|
+
* áudio, precisa de transporte próprio) não mora mais aqui: para canal que
|
|
163
|
+
* `@adatechnology/conversation-contracts` conhece, ela vem de `channelCapabilityFor` (RF10). Manter
|
|
164
|
+
* os dois tipos de capacidade juntos foi o que criou a "janela" duplicada (`windowHours`) que a
|
|
165
|
+
* spec 211 mandou apagar — a mesma verdade não pode morar em dois lugares.
|
|
166
|
+
*/
|
|
167
|
+
type ChannelCapabilities = {
|
|
168
|
+
readonly label: string;
|
|
169
|
+
readonly icon: string;
|
|
170
|
+
readonly reopenMechanism: ReopenMechanism;
|
|
171
|
+
readonly handleKind: HandleKind;
|
|
172
|
+
};
|
|
173
|
+
declare const CHANNEL_CAPABILITIES: Readonly<Record<ConversationChannel, ChannelCapabilities>>;
|
|
174
|
+
declare function capabilitiesOf(channel: ConversationChannel | undefined): ChannelCapabilities;
|
|
175
|
+
declare const CHANNEL_FILTER_ALL = "all";
|
|
176
|
+
type ChannelFilter = ConversationChannel | typeof CHANNEL_FILTER_ALL;
|
|
177
|
+
type ChannelFilterOption = {
|
|
178
|
+
readonly value: ChannelFilter;
|
|
179
|
+
readonly label: string;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Opções derivadas do que existe na lista, não do catálogo inteiro: oferecer Instagram numa conta
|
|
183
|
+
* que só tem WhatsApp promete um recorte que nunca traz resultado.
|
|
184
|
+
*
|
|
185
|
+
* Devolve vazio com menos de dois canais — um filtro de opção única não filtra nada, e a barra só
|
|
186
|
+
* ocuparia espaço. O host usa isso para esconder a seção.
|
|
187
|
+
*/
|
|
188
|
+
declare function channelFiltersFor(conversations: readonly {
|
|
189
|
+
readonly channel?: ConversationChannel | undefined;
|
|
190
|
+
}[]): ChannelFilterOption[];
|
|
191
|
+
type FormatContactHandleParams = {
|
|
192
|
+
readonly handle: string;
|
|
193
|
+
readonly channel?: ConversationChannel | undefined;
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Exibição do identificador conforme a natureza dele. Formatar tudo como telefone — o que a UI
|
|
197
|
+
* fazia — transforma um `@perfil` do Instagram em dígitos sem sentido.
|
|
198
|
+
*/
|
|
199
|
+
declare function formatContactHandle(params: FormatContactHandleParams): string;
|
|
200
|
+
/** Bandeira só faz sentido quando o identificador é telefone. */
|
|
201
|
+
declare function contactFlag(params: FormatContactHandleParams): string;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Mensagem pronta cadastrada pelo produto e oferecida no composer.
|
|
205
|
+
*
|
|
206
|
+
* Difere do `QuickReply` dos chips (`MessageComposer`): aquela vive em código no host; esta vem da
|
|
207
|
+
* API, tem atalho para o `/` e é editada pela tela de cadastro.
|
|
208
|
+
*/
|
|
209
|
+
type QuickReply = {
|
|
210
|
+
readonly id: string;
|
|
211
|
+
/** Até 40 caracteres — é o que o atendente lê na lista. */
|
|
212
|
+
readonly title: string;
|
|
213
|
+
/** Casa `^[a-z0-9-]{1,20}$`: é digitado depois do `/`, sem acento nem espaço. */
|
|
214
|
+
readonly shortcut: string;
|
|
215
|
+
/** Até 1000 caracteres, com `{{marcador}}` onde entra o dado da conversa. */
|
|
216
|
+
readonly body: string;
|
|
217
|
+
/** Ausente em host sem anexos: o contrato continua o mesmo para quem não os oferece. */
|
|
218
|
+
readonly attachments?: readonly QuickReplyAttachment[];
|
|
219
|
+
};
|
|
220
|
+
/** Teto de anexos por mensagem pronta — o mesmo que a API aplica, para a tela recusar antes. */
|
|
221
|
+
declare const QUICK_REPLY_ATTACHMENT_LIMIT = 10;
|
|
222
|
+
/** Arquivo já guardado pelo host; o `uploadId` é a única chave que o pacote devolve ao servidor. */
|
|
223
|
+
type QuickReplyAttachment = {
|
|
224
|
+
readonly uploadId: string;
|
|
225
|
+
readonly filename: string;
|
|
226
|
+
readonly mimeType: string;
|
|
227
|
+
readonly sizeBytes: number;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Item da fila do composer. `local` ainda não subiu (veio do clipe); `stored` já está no servidor
|
|
231
|
+
* (veio de uma mensagem pronta) e é enviado por referência, sem baixar e subir de novo.
|
|
232
|
+
*/
|
|
233
|
+
type QueuedAttachment = {
|
|
234
|
+
readonly kind: 'local';
|
|
235
|
+
readonly localId: string;
|
|
236
|
+
readonly file: File;
|
|
237
|
+
} | {
|
|
238
|
+
readonly kind: 'stored';
|
|
239
|
+
readonly uploadId: string;
|
|
240
|
+
readonly filename: string;
|
|
241
|
+
readonly mimeType: string;
|
|
242
|
+
readonly sizeBytes: number;
|
|
243
|
+
/** Carregada sob demanda só para imagem — a lista não pode abrir N URLs assinadas de uma vez. */
|
|
244
|
+
readonly previewUrl?: string;
|
|
245
|
+
};
|
|
246
|
+
/** Resultado por arquivo: o envio em lote falha parcialmente, e só o que falhou fica na fila. */
|
|
247
|
+
type StoredAttachmentSendResult = {
|
|
248
|
+
readonly uploadId: string;
|
|
249
|
+
readonly status: 'sent' | 'failed' | 'skipped';
|
|
250
|
+
readonly errorCode?: string;
|
|
251
|
+
};
|
|
252
|
+
/** O que a tela de cadastro manda para criar ou atualizar; o `id` é do servidor. */
|
|
253
|
+
type QuickReplyInput = {
|
|
254
|
+
readonly title: string;
|
|
255
|
+
readonly shortcut: string;
|
|
256
|
+
readonly body: string;
|
|
257
|
+
/** Ordem do cadastro é a ordem de envio; ausente não mexe nos anexos já gravados. */
|
|
258
|
+
readonly attachmentUploadIds?: readonly string[];
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* Dado da conversa que um texto pode citar. Uma lista só alimenta a prévia, a inserção e o botão de
|
|
262
|
+
* variáveis — antes eram duas props de formato diferente, e as telas divergiam por isso.
|
|
263
|
+
*/
|
|
264
|
+
type ConversationVariable = {
|
|
265
|
+
readonly id: string;
|
|
266
|
+
/** Rótulo do botão "Inserir variável" (ex.: "Nome do cliente"). */
|
|
267
|
+
readonly label: string;
|
|
268
|
+
/** Como aparece no texto: `{{nome}}`. */
|
|
269
|
+
readonly marker: string;
|
|
270
|
+
/** Vazio quando a conversa não tem o dado: a variável não é oferecida. */
|
|
271
|
+
readonly value: string;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export { type ConversationChannel as C, DEFAULT_CONVERSATION_CHANNEL as D, type FormatContactHandleParams as F, HANDLE_KIND as H, type InteractiveSelection as I, type MessagePayload as M, type QuickReply as Q, REOPEN_MECHANISM as R, type StoredAttachmentSendResult as S, type TranscriptionMode as T, type ConversationsTheme as a, type MessageTranscription as b, type QuickReplyInput as c, type QuickReplyAttachment as d, type InteractivePayload as e, type ConversationsFeatures as f, type QueuedAttachment as g, type ConversationVariable as h, type ChannelFilter as i, type ChannelFilterOption as j, CHANNEL_CAPABILITIES as k, CHANNEL_FILTER_ALL as l, CONVERSATION_CHANNEL as m, type ChannelCapabilities as n, type ConversationsUIConfig as o, type HandleKind as p, type InteractiveOption as q, type InteractiveSection as r, QUICK_REPLY_ATTACHMENT_LIMIT as s, type ReopenMechanism as t, type TranscriptionStatus as u, capabilitiesOf as v, channelFiltersFor as w, contactFlag as x, formatContactHandle as y };
|