Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Assign Step #393

Open
wants to merge 5 commits into
base: v2.0.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions DSL/DMapper/hbs/bot_responses_to_messages.handlebars
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{{#each data.botMessages}}
{
"chatId": "{{../data.chatId}}",
"content": "{{{choose text result}}}",
"buttons": "[{{#each buttons}}{\"title\": \"{{{title}}}\",\"payload\": \"{{{payload}}}\"}{{#unless @last}},{{/unless}}{{/each}}]",
"authorTimestamp": "{{../data.authorTimestamp}}",
"authorId": "{{../data.authorId}}",
"authorFirstName": "{{../data.authorFirstName}}",
"authorLastName": "{{../data.authorLastName}}",
"created": "{{../data.created}}"
}{{#unless @last}},{{/unless}}
{{/each}}
]
1 change: 1 addition & 0 deletions GUI/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ REACT_APP_ANALYTICS_BASE_URL=http://localhost:8080/analytics
REACT_APP_SERVICES_BASE_URL=http://localhost:8080/services
REACT_APP_SETTINGS_BASE_URL=http://localhost:8080/settings
REACT_APP_MONITORING_BASE_URL=http://localhost:8080/monitoring
REACT_APP_SERVICE_DMAPPER=http://data-mapper:3005
REACT_APP_SERVICE_ID=services
REACT_APP_RUUTER_API_URL=http://localhost:8086
REACT_APP_CSP=upgrade-insecure-requests; default-src 'self'; font-src 'self' data:; img-src 'self' data:; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; object-src 'none'; connect-src 'self' http://localhost:8086 http://localhost:8085 https://admin.dev.buerokratt.ee/chat/menu.json;
Expand Down
5 changes: 3 additions & 2 deletions GUI/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"i18next-browser-languagedetector": "^7.0.1",
"moment": "^2.29.4",
"msw": "^0.49.2",
"node-html-markdown": "^1.3.0",
"overlayscrollbars": "^1.13.1",
"overlayscrollbars-react": "^0.2.3",
"radix-ui": "^1.0.1",
Expand Down Expand Up @@ -83,11 +84,11 @@
"@types/to-json-schema": "^0.2.1",
"@types/uuid": "^9.0.1",
"@vitejs/plugin-react": "^3.0.0",
"react-scripts": "^5.0.1",
"vite": "^4.0.0",
"vite-plugin-env-compatible": "^1.1.1",
"vite-plugin-svgr": "^2.4.0",
"vite-tsconfig-paths": "^4.0.3",
"react-scripts": "^5.0.1"
"vite-tsconfig-paths": "^4.0.3"
},
"msw": {
"workerDirectory": "public"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { v4 as uuidv4 } from 'uuid';

export interface ElementGroupBuilderProps {
assignElements?: Assign[];
onRemove?: (id: string) => void;
onChange: (config: any) => void;
seedGroup?: any;
}

export interface Assign {
id: string;
key: string;
value: string;
}

export const getInitialElement = () => {
return {
id: uuidv4(),
key: '',
value: '',
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { FormInput, Icon, Track } from 'components';
import { MdDeleteOutline } from 'react-icons/md';
import { Assign } from "./assign-types";

interface AssignElementProps {
element: Assign;
onRemove: (id: string) => void;
onChange: (element: Assign) => void;
}

const AssignElement: React.FC<AssignElementProps> = ({ element, onRemove, onChange }) => {

const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
change(e.target.name, e.target.value);
}

const change = (name: string, value?: string) => {
onChange({ ...element, [name]: value });
}

return (
<Track gap={16} isFlex>
<Track gap={16} isFlex>
<FormInput value={element.key} name="key" onChange={handleChange} label="" hideLabel />
:
<FormInput value={element.value} name="value" onChange={handleChange} label="" hideLabel />
</Track>
<button onClick={() => onRemove(element.id)} className="small-assign-button assign-red">
<Icon icon={<MdDeleteOutline />} />
</button>
</Track>
);
}

export default AssignElement;
39 changes: 39 additions & 0 deletions GUI/src/components/FlowElementsPopup/AssignBuilder/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Track } from 'components';
import { ElementGroupBuilderProps } from "./assign-types";
import AssignElement from "./assignElement";
import { useAssignBuilder } from './useAssignBuilder';
import '../styles.scss';

const AssignBuilder: React.FC<ElementGroupBuilderProps> = ({ assignElements, onRemove, onChange, seedGroup }) => {
const { t } = useTranslation();
const {
elements,
addElement,
remove,
changeElement,
} = useAssignBuilder({
assignElements,
root: !onRemove,
onChange,
seedGroup,
});

return (
<Track gap={16} direction="vertical" align="stretch" className="assign-action-container">
<Track justify="end">
<Track gap={8}>
<button className="small-assign-button assign-blue" onClick={addElement}>
{t("serviceFlow.popup.addElement")}
</button>
</Track>
</Track>
{elements?.map((element) => (
<AssignElement key={element.id} element={element} onRemove={remove} onChange={changeElement} />
))}
</Track>
);
};

export default AssignBuilder;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useEffect, useState } from "react";
import { Assign, getInitialElement } from "./assign-types";

interface UseAssignBuilderProps {
assignElements?: Assign[];
root?: boolean;
onChange: (group: Assign[]) => void;
seedGroup?: any;
}

export const useAssignBuilder = (config: UseAssignBuilderProps) => {
const elementsInitialValue = config.root ? config.seedGroup ?? [] : config.assignElements!;
const [elements, setElements] = useState<Assign[]>(elementsInitialValue ?? []);

useEffect(() => {
config.onChange(elements)
}, [elements]);

const addElement = () => {
setElements([...elements, getInitialElement()]);
}

const remove = (id: string) => {
setElements(elements.filter(x => x.id !== id));
}

const changeElement = (element: Assign) => setElementById(element.id, element);

const setElementById = (id: string, element: Assign) => {
const newElements = elements.map((x) => (x.id === id ? { ...element } : x));
setElements(newElements);
};

return {
elements,
addElement,
remove,
changeElement,
};
}
23 changes: 23 additions & 0 deletions GUI/src/components/FlowElementsPopup/AssignContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FC } from "react";
import Track from "../Track";
import useServiceStore from "store/new-services.store";
import PreviousVariables from "./PreviousVariables";
import AssignBuilder from "./AssignBuilder";

type AssignContentProps = {
readonly nodeId: string;
};

const AssignContent: FC<AssignContentProps> = ({ nodeId }) => {
const nodes = useServiceStore((state) => state.nodes);
const currentNodeElements = nodes.find((node) => node.id === nodeId)?.data?.assignElements ?? [];

return (
<Track direction="vertical" align="stretch">
<AssignBuilder onChange={useServiceStore.getState().changeAssignNode} seedGroup={currentNodeElements} />
<PreviousVariables nodeId={nodeId} />
</Track>
);
};

export default AssignContent;
2 changes: 1 addition & 1 deletion GUI/src/components/FlowElementsPopup/ConditionContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useState } from "react";
import { FC } from "react";
import Track from "../Track";
import RuleBuilder from "./RuleBuilder";
import useServiceStore from "store/new-services.store";
Expand Down
51 changes: 49 additions & 2 deletions GUI/src/components/FlowElementsPopup/PreviousVariables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,42 @@ import Track from "../Track";
import useServiceStore from "store/new-services.store";
import { endpointResponseVariables } from "types/endpoint/endpoint-response-variables";
import OutputElementBox from "components/OutputElementBox";
import { StepType } from "types";
import { Assign } from "./AssignBuilder/assign-types";
import { useTranslation } from "react-i18next";

