@adatechnology/conversations-ui 0.1.0-rc.34 → 0.1.0-rc.36
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/{types-De5aN-E_.d.ts → ConversationSimulatorPanel--5fIzXWY.d.ts} +303 -1
- package/dist/{chunk-CUYYYZWD.js → chunk-BJNRLLDO.js} +393 -2
- package/dist/index.d.ts +69 -8
- package/dist/index.js +123 -92
- package/dist/preview/index.d.ts +5 -210
- package/dist/preview/index.js +36 -242
- package/package.json +1 -1
- package/src/index.ts +12 -0
- package/src/preview/ConversationPreview.tsx +56 -34
- package/src/preview/ConversationSimulatorClient.ts +143 -0
- package/src/preview/ConversationSimulatorPanel.tsx +46 -4
- package/src/preview/index.ts +19 -1
- package/src/settings/MessagesWorkspace.tsx +113 -10
- package/src/settings/WhatsAppTemplatesSettings.test.tsx +61 -0
- package/src/settings/WhatsAppTemplatesSettings.tsx +14 -2
- package/src/workspace/ConversationsWorkspace.tsx +82 -5
- package/src/workspace/index.ts +6 -1
|
@@ -1601,6 +1601,85 @@ function phoneInitials(number) {
|
|
|
1601
1601
|
return digits.slice(-2);
|
|
1602
1602
|
}
|
|
1603
1603
|
|
|
1604
|
+
// src/conversationChannel.ts
|
|
1605
|
+
var CONVERSATION_CHANNEL = {
|
|
1606
|
+
WHATSAPP: "whatsapp",
|
|
1607
|
+
MESSENGER: "messenger",
|
|
1608
|
+
INSTAGRAM: "instagram",
|
|
1609
|
+
WEBCHAT: "webchat"
|
|
1610
|
+
};
|
|
1611
|
+
var DEFAULT_CONVERSATION_CHANNEL = CONVERSATION_CHANNEL.WHATSAPP;
|
|
1612
|
+
var REOPEN_MECHANISM = {
|
|
1613
|
+
TEMPLATE: "template",
|
|
1614
|
+
TAG: "tag",
|
|
1615
|
+
NONE: "none"
|
|
1616
|
+
};
|
|
1617
|
+
var HANDLE_KIND = {
|
|
1618
|
+
PHONE: "phone",
|
|
1619
|
+
USERNAME: "username",
|
|
1620
|
+
SESSION: "session"
|
|
1621
|
+
};
|
|
1622
|
+
var CHANNEL_CAPABILITIES = {
|
|
1623
|
+
[CONVERSATION_CHANNEL.WHATSAPP]: {
|
|
1624
|
+
label: "WhatsApp",
|
|
1625
|
+
icon: "\u{1F4AC}",
|
|
1626
|
+
hasSessionWindow: true,
|
|
1627
|
+
windowHours: 24,
|
|
1628
|
+
reopenMechanism: REOPEN_MECHANISM.TEMPLATE,
|
|
1629
|
+
handleKind: HANDLE_KIND.PHONE
|
|
1630
|
+
},
|
|
1631
|
+
[CONVERSATION_CHANNEL.MESSENGER]: {
|
|
1632
|
+
// Messenger também tem 24h, mas reabre com message tag — não com template aprovado.
|
|
1633
|
+
label: "Messenger",
|
|
1634
|
+
icon: "\u{1F4E8}",
|
|
1635
|
+
hasSessionWindow: true,
|
|
1636
|
+
windowHours: 24,
|
|
1637
|
+
reopenMechanism: REOPEN_MECHANISM.TAG,
|
|
1638
|
+
handleKind: HANDLE_KIND.USERNAME
|
|
1639
|
+
},
|
|
1640
|
+
[CONVERSATION_CHANNEL.INSTAGRAM]: {
|
|
1641
|
+
label: "Instagram",
|
|
1642
|
+
icon: "\u{1F4F7}",
|
|
1643
|
+
hasSessionWindow: true,
|
|
1644
|
+
windowHours: 24,
|
|
1645
|
+
reopenMechanism: REOPEN_MECHANISM.TAG,
|
|
1646
|
+
handleKind: HANDLE_KIND.USERNAME
|
|
1647
|
+
},
|
|
1648
|
+
[CONVERSATION_CHANNEL.WEBCHAT]: {
|
|
1649
|
+
// Chat próprio: sem intermediário, sem janela. Bloquear o composer aqui seria inventar limite.
|
|
1650
|
+
label: "Chat do site",
|
|
1651
|
+
icon: "\u{1F310}",
|
|
1652
|
+
hasSessionWindow: false,
|
|
1653
|
+
windowHours: 0,
|
|
1654
|
+
reopenMechanism: REOPEN_MECHANISM.NONE,
|
|
1655
|
+
handleKind: HANDLE_KIND.SESSION
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
function capabilitiesOf(channel) {
|
|
1659
|
+
return CHANNEL_CAPABILITIES[channel ?? DEFAULT_CONVERSATION_CHANNEL];
|
|
1660
|
+
}
|
|
1661
|
+
var CHANNEL_FILTER_ALL = "all";
|
|
1662
|
+
function channelFiltersFor(conversations) {
|
|
1663
|
+
const present = new Set(
|
|
1664
|
+
conversations.map((conversation) => conversation.channel ?? DEFAULT_CONVERSATION_CHANNEL)
|
|
1665
|
+
);
|
|
1666
|
+
if (present.size < 2) return [];
|
|
1667
|
+
const ordered = Object.keys(CHANNEL_CAPABILITIES).filter((channel) => present.has(channel));
|
|
1668
|
+
return [
|
|
1669
|
+
{ value: CHANNEL_FILTER_ALL, label: "Todos" },
|
|
1670
|
+
...ordered.map((channel) => ({ value: channel, label: CHANNEL_CAPABILITIES[channel].label }))
|
|
1671
|
+
];
|
|
1672
|
+
}
|
|
1673
|
+
function formatContactHandle(params) {
|
|
1674
|
+
const { handleKind } = capabilitiesOf(params.channel);
|
|
1675
|
+
if (handleKind === HANDLE_KIND.PHONE) return formatPhone(params.handle);
|
|
1676
|
+
if (handleKind === HANDLE_KIND.USERNAME) return params.handle.startsWith("@") ? params.handle : `@${params.handle}`;
|
|
1677
|
+
return `Visitante ${params.handle.slice(-6)}`;
|
|
1678
|
+
}
|
|
1679
|
+
function contactFlag(params) {
|
|
1680
|
+
return capabilitiesOf(params.channel).handleKind === HANDLE_KIND.PHONE ? phoneCountryFlag(params.handle) : "";
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1604
1683
|
// src/hooks/useAsyncResource.ts
|
|
1605
1684
|
import { useCallback as useCallback5, useEffect as useEffect3, useRef as useRef4, useState as useState9 } from "react";
|
|
1606
1685
|
function useAsyncResource(fetcher, deps) {
|
|
@@ -2258,6 +2337,299 @@ function DocumentsLibrary({
|
|
|
2258
2337
|
] });
|
|
2259
2338
|
}
|
|
2260
2339
|
|
|
2340
|
+
// src/preview/ConversationSimulatorClient.ts
|
|
2341
|
+
var SIMULATOR_FILE_MEDIA_KINDS = ["image", "video", "document"];
|
|
2342
|
+
function mediaKindOf(mimeType) {
|
|
2343
|
+
if (mimeType.startsWith("image/")) return "image";
|
|
2344
|
+
if (mimeType.startsWith("video/")) return "video";
|
|
2345
|
+
if (mimeType.startsWith("audio/")) return "audio";
|
|
2346
|
+
return "document";
|
|
2347
|
+
}
|
|
2348
|
+
function acceptsMediaKind(client, kind) {
|
|
2349
|
+
if (!client.sendMedia) return false;
|
|
2350
|
+
return client.acceptedMediaKinds?.includes(kind) ?? true;
|
|
2351
|
+
}
|
|
2352
|
+
function isConversationSimulatorClient(candidate) {
|
|
2353
|
+
return typeof candidate.sendReply === "function";
|
|
2354
|
+
}
|
|
2355
|
+
function toConversationSimulatorClient({
|
|
2356
|
+
client,
|
|
2357
|
+
uploadMedia
|
|
2358
|
+
}) {
|
|
2359
|
+
const upload = uploadMedia ?? client.uploadMedia;
|
|
2360
|
+
const base = {
|
|
2361
|
+
sendText: (text) => client.sendText(text),
|
|
2362
|
+
sendReply: (selection) => {
|
|
2363
|
+
const reply = { id: selection.option.id, title: selection.option.title };
|
|
2364
|
+
return selection.kind === "button" ? client.sendButtonReply(reply) : client.sendListReply(reply);
|
|
2365
|
+
}
|
|
2366
|
+
};
|
|
2367
|
+
if (!upload) return base;
|
|
2368
|
+
return {
|
|
2369
|
+
...base,
|
|
2370
|
+
sendMedia: async ({ mediaKind, file, mimeType, filename, caption }) => {
|
|
2371
|
+
const uploaded = await upload(file);
|
|
2372
|
+
await client.sendMedia({
|
|
2373
|
+
// O tipo sai do MIME que o upload devolveu quando ele existe: host que normaliza o formato
|
|
2374
|
+
// (áudio gravado em `webm` que sobe como `ogg`) mudava de tipo, e a mídia chegava como
|
|
2375
|
+
// documento.
|
|
2376
|
+
mediaType: uploaded.mimeType ? mediaKindOf(uploaded.mimeType) : mediaKind,
|
|
2377
|
+
mediaId: uploaded.mediaId,
|
|
2378
|
+
mimeType: uploaded.mimeType ?? mimeType ?? file.type,
|
|
2379
|
+
filename: uploaded.filename ?? filename ?? file.name,
|
|
2380
|
+
...caption ? { caption } : {}
|
|
2381
|
+
});
|
|
2382
|
+
}
|
|
2383
|
+
};
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
// src/preview/ConversationPreview.tsx
|
|
2387
|
+
import { useCallback as useCallback6, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef6, useState as useState12 } from "react";
|
|
2388
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2389
|
+
function mediaTypeOf(mimeType) {
|
|
2390
|
+
return mediaKindOf(mimeType);
|
|
2391
|
+
}
|
|
2392
|
+
var GROUPING_WINDOW_MS = 5 * 60 * 1e3;
|
|
2393
|
+
var FOLLOW_UP_REFRESH_MS = [400, 1200, 3e3];
|
|
2394
|
+
function decorate(messages) {
|
|
2395
|
+
return messages.map((message, index) => {
|
|
2396
|
+
const previous = index > 0 ? messages[index - 1] : void 0;
|
|
2397
|
+
const currentTime = new Date(message.timestamp).getTime();
|
|
2398
|
+
const previousTime = previous ? new Date(previous.timestamp).getTime() : 0;
|
|
2399
|
+
return {
|
|
2400
|
+
message,
|
|
2401
|
+
isFirstInGroup: !previous || previous.sender !== message.sender || currentTime - previousTime > GROUPING_WINDOW_MS,
|
|
2402
|
+
showDateDivider: !previous || new Date(message.timestamp).toDateString() !== new Date(previous.timestamp).toDateString()
|
|
2403
|
+
};
|
|
2404
|
+
});
|
|
2405
|
+
}
|
|
2406
|
+
function statusOf(error) {
|
|
2407
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
2408
|
+
const candidate = error;
|
|
2409
|
+
const value = candidate.status ?? candidate.statusCode;
|
|
2410
|
+
return typeof value === "number" ? value : void 0;
|
|
2411
|
+
}
|
|
2412
|
+
function isNotFound(error) {
|
|
2413
|
+
return statusOf(error) === 404;
|
|
2414
|
+
}
|
|
2415
|
+
function describeLoadFailure(error) {
|
|
2416
|
+
const status = statusOf(error);
|
|
2417
|
+
if (status === 401 || status === 403) {
|
|
2418
|
+
return "Sem sess\xE3o de administrador nesta aba: a mensagem \xE9 entregue no webhook, mas o transcript n\xE3o pode ser lido. Entre no painel nesta mesma aba e reabra o simulador.";
|
|
2419
|
+
}
|
|
2420
|
+
if (error instanceof Error && error.message) return `N\xE3o foi poss\xEDvel ler o transcript: ${error.message}`;
|
|
2421
|
+
return "N\xE3o foi poss\xEDvel ler o transcript da conversa.";
|
|
2422
|
+
}
|
|
2423
|
+
function ConversationPreview({
|
|
2424
|
+
client,
|
|
2425
|
+
sse,
|
|
2426
|
+
conversationId,
|
|
2427
|
+
loadMessages,
|
|
2428
|
+
placeholder,
|
|
2429
|
+
pollIntervalMs,
|
|
2430
|
+
uploadMedia
|
|
2431
|
+
}) {
|
|
2432
|
+
const [messages, setMessages] = useState12([]);
|
|
2433
|
+
const [failure, setFailure] = useState12(void 0);
|
|
2434
|
+
const [loadFailure, setLoadFailure] = useState12(void 0);
|
|
2435
|
+
const [isRecording, setIsRecording] = useState12(false);
|
|
2436
|
+
const [pendingLocal, setPendingLocal] = useState12([]);
|
|
2437
|
+
const loadMessagesRef = useRef6(loadMessages);
|
|
2438
|
+
const bottomRef = useRef6(null);
|
|
2439
|
+
loadMessagesRef.current = loadMessages;
|
|
2440
|
+
const simulator = useMemo4(
|
|
2441
|
+
() => isConversationSimulatorClient(client) ? client : toConversationSimulatorClient({ client, ...uploadMedia ? { uploadMedia } : {} }),
|
|
2442
|
+
[client, uploadMedia]
|
|
2443
|
+
);
|
|
2444
|
+
const refresh = useCallback6(async () => {
|
|
2445
|
+
try {
|
|
2446
|
+
const loaded = await loadMessagesRef.current(conversationId);
|
|
2447
|
+
setMessages(loaded);
|
|
2448
|
+
setLoadFailure(void 0);
|
|
2449
|
+
if (loaded.length > 0) setPendingLocal([]);
|
|
2450
|
+
} catch (error) {
|
|
2451
|
+
if (isNotFound(error)) {
|
|
2452
|
+
setMessages([]);
|
|
2453
|
+
setLoadFailure(void 0);
|
|
2454
|
+
return;
|
|
2455
|
+
}
|
|
2456
|
+
setLoadFailure(describeLoadFailure(error));
|
|
2457
|
+
}
|
|
2458
|
+
}, [conversationId]);
|
|
2459
|
+
useEffect5(() => {
|
|
2460
|
+
void refresh();
|
|
2461
|
+
}, [refresh]);
|
|
2462
|
+
useEffect5(() => {
|
|
2463
|
+
const source = sse.connectConversationStream(conversationId);
|
|
2464
|
+
const handler = () => {
|
|
2465
|
+
void refresh();
|
|
2466
|
+
};
|
|
2467
|
+
source.addEventListener("message", handler);
|
|
2468
|
+
return () => {
|
|
2469
|
+
source.removeEventListener("message", handler);
|
|
2470
|
+
source.close();
|
|
2471
|
+
};
|
|
2472
|
+
}, [sse, conversationId, refresh]);
|
|
2473
|
+
useEffect5(() => {
|
|
2474
|
+
if (!pollIntervalMs) return;
|
|
2475
|
+
const timer = setInterval(() => void refresh(), pollIntervalMs);
|
|
2476
|
+
return () => clearInterval(timer);
|
|
2477
|
+
}, [pollIntervalMs, refresh]);
|
|
2478
|
+
useEffect5(() => {
|
|
2479
|
+
bottomRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
2480
|
+
}, [messages]);
|
|
2481
|
+
const rendered = useMemo4(() => decorate([...messages, ...pendingLocal]), [messages, pendingLocal]);
|
|
2482
|
+
async function refreshWithFollowUps() {
|
|
2483
|
+
await refresh();
|
|
2484
|
+
for (const atraso of FOLLOW_UP_REFRESH_MS) {
|
|
2485
|
+
setTimeout(() => void refresh(), atraso);
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
async function handleSend(text) {
|
|
2489
|
+
setFailure(void 0);
|
|
2490
|
+
try {
|
|
2491
|
+
await simulator.sendText(text);
|
|
2492
|
+
setPendingLocal((current) => [
|
|
2493
|
+
...current,
|
|
2494
|
+
{
|
|
2495
|
+
id: `local-${current.length}-${text.length}`,
|
|
2496
|
+
type: "text",
|
|
2497
|
+
content: text,
|
|
2498
|
+
// Do ponto de vista do servidor, mensagem do cliente é inbound — é assim que ela aparece
|
|
2499
|
+
// como "minha" nesta visão.
|
|
2500
|
+
direction: "inbound",
|
|
2501
|
+
sender: "customer",
|
|
2502
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2503
|
+
status: "sent"
|
|
2504
|
+
}
|
|
2505
|
+
]);
|
|
2506
|
+
await refreshWithFollowUps();
|
|
2507
|
+
} catch (error) {
|
|
2508
|
+
setFailure(error instanceof Error ? error.message : "Falha ao entregar a mensagem no webhook.");
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
async function handleInteractiveSelect(selection) {
|
|
2512
|
+
setFailure(void 0);
|
|
2513
|
+
try {
|
|
2514
|
+
await simulator.sendReply(selection);
|
|
2515
|
+
await refreshWithFollowUps();
|
|
2516
|
+
} catch (error) {
|
|
2517
|
+
setFailure(error instanceof Error ? error.message : "Falha ao entregar a resposta no webhook.");
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
const sendMedia = simulator.sendMedia;
|
|
2521
|
+
const canAttachFile = SIMULATOR_FILE_MEDIA_KINDS.some((kind) => acceptsMediaKind(simulator, kind));
|
|
2522
|
+
const canRecordAudio = acceptsMediaKind(simulator, "audio");
|
|
2523
|
+
async function handleAttach(file) {
|
|
2524
|
+
if (!sendMedia) return;
|
|
2525
|
+
setFailure(void 0);
|
|
2526
|
+
try {
|
|
2527
|
+
await sendMedia({
|
|
2528
|
+
mediaKind: mediaKindOf(file.type),
|
|
2529
|
+
file,
|
|
2530
|
+
mimeType: file.type,
|
|
2531
|
+
filename: file.name
|
|
2532
|
+
});
|
|
2533
|
+
await refreshWithFollowUps();
|
|
2534
|
+
} catch (error) {
|
|
2535
|
+
setFailure(error instanceof Error ? error.message : "Falha ao enviar o arquivo.");
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
2539
|
+
/* @__PURE__ */ jsxs13(ConversationWallpaper, { className: "flex-1 min-h-0 overflow-y-auto px-4 py-3", children: [
|
|
2540
|
+
rendered.map(({ message, isFirstInGroup, showDateDivider }) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
2541
|
+
showDateDivider ? /* @__PURE__ */ jsx18(DateDivider, { iso: message.timestamp }) : null,
|
|
2542
|
+
/* @__PURE__ */ jsx18(
|
|
2543
|
+
MessageBubble,
|
|
2544
|
+
{
|
|
2545
|
+
message,
|
|
2546
|
+
isMine: message.direction === "inbound",
|
|
2547
|
+
isFirstInGroup,
|
|
2548
|
+
onInteractiveSelect: message.direction === "outbound" ? (selection) => void handleInteractiveSelect(selection) : void 0
|
|
2549
|
+
}
|
|
2550
|
+
)
|
|
2551
|
+
] }, message.id)),
|
|
2552
|
+
/* @__PURE__ */ jsx18("div", { ref: bottomRef })
|
|
2553
|
+
] }),
|
|
2554
|
+
failure ? /* @__PURE__ */ jsx18("p", { role: "alert", className: "px-4 py-2 text-sm text-red-600 dark:text-red-400", children: failure }) : null,
|
|
2555
|
+
loadFailure ? /* @__PURE__ */ jsx18("p", { role: "status", className: "px-4 py-2 text-sm text-amber-700 dark:text-amber-400", children: loadFailure }) : null,
|
|
2556
|
+
/* @__PURE__ */ jsx18(
|
|
2557
|
+
MessageComposer,
|
|
2558
|
+
{
|
|
2559
|
+
onSend: (text) => void handleSend(text),
|
|
2560
|
+
onAttach: canAttachFile ? (file) => void handleAttach(file) : void 0,
|
|
2561
|
+
placeholder: isRecording ? "Gravando\u2026 toque no quadrado para ouvir" : placeholder ?? "Escreva como o cliente\u2026",
|
|
2562
|
+
idleAction: canRecordAudio ? /* @__PURE__ */ jsx18(
|
|
2563
|
+
AudioRecorderButton,
|
|
2564
|
+
{
|
|
2565
|
+
onRecorded: (file) => void handleAttach(file),
|
|
2566
|
+
onFailure: (message) => setFailure(message),
|
|
2567
|
+
onRecordingChange: setIsRecording
|
|
2568
|
+
}
|
|
2569
|
+
) : void 0
|
|
2570
|
+
}
|
|
2571
|
+
)
|
|
2572
|
+
] });
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
// src/preview/ConversationSimulatorPanel.tsx
|
|
2576
|
+
import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2577
|
+
var DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS = {
|
|
2578
|
+
title: "Simulador do cliente",
|
|
2579
|
+
destinationHint: "entrega no webhook real",
|
|
2580
|
+
close: "Fechar simulador",
|
|
2581
|
+
placeholder: "Escreva como o cliente\u2026"
|
|
2582
|
+
};
|
|
2583
|
+
var SIMULATOR_PANEL_CHANNEL_WORDING = {
|
|
2584
|
+
[CONVERSATION_CHANNEL.WHATSAPP]: {
|
|
2585
|
+
destinationHint: DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS.destinationHint,
|
|
2586
|
+
placeholder: DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS.placeholder
|
|
2587
|
+
},
|
|
2588
|
+
[CONVERSATION_CHANNEL.MESSENGER]: {
|
|
2589
|
+
destinationHint: DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS.destinationHint,
|
|
2590
|
+
placeholder: DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS.placeholder
|
|
2591
|
+
},
|
|
2592
|
+
[CONVERSATION_CHANNEL.INSTAGRAM]: {
|
|
2593
|
+
destinationHint: DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS.destinationHint,
|
|
2594
|
+
placeholder: DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS.placeholder
|
|
2595
|
+
},
|
|
2596
|
+
[CONVERSATION_CHANNEL.WEBCHAT]: {
|
|
2597
|
+
destinationHint: "entrega na API do chat do site",
|
|
2598
|
+
placeholder: "Escreva como o visitante\u2026"
|
|
2599
|
+
}
|
|
2600
|
+
};
|
|
2601
|
+
function simulatorPanelLabelsOf(channel) {
|
|
2602
|
+
return {
|
|
2603
|
+
...DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS,
|
|
2604
|
+
...SIMULATOR_PANEL_CHANNEL_WORDING[channel ?? DEFAULT_CONVERSATION_CHANNEL]
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2607
|
+
function ConversationSimulatorPanel({
|
|
2608
|
+
onClose,
|
|
2609
|
+
channel,
|
|
2610
|
+
displayHandle,
|
|
2611
|
+
displayNumber,
|
|
2612
|
+
labels,
|
|
2613
|
+
headerActions,
|
|
2614
|
+
...previewProps
|
|
2615
|
+
}) {
|
|
2616
|
+
const text = { ...simulatorPanelLabelsOf(channel), ...labels };
|
|
2617
|
+
const subtitle = [displayHandle ?? displayNumber ?? previewProps.conversationId, text.destinationHint].join(" \xB7 ");
|
|
2618
|
+
return /* @__PURE__ */ jsxs14("aside", { className: "cv-simulator-panel", "aria-label": text.title, children: [
|
|
2619
|
+
/* @__PURE__ */ jsxs14("header", { className: "cv-simulator-panel__header", children: [
|
|
2620
|
+
/* @__PURE__ */ jsxs14("div", { className: "cv-simulator-panel__heading", children: [
|
|
2621
|
+
/* @__PURE__ */ jsx19("h2", { className: "cv-simulator-panel__title", children: text.title }),
|
|
2622
|
+
/* @__PURE__ */ jsx19("p", { className: "cv-simulator-panel__subtitle", children: subtitle })
|
|
2623
|
+
] }),
|
|
2624
|
+
/* @__PURE__ */ jsxs14("div", { className: "cv-simulator-panel__actions", children: [
|
|
2625
|
+
headerActions,
|
|
2626
|
+
/* @__PURE__ */ jsx19("button", { type: "button", onClick: onClose, "data-cv-tooltip": text.close, "aria-label": text.close, className: "cv-simulator-panel__close", children: /* @__PURE__ */ jsx19("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: /* @__PURE__ */ jsx19("path", { d: "M18 6 6 18M6 6l12 12" }) }) })
|
|
2627
|
+
] })
|
|
2628
|
+
] }),
|
|
2629
|
+
/* @__PURE__ */ jsx19("div", { className: "cv-simulator-panel__body", children: /* @__PURE__ */ jsx19(ConversationPreview, { ...previewProps, placeholder: text.placeholder }) })
|
|
2630
|
+
] });
|
|
2631
|
+
}
|
|
2632
|
+
|
|
2261
2633
|
export {
|
|
2262
2634
|
ConversationLocalesProvider,
|
|
2263
2635
|
useConversationLocales,
|
|
@@ -2302,8 +2674,17 @@ export {
|
|
|
2302
2674
|
MessageComposer,
|
|
2303
2675
|
DateDivider,
|
|
2304
2676
|
formatPhone,
|
|
2305
|
-
phoneCountryFlag,
|
|
2306
2677
|
phoneInitials,
|
|
2678
|
+
CONVERSATION_CHANNEL,
|
|
2679
|
+
DEFAULT_CONVERSATION_CHANNEL,
|
|
2680
|
+
REOPEN_MECHANISM,
|
|
2681
|
+
HANDLE_KIND,
|
|
2682
|
+
CHANNEL_CAPABILITIES,
|
|
2683
|
+
capabilitiesOf,
|
|
2684
|
+
CHANNEL_FILTER_ALL,
|
|
2685
|
+
channelFiltersFor,
|
|
2686
|
+
formatContactHandle,
|
|
2687
|
+
contactFlag,
|
|
2307
2688
|
useAsyncResource,
|
|
2308
2689
|
conversationsOf,
|
|
2309
2690
|
totalOf,
|
|
@@ -2313,5 +2694,15 @@ export {
|
|
|
2313
2694
|
DEFAULT_CONVERSATION_DOCUMENTS_LABELS,
|
|
2314
2695
|
ConversationDocumentsPanel,
|
|
2315
2696
|
DEFAULT_DOCUMENTS_LIBRARY_LABELS,
|
|
2316
|
-
DocumentsLibrary
|
|
2697
|
+
DocumentsLibrary,
|
|
2698
|
+
SIMULATOR_FILE_MEDIA_KINDS,
|
|
2699
|
+
mediaKindOf,
|
|
2700
|
+
acceptsMediaKind,
|
|
2701
|
+
isConversationSimulatorClient,
|
|
2702
|
+
toConversationSimulatorClient,
|
|
2703
|
+
mediaTypeOf,
|
|
2704
|
+
ConversationPreview,
|
|
2705
|
+
DEFAULT_CONVERSATION_SIMULATOR_PANEL_LABELS,
|
|
2706
|
+
simulatorPanelLabelsOf,
|
|
2707
|
+
ConversationSimulatorPanel
|
|
2317
2708
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import react__default, { ReactNode, CSSProperties, UIEvent, FormEvent, RefObject } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, C as CHANNEL_CAPABILITIES, c as CHANNEL_FILTER_ALL, d as CONVERSATION_CHANNEL, e as ChannelCapabilities, h as CompanyDocument, i as CompanyDocumentPage, l as ConversationDocumentPage, m as ConversationEventSource, n as ConversationPage,
|
|
3
|
+
import { U as MessagePayload, a3 as ResolveMediaUrl, P as InteractiveSelection, V as MessageTranscription, N as InteractivePayload, x as ConversationsFeatures, u as ConversationSummary, j as ConversationChannel, Q as ListConversationsParams, w as ConversationsApi, a5 as SSEProvider, aa as TranscriptionMode, R as ListDocumentsParams, k as ConversationDocument, v as ConversationTemplate, f as ChannelFilter, g as ChannelFilterOption, q as ConversationSimulatorClient, s as ConversationSimulatorPanelLabels, Z as PreviewUploadedMedia } from './ConversationSimulatorPanel--5fIzXWY.js';
|
|
4
|
+
export { A as AudioRecorderButton, a as AudioRecorderButtonLabels, b as AudioRecorderButtonProps, C as CHANNEL_CAPABILITIES, c as CHANNEL_FILTER_ALL, d as CONVERSATION_CHANNEL, e as ChannelCapabilities, h as CompanyDocument, i as CompanyDocumentPage, l as ConversationDocumentPage, m as ConversationEventSource, n as ConversationPage, y as ConversationsTheme, z as ConversationsUIConfig, E as DEFAULT_AUDIO_RECORDER_BUTTON_LABELS, F as DEFAULT_CONVERSATION_CHANNEL, H as DEFAULT_MAX_RECORDING_MILLISECONDS, J as FormatContactHandleParams, K as HANDLE_KIND, L as HandleKind, M as InteractiveOption, O as InteractiveSection, S as MediaRenderer, T as MediaRendererProps, a1 as REOPEN_MECHANISM, a2 as ReopenMechanism, a7 as SendSimulatorMediaParams, a8 as SimulatorMediaKind, ab as TranscriptionStatus, ae as capabilitiesOf, af as channelFiltersFor, ag as contactFlag, ak as formatContactHandle } from './ConversationSimulatorPanel--5fIzXWY.js';
|
|
5
|
+
import '@adatechnology/meta-whatsapp-contracts/testing';
|
|
5
6
|
|
|
6
7
|
interface MessageBubbleProps {
|
|
7
8
|
message: MessagePayload;
|
|
@@ -1333,12 +1334,20 @@ interface WhatsAppTemplatesSettingsProps {
|
|
|
1333
1334
|
submitting?: boolean;
|
|
1334
1335
|
result?: WhatsAppCreateTemplateResult | null;
|
|
1335
1336
|
labels?: Partial<WhatsAppCreateTemplateFormLabels>;
|
|
1337
|
+
/** Nome exibido na prévia do template criado; sem isto o form usa seu próprio fallback. */
|
|
1338
|
+
previewCompanyName?: string;
|
|
1339
|
+
variableExamples?: readonly string[];
|
|
1336
1340
|
};
|
|
1337
1341
|
labels?: Partial<WhatsAppTemplatesSettingsLabels>;
|
|
1338
1342
|
/** Vocabulário do formulário de seleção — separado de `labels`, que nomeia só as abas daqui. */
|
|
1339
1343
|
settingsLabels?: Partial<WhatsAppTemplateSettingsFormLabels>;
|
|
1344
|
+
/**
|
|
1345
|
+
* Formulários extras de seleção (um por papel adicional de template, ex.: despedida), empilhados
|
|
1346
|
+
* abaixo do principal na mesma sub-aba. Ausente = só o papel principal, comportamento de sempre.
|
|
1347
|
+
*/
|
|
1348
|
+
extraRoleForms?: ReactNode;
|
|
1340
1349
|
}
|
|
1341
|
-
declare function WhatsAppTemplatesSettings({ labels: labelsOverride, settingsLabels, create, ...settingsProps }: WhatsAppTemplatesSettingsProps): react.JSX.Element;
|
|
1350
|
+
declare function WhatsAppTemplatesSettings({ labels: labelsOverride, settingsLabels, create, extraRoleForms, ...settingsProps }: WhatsAppTemplatesSettingsProps): react.JSX.Element;
|
|
1342
1351
|
|
|
1343
1352
|
interface TopicItem {
|
|
1344
1353
|
key: string;
|
|
@@ -1373,6 +1382,22 @@ interface TemplateSettings {
|
|
|
1373
1382
|
templateLanguage: string;
|
|
1374
1383
|
variables: string[];
|
|
1375
1384
|
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Papel adicional de template (ex.: despedida) além do principal (`getTemplateSettings`/
|
|
1387
|
+
* `saveTemplateSettings`). Cada papel ganha seu próprio formulário empilhado na mesma aba, com
|
|
1388
|
+
* carregamento e salvamento independentes — é o que permite hosts com mais de um papel (o
|
|
1389
|
+
* financiamento tem boas-vindas + despedida) convergirem para este componente em vez de remontar
|
|
1390
|
+
* a tela à parte.
|
|
1391
|
+
*/
|
|
1392
|
+
interface MessagesWorkspaceTemplateRole {
|
|
1393
|
+
readonly key: string;
|
|
1394
|
+
readonly labels: {
|
|
1395
|
+
sectionTitle: string;
|
|
1396
|
+
sectionDescription: string;
|
|
1397
|
+
};
|
|
1398
|
+
getSettings(): Promise<TemplateSettings>;
|
|
1399
|
+
saveSettings(settings: TemplateSettings): Promise<void>;
|
|
1400
|
+
}
|
|
1376
1401
|
interface TranscriptionSettings {
|
|
1377
1402
|
enabled: boolean;
|
|
1378
1403
|
mode: TranscriptionMode;
|
|
@@ -1387,6 +1412,8 @@ interface MessagesWorkspaceApi {
|
|
|
1387
1412
|
/** Sem este par, a aba de templates não é desenhada. */
|
|
1388
1413
|
getTemplateSettings?(): Promise<TemplateSettings>;
|
|
1389
1414
|
saveTemplateSettings?(settings: TemplateSettings): Promise<void>;
|
|
1415
|
+
/** Papéis adicionais de template (ex.: despedida) além do principal acima. */
|
|
1416
|
+
templateRoles?: MessagesWorkspaceTemplateRole[];
|
|
1390
1417
|
/**
|
|
1391
1418
|
* Lista de templates aprovados na Meta. Ausente, a aba ainda existe (dá para salvar o nome
|
|
1392
1419
|
* escolhido), mas nasce sem opções e sem botão de recarregar.
|
|
@@ -1421,9 +1448,12 @@ interface MessagesWorkspaceProps {
|
|
|
1421
1448
|
readonly availableVariables?: WhatsAppTemplateVariableSuggestion[];
|
|
1422
1449
|
/** Aviso do produto acima da aba de templates (ex.: rota da Graph API ainda não implementada). */
|
|
1423
1450
|
readonly renderTemplatesNotice?: () => ReactNode;
|
|
1451
|
+
/** Repassados ao formulário de criação — mesma prévia que `WhatsAppCreateTemplateForm` já suporta. */
|
|
1452
|
+
readonly createTemplatePreviewCompanyName?: string;
|
|
1453
|
+
readonly createTemplateVariableExamples?: readonly string[];
|
|
1424
1454
|
readonly className?: string;
|
|
1425
1455
|
}
|
|
1426
|
-
declare function MessagesWorkspace({ api, labels: labelsOverride, welcomePlaceholders, farewellPlaceholders, availableVariables, renderTemplatesNotice, className, }: MessagesWorkspaceProps): react.JSX.Element;
|
|
1456
|
+
declare function MessagesWorkspace({ api, labels: labelsOverride, welcomePlaceholders, farewellPlaceholders, availableVariables, renderTemplatesNotice, createTemplatePreviewCompanyName, createTemplateVariableExamples, className, }: MessagesWorkspaceProps): react.JSX.Element;
|
|
1427
1457
|
|
|
1428
1458
|
interface UseConversationMessagesResult {
|
|
1429
1459
|
messages: MessagePayload[];
|
|
@@ -1681,13 +1711,38 @@ interface UseConversationsInboxResult {
|
|
|
1681
1711
|
}
|
|
1682
1712
|
declare function useConversationsInbox(params?: UseConversationsInboxParams): UseConversationsInboxResult;
|
|
1683
1713
|
|
|
1714
|
+
type SimulatorTransportParams = {
|
|
1715
|
+
readonly conversationId: string;
|
|
1716
|
+
readonly channel: ConversationChannel;
|
|
1717
|
+
/** Identificador do contato no canal: telefone no WhatsApp, id de sessão no chat do site. */
|
|
1718
|
+
readonly handle: string;
|
|
1719
|
+
};
|
|
1720
|
+
/**
|
|
1721
|
+
* Fábrica do transporte daquele canal.
|
|
1722
|
+
*
|
|
1723
|
+
* É o único ponto onde o host precisa saber de canal: o painel, a moldura e o comportamento são os
|
|
1724
|
+
* mesmos em todos. No WhatsApp devolve o cliente-ponte (assinatura no servidor do host); no chat do
|
|
1725
|
+
* site, o cliente das rotas do widget.
|
|
1726
|
+
*/
|
|
1727
|
+
type SimulatorTransportFactory = (params: SimulatorTransportParams) => ConversationSimulatorClient;
|
|
1684
1728
|
interface ConversationsWorkspaceSimulator {
|
|
1685
1729
|
/**
|
|
1686
|
-
*
|
|
1687
|
-
*
|
|
1730
|
+
* Um transporte por canal — o workspace monta o painel com o da conversa selecionada.
|
|
1731
|
+
*
|
|
1732
|
+
* Canal sem transporte não desenha o botão: capacidade é opcional por ausência, e oferecer
|
|
1733
|
+
* "simular" numa conversa que não tem como receber a mensagem é um botão que falha ao ser tocado.
|
|
1734
|
+
*/
|
|
1735
|
+
readonly transports?: Partial<Record<ConversationChannel, SimulatorTransportFactory>>;
|
|
1736
|
+
/**
|
|
1737
|
+
* Válvula de escape: o host desenha o painel inteiro. Tem precedência sobre `transports`.
|
|
1738
|
+
*
|
|
1739
|
+
* Era a única porta antes de `transports`, quando o simulador só falava WhatsApp e cada produto
|
|
1740
|
+
* remontava a moldura — o que fez duas telas da mesma casa divergirem. Continua aceito para não
|
|
1741
|
+
* quebrar quem já a usa.
|
|
1688
1742
|
*/
|
|
1689
|
-
render(params: {
|
|
1743
|
+
render?(params: {
|
|
1690
1744
|
conversationId: string;
|
|
1745
|
+
channel: ConversationChannel;
|
|
1691
1746
|
close: () => void;
|
|
1692
1747
|
}): ReactNode;
|
|
1693
1748
|
/** Ausente = ligado. Serve para esconder fora de desenvolvimento sem condicionar o JSX. */
|
|
@@ -1695,6 +1750,12 @@ interface ConversationsWorkspaceSimulator {
|
|
|
1695
1750
|
/** Ícone da biblioteca (lucide) no utilitário do cabeçalho. Ausente, entra o frasco de teste. */
|
|
1696
1751
|
readonly icon?: ReactNode;
|
|
1697
1752
|
readonly label?: string;
|
|
1753
|
+
/** Vocabulário do painel. O que muda de canal (destino, placeholder) já vem resolvido. */
|
|
1754
|
+
readonly labels?: Partial<ConversationSimulatorPanelLabels>;
|
|
1755
|
+
/** Destino do upload no canal que entrega mídia por referência (o caminho da Meta). */
|
|
1756
|
+
readonly uploadMedia?: (file: File) => Promise<PreviewUploadedMedia>;
|
|
1757
|
+
/** Recarrega o transcript a cada N ms. Serve a host sem stream. */
|
|
1758
|
+
readonly pollIntervalMs?: number;
|
|
1698
1759
|
}
|
|
1699
1760
|
interface ConversationsWorkspaceProps {
|
|
1700
1761
|
readonly labels?: Partial<ConversationsWorkspaceLabels>;
|
|
@@ -1819,4 +1880,4 @@ interface ConversationsInboxListProps {
|
|
|
1819
1880
|
}
|
|
1820
1881
|
declare function ConversationsInboxList({ inbox, labels, className, renderFilters, renderBulkActions, renderRow, onSendTemplateToSelected, }: ConversationsInboxListProps): react.JSX.Element;
|
|
1821
1882
|
|
|
1822
|
-
export { type AsyncResourceState, AudioPlayer, type AudioPlayerProps, AudioTranscription, type AudioTranscriptionProps, Avatar, type AvatarLabels, type AvatarProps, type BotMessages, type BuildTranscriptTextParams, BulkActionBar, type BulkActionBarProps, CHANNEL_BRAND_COLOR, CONVERSATIONS_PER_PAGE, CONVERSATION_WINDOW, ChannelFilter, ChannelFilterOption, ChannelIcon, type ChannelIconProps, ConversationChannel, type ConversationContextEntry, ConversationContextPanel, type ConversationContextPanelClassNames, type ConversationContextPanelLabels, type ConversationContextPanelProps, type ConversationContextStatus, ConversationDocument, ConversationDocumentsPanel, type ConversationDocumentsPanelClassNames, type ConversationDocumentsPanelLabels, type ConversationDocumentsPanelProps, ConversationHeader, type ConversationHeaderClassNames, type ConversationHeaderLabels, type ConversationHeaderProps, type ConversationHeaderUtility, ConversationListItem, type ConversationListItemLabels, type ConversationListItemProps, type ConversationLocales, ConversationLocalesProvider, type ConversationLocalesProviderProps, ConversationPane, type ConversationPaneProps, type ConversationRealtimeHandler, ConversationRow, type ConversationRowClassNames, type ConversationRowProps, ConversationSummary, ConversationTemplate, ConversationWallpaper, type ConversationWallpaperProps, type ConversationWindow, ConversationsApi, ConversationsFeatures, ConversationsInboxList, type ConversationsInboxListProps, ConversationsProvider, ConversationsWorkspace, type ConversationsWorkspaceLabels, type ConversationsWorkspaceProps, type ConversationsWorkspaceSimulator, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_AVATAR_LABELS, DEFAULT_CONVERSATIONS_WORKSPACE_LABELS, DEFAULT_CONVERSATION_CONTEXT_LABELS, DEFAULT_CONVERSATION_DOCUMENTS_LABELS, DEFAULT_CONVERSATION_HEADER_LABELS, DEFAULT_CONVERSATION_LIST_ITEM_LABELS, DEFAULT_DARK_MODE_TOGGLE_LABELS, DEFAULT_DOCUMENTS_LIBRARY_LABELS, DEFAULT_DOCUMENTS_WORKSPACE_LABELS, DEFAULT_EMOJI_PICKER_LABELS, DEFAULT_INTERACTIVE_MESSAGE_LABELS, DEFAULT_LIGHTBOX_LABELS, DEFAULT_MESSAGE_COMPOSER_LABELS, DEFAULT_RICH_COMPOSER_TOOLTIPS, DEFAULT_TEMPLATES_SETTINGS_LABELS, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, DEFAULT_WINDOW_EXPIRED_LABELS, DOCUMENT_SOURCE_FILTER, DarkModeToggle, type DarkModeToggleLabels, type DarkModeToggleProps, DateDivider, type DateDividerClassNames, type DateDividerProps, type DocumentSourceFilter, type DocumentsFiltersContext, DocumentsLibrary, type DocumentsLibraryClassNames, type DocumentsLibraryLabels, type DocumentsLibraryProps, DocumentsWorkspace, type DocumentsWorkspaceClassNames, type DocumentsWorkspaceLabels, type DocumentsWorkspaceProps, EMOJI_CATEGORIES, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, FileIcon, type FileIconProps, type FilterOption, InteractiveMessage, type InteractiveMessageLabels, type InteractiveMessageProps, InteractivePayload, InteractiveSelection, Lightbox, type LightboxLabels, type LightboxProps, ListConversationsParams, ListDocumentsParams, ListingPagination, type ListingPaginationProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerClassNames, type MessageComposerLabels, type MessageComposerProps, MessagePayload, MessageTail, MessageText, type MessageTextProps, MessageTimestamp, MessageTranscription, MessagesWorkspace, type MessagesWorkspaceApi, type MessagesWorkspaceLabels, type MessagesWorkspaceProps, MultiSelectFilter, type MultiSelectFilterProps, NARROW_MAX_WIDTH_PX, type QuickReply, RICH_COMPOSER_ACTION, ResolveMediaUrl, type RichComposerAction, type RichComposerQuickReply, type RichComposerTooltips, type RichComposerVariable, RichMessageComposer, type RichMessageComposerHandle, type RichMessageComposerProps, SSEProvider, SimpleEmojiPicker, type SimpleEmojiPickerProps, type SortDirection, SortableHead, type SortableHeadProps, StatusTicks, type StatusTicksProps, TEMPLATE_SETTINGS_TAB, TOOLTIP_ATTRIBUTE, type TemplateSettings, type TemplateSettingsTab, ToastProvider, TooltipLayer, type TopicItem, TopicsForm, type TopicsFormLabels, type TopicsFormProps, TranscriptionMode, type TranscriptionSettings, TranscriptionSettingsForm, type TranscriptionSettingsFormLabels, type TranscriptionSettingsFormProps, type UrlStateOptions, type UseConversationActionsResult, type UseConversationContextResult, type UseConversationDocumentsParams, type UseConversationDocumentsResult, type UseConversationListParams, type UseConversationListResult, type UseConversationMessagesResult, type UseConversationsInboxParams, type UseConversationsInboxResult, type UseInboxActionsResult, type UseScrollToLatestMessageParams, type UseScrollToLatestMessageResult, type UseWaitingNotificationsLabels, type UseWaitingNotificationsParams, type UseWaitingNotificationsResult, WINDOW_FILTERS, WelcomeFarewellForm, type WelcomeFarewellFormLabels, type WelcomeFarewellFormProps, WhatsAppCreateTemplateForm, type WhatsAppCreateTemplateFormLabels, type WhatsAppCreateTemplateFormProps, type WhatsAppCreateTemplateResult, type WhatsAppCreateTemplateState, WhatsAppMessageEditor, type WhatsAppMessageEditorLabels, type WhatsAppMessageEditorProps, type WhatsAppTemplateHeaderType, WhatsAppTemplateSettingsForm, type WhatsAppTemplateSettingsFormLabels, type WhatsAppTemplateSettingsFormProps, type WhatsAppTemplateSummary, type WhatsAppTemplateVariableSuggestion, WhatsAppTemplatesSettings, type WhatsAppTemplatesSettingsLabels, type WhatsAppTemplatesSettingsProps, WindowExpiredNotice, type WindowExpiredNoticeLabels, type WindowExpiredNoticeProps, type WindowOfParams, applyQuickReplyVariables, buildTranscriptFilename, buildTranscriptText, createMediaUrlResolver, downloadTextFile, formatDateTime, formatFileSize, formatPhone, formatStalledFor, formatTimestamp, htmlToWA, isSameDay, isWindowBlocking, parseWhatsAppFormatting, phoneInitials, resolveQuickReply, searchEmojis, toast, useConversationActions, useConversationContext, useConversationDocuments, useConversationList, useConversationLocales, useConversationMessages, useConversationRealtime, useConversations, useConversationsInbox, useDarkMode, useDebouncedValue, useGlobalRealtime, useInboxActions, useIsDarkTheme, useIsNarrow, useScrollToLatestMessage, useToast, useUrlArrayState, useUrlNumberState, useUrlStringState, useWaitingNotifications, waToHTML, waToHTMLInline, windowOf };
|
|
1883
|
+
export { type AsyncResourceState, AudioPlayer, type AudioPlayerProps, AudioTranscription, type AudioTranscriptionProps, Avatar, type AvatarLabels, type AvatarProps, type BotMessages, type BuildTranscriptTextParams, BulkActionBar, type BulkActionBarProps, CHANNEL_BRAND_COLOR, CONVERSATIONS_PER_PAGE, CONVERSATION_WINDOW, ChannelFilter, ChannelFilterOption, ChannelIcon, type ChannelIconProps, ConversationChannel, type ConversationContextEntry, ConversationContextPanel, type ConversationContextPanelClassNames, type ConversationContextPanelLabels, type ConversationContextPanelProps, type ConversationContextStatus, ConversationDocument, ConversationDocumentsPanel, type ConversationDocumentsPanelClassNames, type ConversationDocumentsPanelLabels, type ConversationDocumentsPanelProps, ConversationHeader, type ConversationHeaderClassNames, type ConversationHeaderLabels, type ConversationHeaderProps, type ConversationHeaderUtility, ConversationListItem, type ConversationListItemLabels, type ConversationListItemProps, type ConversationLocales, ConversationLocalesProvider, type ConversationLocalesProviderProps, ConversationPane, type ConversationPaneProps, type ConversationRealtimeHandler, ConversationRow, type ConversationRowClassNames, type ConversationRowProps, ConversationSimulatorClient, ConversationSummary, ConversationTemplate, ConversationWallpaper, type ConversationWallpaperProps, type ConversationWindow, ConversationsApi, ConversationsFeatures, ConversationsInboxList, type ConversationsInboxListProps, ConversationsProvider, ConversationsWorkspace, type ConversationsWorkspaceLabels, type ConversationsWorkspaceProps, type ConversationsWorkspaceSimulator, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_AVATAR_LABELS, DEFAULT_CONVERSATIONS_WORKSPACE_LABELS, DEFAULT_CONVERSATION_CONTEXT_LABELS, DEFAULT_CONVERSATION_DOCUMENTS_LABELS, DEFAULT_CONVERSATION_HEADER_LABELS, DEFAULT_CONVERSATION_LIST_ITEM_LABELS, DEFAULT_DARK_MODE_TOGGLE_LABELS, DEFAULT_DOCUMENTS_LIBRARY_LABELS, DEFAULT_DOCUMENTS_WORKSPACE_LABELS, DEFAULT_EMOJI_PICKER_LABELS, DEFAULT_INTERACTIVE_MESSAGE_LABELS, DEFAULT_LIGHTBOX_LABELS, DEFAULT_MESSAGE_COMPOSER_LABELS, DEFAULT_RICH_COMPOSER_TOOLTIPS, DEFAULT_TEMPLATES_SETTINGS_LABELS, DEFAULT_WHATSAPP_MESSAGE_EDITOR_LABELS, DEFAULT_WINDOW_EXPIRED_LABELS, DOCUMENT_SOURCE_FILTER, DarkModeToggle, type DarkModeToggleLabels, type DarkModeToggleProps, DateDivider, type DateDividerClassNames, type DateDividerProps, type DocumentSourceFilter, type DocumentsFiltersContext, DocumentsLibrary, type DocumentsLibraryClassNames, type DocumentsLibraryLabels, type DocumentsLibraryProps, DocumentsWorkspace, type DocumentsWorkspaceClassNames, type DocumentsWorkspaceLabels, type DocumentsWorkspaceProps, EMOJI_CATEGORIES, type EmojiCategory, type EmojiEntry, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, FileIcon, type FileIconProps, type FilterOption, InteractiveMessage, type InteractiveMessageLabels, type InteractiveMessageProps, InteractivePayload, InteractiveSelection, Lightbox, type LightboxLabels, type LightboxProps, ListConversationsParams, ListDocumentsParams, ListingPagination, type ListingPaginationProps, MessageBubble, type MessageBubbleProps, MessageComposer, type MessageComposerClassNames, type MessageComposerLabels, type MessageComposerProps, MessagePayload, MessageTail, MessageText, type MessageTextProps, MessageTimestamp, MessageTranscription, MessagesWorkspace, type MessagesWorkspaceApi, type MessagesWorkspaceLabels, type MessagesWorkspaceProps, MultiSelectFilter, type MultiSelectFilterProps, NARROW_MAX_WIDTH_PX, type QuickReply, RICH_COMPOSER_ACTION, ResolveMediaUrl, type RichComposerAction, type RichComposerQuickReply, type RichComposerTooltips, type RichComposerVariable, RichMessageComposer, type RichMessageComposerHandle, type RichMessageComposerProps, SSEProvider, SimpleEmojiPicker, type SimpleEmojiPickerProps, type SimulatorTransportFactory, type SimulatorTransportParams, type SortDirection, SortableHead, type SortableHeadProps, StatusTicks, type StatusTicksProps, TEMPLATE_SETTINGS_TAB, TOOLTIP_ATTRIBUTE, type TemplateSettings, type TemplateSettingsTab, ToastProvider, TooltipLayer, type TopicItem, TopicsForm, type TopicsFormLabels, type TopicsFormProps, TranscriptionMode, type TranscriptionSettings, TranscriptionSettingsForm, type TranscriptionSettingsFormLabels, type TranscriptionSettingsFormProps, type UrlStateOptions, type UseConversationActionsResult, type UseConversationContextResult, type UseConversationDocumentsParams, type UseConversationDocumentsResult, type UseConversationListParams, type UseConversationListResult, type UseConversationMessagesResult, type UseConversationsInboxParams, type UseConversationsInboxResult, type UseInboxActionsResult, type UseScrollToLatestMessageParams, type UseScrollToLatestMessageResult, type UseWaitingNotificationsLabels, type UseWaitingNotificationsParams, type UseWaitingNotificationsResult, WINDOW_FILTERS, WelcomeFarewellForm, type WelcomeFarewellFormLabels, type WelcomeFarewellFormProps, WhatsAppCreateTemplateForm, type WhatsAppCreateTemplateFormLabels, type WhatsAppCreateTemplateFormProps, type WhatsAppCreateTemplateResult, type WhatsAppCreateTemplateState, WhatsAppMessageEditor, type WhatsAppMessageEditorLabels, type WhatsAppMessageEditorProps, type WhatsAppTemplateHeaderType, WhatsAppTemplateSettingsForm, type WhatsAppTemplateSettingsFormLabels, type WhatsAppTemplateSettingsFormProps, type WhatsAppTemplateSummary, type WhatsAppTemplateVariableSuggestion, WhatsAppTemplatesSettings, type WhatsAppTemplatesSettingsLabels, type WhatsAppTemplatesSettingsProps, WindowExpiredNotice, type WindowExpiredNoticeLabels, type WindowExpiredNoticeProps, type WindowOfParams, applyQuickReplyVariables, buildTranscriptFilename, buildTranscriptText, createMediaUrlResolver, downloadTextFile, formatDateTime, formatFileSize, formatPhone, formatStalledFor, formatTimestamp, htmlToWA, isSameDay, isWindowBlocking, parseWhatsAppFormatting, phoneInitials, resolveQuickReply, searchEmojis, toast, useConversationActions, useConversationContext, useConversationDocuments, useConversationList, useConversationLocales, useConversationMessages, useConversationRealtime, useConversations, useConversationsInbox, useDarkMode, useDebouncedValue, useGlobalRealtime, useInboxActions, useIsDarkTheme, useIsNarrow, useScrollToLatestMessage, useToast, useUrlArrayState, useUrlNumberState, useUrlStringState, useWaitingNotifications, waToHTML, waToHTMLInline, windowOf };
|