Skip to content

Commit

Permalink
Add chatbot fields: delay and action
Browse files Browse the repository at this point in the history
  • Loading branch information
WalissonPires committed Jul 17, 2024
1 parent a1eeaf3 commit adb64cc
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 6 deletions.
9 changes: 8 additions & 1 deletion src/common/services/messaging/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface ChatNode {
delayChildren?: number; // Delay antes de selecionar o próximo estado. CasoUso: O bot pede para o cliente digitar algo. Só que o cliente enviar em varias mensagens. Para exibir que o bot responda na primeira mensagem esperar algum tempo
action?: {
type: ChatNodeAction;
params?: any;
};
delay?: number; // seconds
}
Expand All @@ -60,8 +61,14 @@ export interface ChatNodeOutput {
content: string;
}


export enum ChatNodeAction {
GoToPrevious = 1
GoToPrevious = 1,
GoToNode = 2
}

export interface GoToNodeParams {
nodeId: string;
}

export enum ChatNodePatternType {
Expand Down
81 changes: 80 additions & 1 deletion src/components/ChatbotFlowView/hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useMemo, ChangeEvent, MouseEvent, useEffect } from "react";
import { AppError } from "@/common/error";
import { AnyText, ChatNode, ChatNodeOutput, ChatNodePatternType, ProviderType } from "@/common/services/messaging/models";
import { AnyText, ChatNode, ChatNodeAction, ChatNodeOutput, ChatNodePatternType, GoToNodeParams, ProviderType } from "@/common/services/messaging/models";
import { AppToast } from "@/common/ui/toast";
import { MessageProvidersApi } from "@/domains/message-providers/client-api";
import { useLoading } from "../../AppLayout/Loading/hooks";
Expand All @@ -24,6 +24,7 @@ export function useChatbotFlow() {
const curretNodeId = nodesPath.at(-1);
const currentNode = curretNodeId ? nodesIndex[curretNodeId] : null;

const getNodesList = () => Object.values(nodesIndex);

const handleNext = (node: ChatNode) => () => {

Expand Down Expand Up @@ -114,6 +115,26 @@ export function useChatbotFlow() {
}));
};

const handleDelayChange = (event: ChangeEvent<HTMLInputElement>) => {

if (!currentNode || !rootNode) return;

setRootNode(updateNode(rootNode, node => {

if (node.id !== currentNode.id) return;

if (event.target.value === '') {
node.delay = undefined;
return;
}

const delay = parseInt(event.target.value);

if (!isNaN(delay))
node.delay = delay;
}));
};

const handlePatternTypeChange = (event: ChangeEvent<HTMLSelectElement>) => {

if (!currentNode || !rootNode) return;
Expand All @@ -138,6 +159,55 @@ export function useChatbotFlow() {
}));
};

const handleActionTypeChange = (event: ChangeEvent<HTMLSelectElement>) => {

if (!currentNode || !rootNode) return;

setRootNode(updateNode(rootNode, node => {

if (node.id !== currentNode.id) return;

if (event.target.value === '') {

node.action = undefined;
return;
}

const actionType = parseInt(event.target.value);

if (node.action)
node.action.type = actionType;
else
node.action = { type: actionType };
}));
};

const handleGoToNodeParamNodeIdChange = (event: ChangeEvent<HTMLSelectElement>) => {

if (!currentNode || !rootNode) return;

setRootNode(updateNode(rootNode, node => {

if (node.id !== currentNode.id) return;

if (event.target.value === '') {

node.action = undefined;
return;
}

if (!node.action)
throw new Error('Action is empty');

const params: GoToNodeParams = {
...node.action.params,
nodeId: event.target.id
};

node.action.params = params;
}));
};

