@adatechnology/conversations-ui 0.1.0-rc.8 → 0.1.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/ConversationSimulatorPanel--5fIzXWY.d.ts +804 -0
- package/dist/chunk-BJNRLLDO.js +2708 -0
- package/dist/chunk-DKPXKQGC.js +110 -0
- package/dist/{chunk-OGRRHQQW.js → chunk-WCBDXZ3X.js} +68 -4
- package/dist/flows/index.d.ts +422 -5
- package/dist/flows/index.js +2502 -678
- package/dist/index.d.ts +921 -17
- package/dist/index.js +3677 -678
- package/dist/preview/index.d.ts +62 -105
- package/dist/preview/index.js +162 -284
- package/dist/styles.css +893 -0
- package/package.json +9 -8
- package/src/AudioPlayer.tsx +8 -0
- package/src/AudioRecorderButton.test.tsx +30 -0
- package/src/AudioRecorderButton.tsx +248 -0
- package/src/AudioTranscription.test.tsx +115 -0
- package/src/AudioTranscription.tsx +252 -0
- package/src/Avatar.tsx +1 -1
- package/src/ConversationContextPanel.tsx +218 -44
- package/src/ConversationDocumentsPanel.tsx +11 -6
- package/src/ConversationHeader.test.tsx +66 -0
- package/src/ConversationHeader.tsx +147 -47
- package/src/ConversationListItem.tsx +8 -6
- package/src/ConversationLocalesProvider.tsx +28 -0
- package/src/ConversationRow.tsx +53 -7
- package/src/DarkModeToggle.test.tsx +76 -0
- package/src/DarkModeToggle.tsx +92 -0
- package/src/DocumentsLibrary.tsx +67 -7
- package/src/EmojiPicker.tsx +2 -1
- package/src/InteractiveMessage.tsx +3 -0
- package/src/Lightbox.tsx +1 -1
- package/src/MediaRenderer.tsx +88 -15
- package/src/MessageBubble.test.tsx +41 -0
- package/src/MessageBubble.tsx +47 -5
- package/src/MessageComposer.test.tsx +35 -0
- package/src/MessageComposer.tsx +122 -17
- package/src/MessageText.tsx +2 -1
- package/src/MessageTimestamp.tsx +2 -1
- package/src/RichMessageComposer.test.tsx +113 -0
- package/src/RichMessageComposer.tsx +551 -0
- package/src/SimpleEmojiPicker.tsx +5 -3
- package/src/StatusTicks.tsx +1 -1
- package/src/Toast.tsx +4 -0
- package/src/Tooltip.test.ts +42 -0
- package/src/Tooltip.tsx +167 -0
- package/src/Wallpaper.test.tsx +21 -0
- package/src/Wallpaper.tsx +67 -7
- package/src/WhatsAppMessageEditor.tsx +10 -7
- package/src/WindowExpiredNotice.tsx +12 -4
- package/src/{preview/audioRecorderFormat.test.ts → audioRecorderFormat.test.ts} +1 -1
- package/src/buildOutput.test.ts +79 -0
- package/src/composer.constant.ts +33 -0
- package/src/conversationTranscript.test.ts +57 -0
- package/src/conversationTranscript.ts +29 -4
- package/src/conversationWindow.ts +7 -5
- package/src/documentTypeLabel.test.ts +57 -0
- package/src/documents/DocumentsWorkspace.tsx +550 -0
- package/src/documents/index.ts +8 -0
- package/src/documents/labels.ts +92 -0
- package/src/flows/FlowConnectionEdge.tsx +104 -0
- package/src/flows/FlowGroupHeader.tsx +12 -2
- package/src/flows/FlowLegend.tsx +125 -0
- package/src/flows/FlowMapCanvas.tsx +15 -12
- package/src/flows/FlowMapNode.tsx +4 -1
- package/src/flows/FlowNodeCard.tsx +219 -34
- package/src/flows/FlowNodePanel.tsx +153 -39
- package/src/flows/FlowPalette.tsx +156 -70
- package/src/flows/FlowPortalNode.tsx +1 -1
- package/src/flows/FlowWhatsAppPreview.tsx +14 -3
- package/src/flows/FlowsWorkspace.tsx +1255 -0
- package/src/flows/flowCanvasModel.test.ts +456 -0
- package/src/flows/flowCanvasModel.ts +378 -0
- package/src/flows/flowEditorOps.test.ts +276 -0
- package/src/flows/flowEditorOps.ts +202 -0
- package/src/flows/flowGraph.ts +78 -53
- package/src/flows/flowMenuPlacement.test.ts +130 -0
- package/src/flows/flowMenuPlacement.ts +86 -0
- package/src/flows/index.ts +51 -2
- package/src/flows/labels.ts +180 -0
- package/src/flows/workspaceContract.test.ts +126 -0
- package/src/hooks/useContainerWidth.ts +35 -0
- package/src/hooks/useConversationRealtime.ts +10 -8
- package/src/hooks/useScrollToLatestMessage.ts +127 -0
- package/src/hooks/useUrlFilterState.ts +107 -0
- package/src/icon.constant.ts +12 -0
- package/src/index.ts +100 -0
- package/src/lib/composer-formatting.test.ts +78 -0
- package/src/lib/composer-formatting.ts +145 -0
- package/src/lib/whatsapp-formatting.test.tsx +37 -0
- package/src/lib/whatsapp-formatting.tsx +28 -3
- package/src/listing/index.tsx +202 -0
- package/src/pagination.constant.ts +10 -0
- package/src/preview/ConversationPreview.tsx +84 -45
- package/src/preview/ConversationSimulatorClient.ts +143 -0
- package/src/preview/ConversationSimulatorPanel.test.tsx +55 -0
- package/src/preview/ConversationSimulatorPanel.tsx +131 -0
- package/src/preview/createPreviewBridgeClient.test.ts +92 -0
- package/src/preview/createPreviewBridgeClient.ts +124 -0
- package/src/preview/createPreviewMediaUploader.ts +82 -0
- package/src/preview/createPreviewWebhookClient.test.ts +96 -0
- package/src/preview/createPreviewWebhookClient.ts +99 -3
- package/src/preview/index.ts +36 -2
- package/src/preview/previewMediaUploader.test.ts +61 -0
- package/src/providers/ConversationsProvider.tsx +8 -6
- package/src/providers/types.ts +59 -2
- package/src/quickReply.test.ts +58 -0
- package/src/replyLatency.test.ts +71 -0
- package/src/replyLatency.ts +57 -0
- package/src/settings/MessagesWorkspace.tsx +571 -0
- package/src/settings/TopicsForm.tsx +2 -0
- package/src/settings/TranscriptionSettingsForm.test.tsx +81 -0
- package/src/settings/TranscriptionSettingsForm.tsx +190 -0
- package/src/settings/WelcomeFarewellForm.tsx +1 -0
- package/src/settings/WhatsAppCreateTemplateForm.tsx +1 -0
- package/src/settings/WhatsAppTemplateSettingsForm.tsx +5 -2
- package/src/settings/WhatsAppTemplatesSettings.test.tsx +61 -0
- package/src/settings/WhatsAppTemplatesSettings.tsx +22 -2
- package/src/styles.css +858 -0
- package/src/theme.ts +13 -0
- package/src/types.ts +26 -0
- package/src/workspace/BulkTemplateModal.tsx +132 -0
- package/src/workspace/ConversationPane.tsx +432 -0
- package/src/workspace/ConversationsInboxList.tsx +194 -0
- package/src/workspace/ConversationsWorkspace.tsx +423 -0
- package/src/workspace/index.ts +17 -0
- package/src/workspace/labels.test.ts +17 -0
- package/src/workspace/labels.ts +85 -0
- package/src/workspace/useConversationsInbox.ts +332 -0
- package/dist/chunk-73MW5HNT.js +0 -1717
- package/dist/chunk-NV2RZ5KT.js +0 -56
- package/dist/types-B5C1DLu1.d.ts +0 -365
- package/src/preview/AudioRecorderButton.tsx +0 -117
package/dist/preview/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { U as MessagePayload, u as ConversationSummary, m as ConversationEventSource, w as ConversationsApi, Q as ListConversationsParams, n as ConversationPage, a5 as SSEProvider, k as ConversationDocument, a6 as SendPreviewMediaParams, Z as PreviewUploadedMedia, $ as PreviewWebhookClient, a3 as ResolveMediaUrl } from '../ConversationSimulatorPanel--5fIzXWY.js';
|
|
2
|
+
export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, o as ConversationPreview, p as ConversationPreviewProps, q as ConversationSimulatorClient, r as ConversationSimulatorPanel, s as ConversationSimulatorPanelLabels, t as ConversationSimulatorPanelProps, B as CreatePreviewMediaUploaderParams, D as CreatePreviewWebhookClientParams, E as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, G as DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS, I as DEFAULT_MEDIA_UPLOAD_PATH, W as PreviewInProductionError, X as PreviewMediaUploadRejectedError, Y as PreviewMediaUploadRequest, _ as PreviewUploadedMedia, a0 as PreviewWebhookRejectedError, a4 as SIMULATOR_FILE_MEDIA_KINDS, a7 as SendSimulatorMediaParams, a8 as SimulatorMediaKind, a9 as ToSimulatorClientParams, ac as acceptsMediaKind, ad as assertPreviewEnvironment, ah as createPreviewMediaPoster, ai as createPreviewMediaUploader, aj as createPreviewWebhookClient, al as isConversationSimulatorClient, am as mediaKindOf, an as mediaTypeOf, ao as signPreviewPayload, ap as simulatorPanelLabelsOf, aq as toConversationSimulatorClient } from '../ConversationSimulatorPanel--5fIzXWY.js';
|
|
3
|
+
import { InteractiveReplyOption } from '@adatechnology/meta-whatsapp-contracts/testing';
|
|
2
4
|
import * as react from 'react';
|
|
3
|
-
|
|
5
|
+
export { PREVIEW_MEDIA_ID_PREFIX } from '@adatechnology/meta-whatsapp-contracts';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Estado em memória que alimenta o preview de atendimento humano. Mock de API e mock de SSE
|
|
@@ -112,122 +114,77 @@ declare const PREVIEW_MESSAGES: Readonly<Record<string, readonly MessagePayload[
|
|
|
112
114
|
declare const PREVIEW_DOCUMENTS: Readonly<Record<string, readonly ConversationDocument[]>>;
|
|
113
115
|
|
|
114
116
|
/**
|
|
115
|
-
* Cliente que
|
|
116
|
-
*
|
|
117
|
-
*
|
|
117
|
+
* Cliente do preview que NÃO carrega segredo: em vez de montar e assinar o payload da Meta no
|
|
118
|
+
* navegador, manda um comando semântico (`{ kind: 'text', text }`) para uma rota do próprio host,
|
|
119
|
+
* autenticada pela sessão que o painel já tem. Quem monta o payload e assina é o servidor, com o
|
|
120
|
+
* app secret que nunca sai de lá.
|
|
118
121
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
122
|
+
* Por que esta fábrica existe ao lado de `createPreviewWebhookClient`: assinar no navegador exige o
|
|
123
|
+
* app secret dentro do bundle, e bundle é público por definição — em qualquer ambiente com URL
|
|
124
|
+
* acessível isso é o mesmo que publicar o segredo. Com o segredo vazado, qualquer um forja webhooks
|
|
125
|
+
* válidos daquele app: injeta mensagens de qualquer número e dispara os fluxos. `createPreviewWebhook
|
|
126
|
+
* Client` continua servindo para execução puramente local (docker de dev, onde o bundle não é
|
|
127
|
+
* servido para ninguém); para qualquer ambiente publicado, a ponte é o caminho.
|
|
121
128
|
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* mas o hábito de embarcar segredo em frontend não é.
|
|
129
|
+
* O pacote não decide autenticação: o host injeta `sendCommand` (ou `headers` + `fetchImplementation`),
|
|
130
|
+
* porque token, cookie e cabeçalho de sessão são do produto, não da biblioteca.
|
|
125
131
|
*/
|
|
126
132
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
readonly
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Comando semântico entregue ao host. É deliberadamente o QUE o cliente fez, não o payload da Meta:
|
|
135
|
+
* se o navegador mandasse o payload pronto, a rota viraria um injetor de webhook arbitrário para
|
|
136
|
+
* quem tivesse sessão. Mandando a intenção, o servidor é quem escolhe a forma.
|
|
137
|
+
*/
|
|
138
|
+
type PreviewInboundCommand = {
|
|
139
|
+
readonly kind: 'text';
|
|
140
|
+
readonly from: string;
|
|
141
|
+
readonly text: string;
|
|
142
|
+
} | {
|
|
143
|
+
readonly kind: 'buttonReply';
|
|
144
|
+
readonly from: string;
|
|
145
|
+
readonly reply: InteractiveReplyOption;
|
|
146
|
+
} | {
|
|
147
|
+
readonly kind: 'listReply';
|
|
148
|
+
readonly from: string;
|
|
149
|
+
readonly reply: InteractiveReplyOption;
|
|
150
|
+
} | {
|
|
151
|
+
readonly kind: 'audio';
|
|
152
|
+
readonly from: string;
|
|
141
153
|
readonly mediaId: string;
|
|
142
|
-
|
|
143
|
-
readonly
|
|
144
|
-
readonly caption?: string;
|
|
145
|
-
};
|
|
146
|
-
type CreatePreviewWebhookClientParams = {
|
|
147
|
-
readonly webhookUrl: string;
|
|
148
|
-
readonly appSecret: string;
|
|
154
|
+
} | ({
|
|
155
|
+
readonly kind: 'media';
|
|
149
156
|
readonly from: string;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
declare class PreviewInProductionError extends Error {
|
|
154
|
-
constructor();
|
|
155
|
-
}
|
|
156
|
-
declare class PreviewWebhookRejectedError extends Error {
|
|
157
|
+
} & SendPreviewMediaParams);
|
|
158
|
+
type SendPreviewInboundCommand = (command: PreviewInboundCommand) => Promise<void>;
|
|
159
|
+
declare class PreviewBridgeRejectedError extends Error {
|
|
157
160
|
readonly status: number;
|
|
158
161
|
constructor(status: number);
|
|
159
162
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
* que um que se recusa a montar.
|
|
163
|
-
*/
|
|
164
|
-
declare function assertPreviewEnvironment(isProduction: boolean): void;
|
|
165
|
-
/**
|
|
166
|
-
* Assina um texto qualquer com o app secret, no mesmo formato do header da Meta.
|
|
167
|
-
*
|
|
168
|
-
* Exportada porque o preview precisa provar identidade em MAIS de um lugar: além de entregar a
|
|
169
|
-
* mensagem no webhook, ele lê o transcript de volta — e ler pela API de admin exigia uma sessão que
|
|
170
|
-
* a aba do simulador não tem. Assinar a leitura com o segredo que ele já carrega resolve sem token
|
|
171
|
-
* de admin e sem rota aberta.
|
|
172
|
-
*/
|
|
173
|
-
declare function signPreviewPayload(params: {
|
|
174
|
-
rawBody: string;
|
|
175
|
-
appSecret: string;
|
|
176
|
-
}): Promise<string>;
|
|
177
|
-
declare function createPreviewWebhookClient(params: CreatePreviewWebhookClientParams): PreviewWebhookClient;
|
|
178
|
-
|
|
179
|
-
type ConversationPreviewProps = {
|
|
180
|
-
client: PreviewWebhookClient;
|
|
181
|
-
sse: SSEProvider;
|
|
182
|
-
conversationId: string;
|
|
183
|
-
loadMessages: (conversationId: string) => Promise<MessagePayload[]>;
|
|
184
|
-
placeholder?: string;
|
|
163
|
+
type CreatePreviewBridgeClientParams = {
|
|
164
|
+
readonly from: string;
|
|
185
165
|
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* responde". Ausente, não faz polling (host com SSE não precisa).
|
|
166
|
+
* Entrega o comando. Use quando o host já tem um cliente HTTP com sessão, interceptors e refresh
|
|
167
|
+
* de token — reimplementar isso aqui só duplicaria a autenticação do produto.
|
|
189
168
|
*/
|
|
190
|
-
|
|
169
|
+
readonly sendCommand?: SendPreviewInboundCommand;
|
|
170
|
+
/** Alternativa a `sendCommand` para hosts sem cliente HTTP próprio. */
|
|
171
|
+
readonly endpointUrl?: string;
|
|
172
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
173
|
+
readonly fetchImplementation?: typeof fetch;
|
|
191
174
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
175
|
+
* Rota que guarda o áudio gravado. Por padrão, `/v1/preview/media` na origem do `endpointUrl`.
|
|
176
|
+
*
|
|
177
|
+
* Aqui não há assinatura a calcular: a ponte existe justamente para não ter segredo no navegador,
|
|
178
|
+
* e a rota é protegida pela sessão do painel — os mesmos `headers` do comando valem para o upload.
|
|
196
179
|
*/
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
readonly
|
|
180
|
+
readonly mediaUploadUrl?: string;
|
|
181
|
+
/**
|
|
182
|
+
* Substitui o upload embutido. Necessário para host que só passa `sendCommand`: sem `endpointUrl`
|
|
183
|
+
* não há origem a derivar, e sem destino o gravador não é desenhado.
|
|
184
|
+
*/
|
|
185
|
+
readonly uploadMedia?: (file: File) => Promise<PreviewUploadedMedia>;
|
|
203
186
|
};
|
|
204
|
-
|
|
205
|
-
declare function mediaTypeOf(mimeType: string): SendPreviewMediaParams['mediaType'];
|
|
206
|
-
declare function ConversationPreview({ client, sse, conversationId, loadMessages, placeholder, pollIntervalMs, uploadMedia, }: ConversationPreviewProps): react.JSX.Element;
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Gravação de áudio no simulador, pelo microfone do próprio navegador.
|
|
210
|
-
*
|
|
211
|
-
* Existe porque áudio é o formato que mais chega de cliente real e o que mais quebra fluxo: sem
|
|
212
|
-
* poder gravar aqui, testar o caminho de transcrição exigia mandar mensagem do celular de alguém.
|
|
213
|
-
*
|
|
214
|
-
* O arquivo gravado sai daqui como `File` e segue exatamente o mesmo caminho de um anexo — quem
|
|
215
|
-
* hospeda e devolve o `mediaId` é o host, via `uploadMedia`.
|
|
216
|
-
*/
|
|
217
|
-
interface AudioRecorderButtonLabels {
|
|
218
|
-
start: string;
|
|
219
|
-
stop: string;
|
|
220
|
-
unsupported: string;
|
|
221
|
-
denied: string;
|
|
222
|
-
}
|
|
223
|
-
declare const DEFAULT_AUDIO_RECORDER_BUTTON_LABELS: AudioRecorderButtonLabels;
|
|
224
|
-
interface AudioRecorderButtonProps {
|
|
225
|
-
onRecorded: (file: File) => void | Promise<void>;
|
|
226
|
-
onFailure?: (message: string) => void;
|
|
227
|
-
labels?: Partial<AudioRecorderButtonLabels>;
|
|
228
|
-
disabled?: boolean;
|
|
229
|
-
}
|
|
230
|
-
declare function AudioRecorderButton({ onRecorded, onFailure, labels, disabled }: AudioRecorderButtonProps): react.JSX.Element;
|
|
187
|
+
declare function createPreviewBridgeClient(params: CreatePreviewBridgeClientParams): PreviewWebhookClient;
|
|
231
188
|
|
|
232
189
|
/**
|
|
233
190
|
* Roteiro que mantém o preview vivo: sem tráfego chegando, a inbox é uma tela estática e as
|
|
@@ -327,4 +284,4 @@ type MediaTypesPreviewProps = {
|
|
|
327
284
|
};
|
|
328
285
|
declare function MediaTypesPreview({ conversationId, className, }: MediaTypesPreviewProps): react.JSX.Element;
|
|
329
286
|
|
|
330
|
-
export { type AppendMessageParams,
|
|
287
|
+
export { type AppendMessageParams, type CreateMockConversationsApiParams, type CreateMockSSEProviderParams, type CreatePreviewBridgeClientParams, type CreatePreviewStoreParams, DEFAULT_PREVIEW_SCRIPT, GLOBAL_CHANNEL, type ListConversationsFilters, MEDIA_TYPES_CONVERSATION_ID, MediaTypesPreview, type MediaTypesPreviewProps, type MockEventSource, PREVIEW_CONVERSATIONS, PREVIEW_DOCUMENTS, PREVIEW_FILE_SAMPLES, PREVIEW_MESSAGES, PreviewBridgeRejectedError, type PreviewEmission, type PreviewInboundCommand, type PreviewScriptStep, type PreviewStore, type PreviewStoreListener, PreviewWebhookClient, type SendPreviewInboundCommand, SendPreviewMediaParams, type SetModeParams, type StartPreviewScriptParams, conversationChannel, createMockConversationsApi, createMockEventSource, createMockSSEProvider, createPreviewBridgeClient, createPreviewMediaResolver, createPreviewStore, previewFileBase64, previewFileUrl, resolvePreviewFileSample, startPreviewScript };
|