type PreviousVariablesProps = {
readonly nodeId: string;
};

const PreviousVariables: FC<PreviousVariablesProps> = ({ nodeId }) => {
const { t } = useTranslation();
let endpointsVariables = useServiceStore((state) => state.endpointsResponseVariables);
const nodes = useServiceStore((state) => state.nodes);
const [endpoints, setEndpoints] = useState<endpointResponseVariables[]>([]);
const [assignedVariables, setAssignedVariables] = useState<Assign[]>([]);

useEffect(() => {
const previousNodes = nodes.slice(
0,
nodes.findIndex((node) => node.id === nodeId)
);
const endpointNodes = previousNodes.filter((node) => node.data.stepType === "user-defined");

// Get Endpoints variables
const endpointNodes = previousNodes.filter((node) => node.data.stepType === StepType.UserDefined);
const names = endpointNodes.map((node) => node.data.label);
endpointsVariables = endpointsVariables.filter((endpoint) => names.includes(endpoint.name));
setEndpoints(endpointsVariables);

// Get Assign variables
const assignNodes = previousNodes.filter((node) => node.data.stepType === StepType.Assign);
const assignElements = assignNodes.map((node) => node.data.assignElements).flat();
const inputElement: Assign = {
id: "-1",
key: "input",
value: "${incoming.body.input}",
};
setAssignedVariables([...assignElements, inputElement]);
}, [endpointsVariables]);

const popupBodyCss: CSSProperties = {
Expand All @@ -31,8 +48,38 @@ const PreviousVariables: FC<PreviousVariablesProps> = ({ nodeId }) => {

return (
<Track direction="vertical" align="stretch">
{assignedVariables.length > 0 && (
<Track direction="vertical" align="left" style={{ width: "100%", ...popupBodyCss, backgroundColor: "#F9F9F9" }}>
<label
htmlFor="json"
style={{ marginBottom: "10px", textTransform: "capitalize", cursor: "auto" }}
>{t('serviceFlow.previousVariables.assignElements')}</label>
<Track
direction="horizontal"
gap={4}
justify="start"
isMultiline
style={{ maxHeight: "30vh", overflow: "auto" }}
>
{assignedVariables.map((assign) => (
<OutputElementBox
key={assign.id}
text={assign.key}
draggable={true}
value={`\${${assign.key}}`}
useValue
></OutputElementBox>
))}
</Track>
</Track>
)}
{endpoints.map((endpoint) => (
<Track key={endpoint.name} direction="vertical" align="left" style={{ width: "100%", ...popupBodyCss, backgroundColor: "#F9F9F9" }}>
<Track
key={endpoint.name}
direction="vertical"
align="left"
style={{ width: "100%", ...popupBodyCss, backgroundColor: "#F9F9F9" }}
>
<label
htmlFor="json"
style={{ marginBottom: "10px", textTransform: "capitalize", cursor: "auto" }}
Expand Down
18 changes: 18 additions & 0 deletions GUI/src/components/FlowElementsPopup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import useServiceStore from "store/new-services.store";
import FileSignContent from "./FileSignContent";
import "./styles.scss";
import ConditionContent from "./ConditionContent";
import AssignContent from "./AssignContent";

const FlowElementsPopup: React.FC = () => {
const { t } = useTranslation();
Expand All @@ -34,11 +35,16 @@ const FlowElementsPopup: React.FC = () => {

const endpoints = useServiceStore((state) => state.endpoints);
const rules = useServiceStore((state) => state.rules);
const assignElements = useServiceStore((state) => state.assignElements);

useEffect(() => {
if (node) node.data.rules = rules;
}, [rules]);

useEffect(() => {
if (node) node.data.assignElements = assignElements;
}, [assignElements]);

// StepType.Textfield
const [textfieldMessage, setTextfieldMessage] = useState<string | null>(null);
const [textfieldMessagePlaceholders, setTextfieldMessagePlaceholders] = useState<{ [key: string]: string }>({});
Expand All @@ -60,6 +66,13 @@ const FlowElementsPopup: React.FC = () => {
useServiceStore.getState().changeRulesNode(node.data.rules);
}, [stepType === StepType.Input, stepType === StepType.Condition]);

useEffect(() => {
if (stepType !== StepType.Assign) return;
if (!node?.data?.assignElements) return;

useServiceStore.getState().changeAssignNode(node.data.assignElements);
}, [stepType === StepType.Assign]);

if (!node) return <></>;

const title = node.data.label;
Expand Down Expand Up @@ -97,6 +110,10 @@ const FlowElementsPopup: React.FC = () => {
updatedNode.data.rules = rules;
}

if (stepType === StepType.Assign) {
updatedNode.data.assignElements = assignElements;
}

useServiceStore.getState().handlePopupSave(updatedNode);
onClose();
};
Expand Down Expand Up @@ -218,6 +235,7 @@ const FlowElementsPopup: React.FC = () => {
{stepType === StepType.FileSign && <FileSignContent onOptionChange={setSignOption} signOption={signOption} />}
{stepType === StepType.FinishingStepEnd && <EndConversationContent />}
{stepType === StepType.RasaRules && <RasaRulesContent />}
{stepType === StepType.Assign && <AssignContent nodeId={node.id} />}
{stepType === StepType.Condition && <ConditionContent nodeId={node.id}/>}
<JsonRequestContent isVisible={isJsonRequestVisible} jsonContent={jsonRequestContent} />
</Tabs.Content>
Expand Down
28 changes: 28 additions & 0 deletions GUI/src/components/FlowElementsPopup/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,31 @@ div>.small-rule-group-button:last-child {
.rule-gray:hover {
background: #0002;
}

.assign-action-container {
padding: 10px;
background: rgba(25, 0, 255, 0.067);
border: 1px solid rgba(25, 0, 255, 0.067);
}

.small-assign-button {
padding: 4px 10px;
margin: 4px;
border-radius: 10px;
}

.assign-blue {
background: #00f5;
}

.assign-blue:hover {
background: #00f6;
}

.assign-red {
background: #f007;
}

.assign-red:hover {
background: #f008;
}
Loading