const handleOutputContentChange = ({ type, content }: ChatNodeOutput) => (event: ChangeEvent<HTMLPreElement>) => {

if (!currentNode || !rootNode) return;
Expand Down Expand Up @@ -228,14 +298,18 @@ export function useChatbotFlow() {
nodesIndex,
nodesPath,
visible,
getNodesList,
handleToggleDropdown,
handleNext,
handlePrevious,
handleAddResponse,
handleShowAddChild,
handleRemoveChild,
handlePatternChange,
handleDelayChange,
handlePatternTypeChange,
handleActionTypeChange,
handleGoToNodeParamNodeIdChange,
handleOutputContentChange,
handleRemoveOutput,
handleSave,
Expand All @@ -257,6 +331,11 @@ export const UserBuildinPatternsDisplay: Record<UserBuildinPatterns, string> = {
[ChatNodePatternType.Regex]: 'Regex',
};

export const ChatNodeActionDisplay: Record<ChatNodeAction, string> = {
[ChatNodeAction.GoToNode]: 'Ir para mensagem',
[ChatNodeAction.GoToPrevious]: 'Ir para mensagem anterior'
};

// export function mapPatternToUserBuildinPatterns(pattern: string) {

// if (pattern === AnyText) {
Expand Down
37 changes: 33 additions & 4 deletions src/components/ChatbotFlowView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import Skeleton from "react-loading-skeleton";
import { ArrowRightIcon, ChatBubbleBottomCenterTextIcon, ChevronDownIcon, ChevronRightIcon, EnvelopeIcon, FilmIcon, PlusIcon, TrashIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { Button, DropdownMenu, DropdownMenuItem, Input, Select } from "../Form";
import { ChatNodePatternTypeAdditional, UserBuildinPatternsDisplay, useChatbotFlow } from "./hooks";
import { AnyText, ChatNodePatternType } from "../../common/services/messaging/models";
import { Button, ColSize, DropdownMenu, DropdownMenuItem, FormColumn, FormRow, Input, Select } from "../Form";
import { ChatNodeActionDisplay, ChatNodePatternTypeAdditional, UserBuildinPatternsDisplay, useChatbotFlow } from "./hooks";
import { AnyText, ChatNodeAction, ChatNodePatternType, GoToNodeParams } from "../../common/services/messaging/models";
import { getEnumPairValue } from "../../common/primitives/enum/enum-utils";


Expand All @@ -16,14 +16,18 @@ export function ChatbotFlowView() {
nodesIndex,
nodesPath,
visible,
getNodesList,
handleToggleDropdown,
handleNext,
handlePrevious,
handleAddResponse,
handleShowAddChild,
handleRemoveChild,
handlePatternChange,
handleDelayChange,
handlePatternTypeChange,
handleActionTypeChange,
handleGoToNodeParamNodeIdChange,
handleOutputContentChange,
handleRemoveOutput,
handleSave,
Expand Down Expand Up @@ -60,7 +64,7 @@ export function ChatbotFlowView() {
<div className="mb-2 text-right">
<Button onClick={handleSave}>Salvar</Button>
</div>
<div>
<div className="mb-6">
<label className="block font-bold">Mensagem do usuário</label>
<div className="flex flex-row">
{/* <label className="flex flex-row items-center p-2 bg-slate-100">
Expand All @@ -76,6 +80,31 @@ export function ChatbotFlowView() {
</div>
</div>

<FormRow>
<FormColumn size={ColSize.span2}>
<label className="block font-bold">Tempo espera</label>
<Input value={currentNode?.delay ?? ''} onChange={handleDelayChange} placeholder="Tempo em segundos" />
</FormColumn>
</FormRow>
<FormRow>
<FormColumn size={ColSize.span2}>
<label className="block font-bold">Ação</label>
<Select defaultValue={''} value={currentNode?.action?.type ?? ''} onChange={handleActionTypeChange}>
<option value="">Nenhuma</option>
{getEnumPairValue(ChatNodeActionDisplay).map(({ value, text }) => <option value={value} key={value}>{text}</option>)}
</Select>
</FormColumn>
</FormRow>
{currentNode?.action?.type == ChatNodeAction.GoToNode &&
<FormRow>
<FormColumn size={ColSize.span2}>
<label className="block font-bold">Mensagem dest.</label>
<Select defaultValue={''} value={(currentNode?.action?.params as GoToNodeParams)?.nodeId} onChange={handleGoToNodeParamNodeIdChange}>
{getNodesList().filter(x => x.id !== currentNode?.id).map(node => <option value={node.id} key={node.id}>{node.label}</option>)}
</Select>
</FormColumn>
</FormRow>}

<div className="mt-3">
<div className="flex flex-row flex-wrap justify-between items-center mb-3">
<label className="block font-bold">Respostas</label>
Expand Down

0 comments on commit adb64cc

Please sign in to comment.