@adatechnology/conversations-ui 0.1.0-rc.39 → 0.1.0-rc.40
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-DXPSPUWF.js → chunk-DKPXKQGC.js} +1 -1
- package/dist/flows/index.d.ts +88 -5
- package/dist/flows/index.js +1104 -686
- package/dist/index.js +1 -1
- package/package.json +8 -7
- package/src/Tooltip.tsx +5 -2
- package/src/flows/FlowConnectionEdge.tsx +104 -0
- package/src/flows/FlowLegend.tsx +125 -0
- package/src/flows/FlowNodeCard.tsx +188 -30
- package/src/flows/FlowNodePanel.tsx +5 -2
- package/src/flows/FlowPalette.tsx +105 -78
- package/src/flows/FlowsWorkspace.tsx +177 -7
- package/src/flows/flowCanvasModel.test.ts +145 -1
- package/src/flows/flowCanvasModel.ts +54 -44
- package/src/flows/flowEditorOps.test.ts +35 -0
- package/src/flows/flowEditorOps.ts +25 -0
- package/src/flows/flowGraph.ts +72 -47
- package/src/flows/index.ts +4 -1
- package/src/flows/labels.ts +39 -0
package/dist/flows/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { NodeProps } from '@xyflow/react';
|
|
3
|
+
import { NodeProps, EdgeProps } from '@xyflow/react';
|
|
4
4
|
import { LucideIcon } from 'lucide-react';
|
|
5
5
|
import { FlowConditionOperator, FlowGraphData, FlowNodeData, FlowNodeType, FlowQuestionType, FlowActionKind } from '@adatechnology/meta-whatsapp-contracts';
|
|
6
6
|
export { FlowActionKind, FlowConditionOperator, FlowGraphData, FlowNodeData, FlowNodeNext, FlowNodeType, FlowQuestionType } from '@adatechnology/meta-whatsapp-contracts';
|
|
@@ -12,6 +12,15 @@ declare const BUILT_IN_ACTION_KINDS: {
|
|
|
12
12
|
readonly SEND_PRODUCT_LIST: "send_product_list";
|
|
13
13
|
readonly SEND_MEDIA: "send_media";
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Ações depois das quais a conversa CONTINUA no grafo, em vez de terminar.
|
|
17
|
+
*
|
|
18
|
+
* A distinção não é estética: o motor do bot só anda para o `next` depois de `send_media` — as
|
|
19
|
+
* demais ações (handoff, encerrar, simular, catálogo) encerram o passo ali. Dar saída a uma ação
|
|
20
|
+
* que o motor não atravessa desenharia um fio que o bot ignora em produção, deixando a conversa
|
|
21
|
+
* parada sem ninguém entender por quê — o mesmo erro que `resolveConnection` recusa cometer.
|
|
22
|
+
*/
|
|
23
|
+
declare const PASS_THROUGH_ACTION_KINDS: readonly string[];
|
|
15
24
|
declare const CROSS_FLOW_PREFIX = "flow:";
|
|
16
25
|
declare const isCrossFlowTarget: (target: string) => boolean;
|
|
17
26
|
declare const crossFlowKey: (target: string) => string;
|
|
@@ -50,6 +59,15 @@ declare function validateGraph(graph: FlowGraphData, issueText: {
|
|
|
50
59
|
conditionIncomplete: (id: string) => string;
|
|
51
60
|
conditionBranchMissing: (id: string, branch: string) => string;
|
|
52
61
|
}): GraphIssue[];
|
|
62
|
+
/**
|
|
63
|
+
* Auto-layout em cascata: avança para a direita a cada passo do fluxo e desce a cada card.
|
|
64
|
+
*
|
|
65
|
+
* **Um card por linha, sempre.** Empilhar por camada — todos do mesmo nível na mesma coluna, todas
|
|
66
|
+
* as colunas começando na mesma altura — deixava os fios correndo na horizontal, e um fio horizontal
|
|
67
|
+
* passa por trás de qualquer card que esteja entre a origem e o destino. Descendo um degrau por
|
|
68
|
+
* card, toda ligação vira uma diagonal curta e visível, e o caminho da conversa se lê de cima para
|
|
69
|
+
* baixo enquanto avança da esquerda para a direita.
|
|
70
|
+
*/
|
|
53
71
|
declare function computeAutoLayout(graph: FlowGraphData): Record<string, {
|
|
54
72
|
x: number;
|
|
55
73
|
y: number;
|
|
@@ -120,6 +138,25 @@ interface FlowEditorLabels {
|
|
|
120
138
|
media: string;
|
|
121
139
|
mediaUnavailable: string;
|
|
122
140
|
};
|
|
141
|
+
quickAdd: {
|
|
142
|
+
fromHandle: string;
|
|
143
|
+
title: string;
|
|
144
|
+
disconnect: string;
|
|
145
|
+
};
|
|
146
|
+
/** Legenda do canvas: o que cada traço e cada contorno querem dizer. */
|
|
147
|
+
legendPanel: {
|
|
148
|
+
title: string;
|
|
149
|
+
nodes: string;
|
|
150
|
+
connections: string;
|
|
151
|
+
linear: string;
|
|
152
|
+
branch: string;
|
|
153
|
+
fallback: string;
|
|
154
|
+
crossFlow: string;
|
|
155
|
+
live: string;
|
|
156
|
+
selfLoop: string;
|
|
157
|
+
detached: string;
|
|
158
|
+
startNode: string;
|
|
159
|
+
};
|
|
123
160
|
palette: {
|
|
124
161
|
title: string;
|
|
125
162
|
question: string;
|
|
@@ -222,6 +259,18 @@ type FlowNodeCardData = {
|
|
|
222
259
|
labels: FlowEditorLabels;
|
|
223
260
|
actionKindIcons?: Record<string, LucideIcon>;
|
|
224
261
|
onSelect: (id: string) => void;
|
|
262
|
+
/**
|
|
263
|
+
* Criar o próximo nó já ligado nesta saída. Capacidade por ausência: sem o callback, o "+" não
|
|
264
|
+
* aparece — puxar o fio à mão continua funcionando igual.
|
|
265
|
+
*/
|
|
266
|
+
onQuickAdd?: ((params: {
|
|
267
|
+
nodeId: string;
|
|
268
|
+
handle: string;
|
|
269
|
+
anchor: {
|
|
270
|
+
x: number;
|
|
271
|
+
y: number;
|
|
272
|
+
};
|
|
273
|
+
}) => void) | undefined;
|
|
225
274
|
};
|
|
226
275
|
declare function FlowNodeCard({ data }: NodeProps): react.JSX.Element;
|
|
227
276
|
declare const flowNodeTypes: {
|
|
@@ -297,8 +346,41 @@ interface FlowPaletteProps {
|
|
|
297
346
|
labels?: Partial<FlowEditorLabels>;
|
|
298
347
|
actionOptions?: FlowPaletteActionOption[];
|
|
299
348
|
}
|
|
349
|
+
interface FlowPaletteMenuProps {
|
|
350
|
+
onSelect: (spec: NewNodeSpec) => void;
|
|
351
|
+
labels: FlowEditorLabels;
|
|
352
|
+
actionOptions?: FlowPaletteActionOption[];
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* A lista de tipos de nó, sem o botão que a abre.
|
|
356
|
+
*
|
|
357
|
+
* Separada porque o "+" do card abre exatamente esta lista: duplicar os itens era garantir que um
|
|
358
|
+
* tipo novo aparecesse num caminho e faltasse no outro.
|
|
359
|
+
*/
|
|
360
|
+
declare function FlowPaletteMenu({ onSelect, labels, actionOptions }: FlowPaletteMenuProps): react.JSX.Element;
|
|
300
361
|
declare function FlowPalette({ onAdd, labels: labelsOverride, actionOptions }: FlowPaletteProps): react.JSX.Element;
|
|
301
362
|
|
|
363
|
+
type FlowLegendEdgeSample = {
|
|
364
|
+
readonly color: string;
|
|
365
|
+
readonly dash?: string | undefined;
|
|
366
|
+
readonly label: string;
|
|
367
|
+
};
|
|
368
|
+
type FlowLegendProps = {
|
|
369
|
+
readonly labels: FlowEditorLabels;
|
|
370
|
+
readonly edgeSamples: readonly FlowLegendEdgeSample[];
|
|
371
|
+
/** Classe de cor por tipo de card — a mesma que o `FlowNodeCard` usa, para a chave bater. */
|
|
372
|
+
readonly nodeSwatches: readonly {
|
|
373
|
+
readonly type: FlowNodeType;
|
|
374
|
+
readonly className: string;
|
|
375
|
+
}[];
|
|
376
|
+
};
|
|
377
|
+
declare function FlowLegend({ labels, edgeSamples, nodeSwatches }: FlowLegendProps): react.JSX.Element;
|
|
378
|
+
|
|
379
|
+
declare function FlowConnectionEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, markerEnd, style, data, interactionWidth, }: EdgeProps): react.JSX.Element;
|
|
380
|
+
declare const flowEdgeTypes: {
|
|
381
|
+
flowConnection: typeof FlowConnectionEdge;
|
|
382
|
+
};
|
|
383
|
+
|
|
302
384
|
interface FlowNodePanelProps {
|
|
303
385
|
graph: FlowGraphData;
|
|
304
386
|
node: FlowNodeData;
|
|
@@ -388,11 +470,12 @@ declare function countLiveByNode(params: {
|
|
|
388
470
|
readonly positions: readonly FlowLivePositionInput[] | undefined;
|
|
389
471
|
}): Record<string, number>;
|
|
390
472
|
/**
|
|
391
|
-
* Um layout só para TODOS os nós de TODOS os fluxos abertos juntos
|
|
473
|
+
* Um layout só para TODOS os nós de TODOS os fluxos abertos juntos, na mesma cascata do fluxo
|
|
474
|
+
* único: um passo para a direita a cada avanço da conversa, um degrau para baixo a cada card.
|
|
392
475
|
*
|
|
393
476
|
* Posicionar cada fluxo à parte e deslocar não resolve: nada impede dois fluxos de ocuparem o mesmo
|
|
394
|
-
* espaço, e a altura real de cada card é ignorada. Aqui
|
|
395
|
-
*
|
|
477
|
+
* espaço, e a altura real de cada card é ignorada. Aqui a travessia roda sobre o grafo mesclado
|
|
478
|
+
* inteiro, com os saltos `flow:<key>` já resolvidos para o nó inicial do alvo.
|
|
396
479
|
*/
|
|
397
480
|
declare function computeMergedLayout(params: {
|
|
398
481
|
readonly openKeys: readonly string[];
|
|
@@ -577,4 +660,4 @@ declare function applyConnection(node: FlowNodeData, resolved: ResolvedConnectio
|
|
|
577
660
|
*/
|
|
578
661
|
declare function isGraphDirty(working: FlowGraphData | undefined, published: FlowGraphData | undefined): boolean;
|
|
579
662
|
|
|
580
|
-
export { BUILT_IN_ACTION_KINDS, CONDITION_OPERATORS, CROSS_FLOW_PREFIX, type CollectionChain, type ConnectionRequest, type CreateFlowInput, DEFAULT_FLOW_EDITOR_LABELS, type FlowEdgeKind, type FlowEdgeSpec, type FlowEditorLabels, FlowGroupFrame, type FlowGroupFrameData, FlowGroupHeader, type FlowGroupHeaderData, type FlowLiveNodeCount, type FlowLivePosition, type FlowLivePositionInput, FlowMapCanvas, type FlowMapCanvasProps, FlowMapNode, type FlowMapNodeData, FlowNodeCard, type FlowNodeCardData, FlowNodePanel, type FlowNodePanelProps, type FlowNodePosition, FlowPalette, type FlowPaletteActionOption, type FlowPaletteProps, FlowPortalNode, type FlowPortalNodeData, type FlowValidationLabels, FlowWhatsAppPreview, type FlowWhatsAppPreviewProps, FlowsWorkspace, type FlowsWorkspaceApi, type FlowsWorkspaceProps, GROUP_HEADER_NODE_ID, type GraphIssue, NODE_CARD_WIDTH, type NewNodeSpec, type ResolvedConnection, WHATSAPP_LIMITS, applyConnection, buildFlowEdges, chainFrameBounds, chainFrameNodeId, computeAutoLayout, computeFlowMapLayout, computeMergedLayout, countLiveByNode, crossFlowKey, crossFlowTargetsOf, detachedNodeIds, estimateNodeHeight, findCollectionChains, flowGroupFrameNodeTypes, flowGroupHeaderNodeTypes, flowMapNodeTypes, flowNodeTypes, flowPortalNodeTypes, isCrossFlowTarget, isGraphDirty, mergeFlowEditorLabels, mergedFlowKeysFrom, namespaceNodeId, newNodeFromSpec, nodeLabel, parseNamespacedId, portalNodeId, removeNodeAndCleanRefs, rendersAsButtons, resolveConnection, slugifyNodeId, targetsOf, validateGraph };
|
|
663
|
+
export { BUILT_IN_ACTION_KINDS, CONDITION_OPERATORS, CROSS_FLOW_PREFIX, type CollectionChain, type ConnectionRequest, type CreateFlowInput, DEFAULT_FLOW_EDITOR_LABELS, FlowConnectionEdge, type FlowEdgeKind, type FlowEdgeSpec, type FlowEditorLabels, FlowGroupFrame, type FlowGroupFrameData, FlowGroupHeader, type FlowGroupHeaderData, FlowLegend, type FlowLiveNodeCount, type FlowLivePosition, type FlowLivePositionInput, FlowMapCanvas, type FlowMapCanvasProps, FlowMapNode, type FlowMapNodeData, FlowNodeCard, type FlowNodeCardData, FlowNodePanel, type FlowNodePanelProps, type FlowNodePosition, FlowPalette, type FlowPaletteActionOption, FlowPaletteMenu, type FlowPaletteProps, FlowPortalNode, type FlowPortalNodeData, type FlowValidationLabels, FlowWhatsAppPreview, type FlowWhatsAppPreviewProps, FlowsWorkspace, type FlowsWorkspaceApi, type FlowsWorkspaceProps, GROUP_HEADER_NODE_ID, type GraphIssue, NODE_CARD_WIDTH, type NewNodeSpec, PASS_THROUGH_ACTION_KINDS, type ResolvedConnection, WHATSAPP_LIMITS, applyConnection, buildFlowEdges, chainFrameBounds, chainFrameNodeId, computeAutoLayout, computeFlowMapLayout, computeMergedLayout, countLiveByNode, crossFlowKey, crossFlowTargetsOf, detachedNodeIds, estimateNodeHeight, findCollectionChains, flowEdgeTypes, flowGroupFrameNodeTypes, flowGroupHeaderNodeTypes, flowMapNodeTypes, flowNodeTypes, flowPortalNodeTypes, isCrossFlowTarget, isGraphDirty, mergeFlowEditorLabels, mergedFlowKeysFrom, namespaceNodeId, newNodeFromSpec, nodeLabel, parseNamespacedId, portalNodeId, removeNodeAndCleanRefs, rendersAsButtons, resolveConnection, slugifyNodeId, targetsOf, validateGraph };
|