Merge branch 'cz/code-node-toolbar' into zustand/io/migration

This commit is contained in:
cristhianzl 2024-02-08 17:51:35 -03:00
commit e4aa1d12bb
6 changed files with 101 additions and 5 deletions

View file

@ -304,7 +304,10 @@ export default function ParameterComponent({
) : ( ) : (
<div <div
ref={ref} ref={ref}
className="relative mt-1 flex w-full flex-wrap items-center justify-between bg-muted px-5 py-2" className={
"relative mt-1 flex w-full flex-wrap items-center justify-between bg-muted px-5 py-2" +
(type === "code" ? " hidden " : "")
}
> >
<> <>
<div <div
@ -456,7 +459,7 @@ export default function ParameterComponent({
)} )}
</div> </div>
) : left === true && type === "code" ? ( ) : left === true && type === "code" ? (
<div className="mt-2 w-full"> <div className="mt-2 hidden w-full">
<CodeAreaComponent <CodeAreaComponent
readonly={ readonly={
data.node?.flow && data.node.template[name].dynamic data.node?.flow && data.node.template[name].dynamic

View file

@ -14,6 +14,7 @@ export default function CodeAreaComponent({
setNodeClass, setNodeClass,
id = "", id = "",
readonly = false, readonly = false,
openModal,
}: CodeAreaComponentType) { }: CodeAreaComponentType) {
const [myValue, setMyValue] = useState( const [myValue, setMyValue] = useState(
typeof value == "string" ? value : JSON.stringify(value) typeof value == "string" ? value : JSON.stringify(value)
@ -32,6 +33,7 @@ export default function CodeAreaComponent({
return ( return (
<div className={disabled ? "pointer-events-none w-full " : " w-full"}> <div className={disabled ? "pointer-events-none w-full " : " w-full"}>
<CodeAreaModal <CodeAreaModal
openModal={openModal}
readonly={readonly} readonly={readonly}
dynamic={dynamic} dynamic={dynamic}
value={myValue} value={myValue}

View file

@ -24,6 +24,7 @@ export default function CodeAreaModal({
children, children,
dynamic, dynamic,
readonly = false, readonly = false,
openModal,
}: codeAreaModalPropsType): JSX.Element { }: codeAreaModalPropsType): JSX.Element {
const [code, setCode] = useState(value); const [code, setCode] = useState(value);
const dark = useDarkStore((state) => state.dark); const dark = useDarkStore((state) => state.dark);
@ -43,6 +44,10 @@ export default function CodeAreaModal({
} }
}, []); }, []);
useEffect(() => {
if (openModal) setOpen(true);
}, [openModal]);
function processNonDynamicField() { function processNonDynamicField() {
postValidateCode(code) postValidateCode(code)
.then((apiReturn) => { .then((apiReturn) => {

View file

@ -1,6 +1,7 @@
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import ShadTooltip from "../../../../components/ShadTooltipComponent"; import ShadTooltip from "../../../../components/ShadTooltipComponent";
import CodeAreaComponent from "../../../../components/codeAreaComponent";
import IconComponent from "../../../../components/genericIconComponent"; import IconComponent from "../../../../components/genericIconComponent";
import { import {
Select, Select,
@ -15,6 +16,7 @@ import { useDarkStore } from "../../../../stores/darkStore";
import useFlowStore from "../../../../stores/flowStore"; import useFlowStore from "../../../../stores/flowStore";
import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
import { useStoreStore } from "../../../../stores/storeStore"; import { useStoreStore } from "../../../../stores/storeStore";
import { APIClassType } from "../../../../types/api";
import { nodeToolbarPropsType } from "../../../../types/components"; import { nodeToolbarPropsType } from "../../../../types/components";
import { FlowType } from "../../../../types/flow"; import { FlowType } from "../../../../types/flow";
import { import {
@ -32,6 +34,7 @@ export default function NodeToolbarComponent({
setShowNode, setShowNode,
numberOfHandles, numberOfHandles,
showNode, showNode,
name = "code",
}: nodeToolbarPropsType): JSX.Element { }: nodeToolbarPropsType): JSX.Element {
const nodeLength = Object.keys(data.node!.template).filter( const nodeLength = Object.keys(data.node!.template).filter(
(templateField) => (templateField) =>
@ -123,6 +126,9 @@ export default function NodeToolbarComponent({
case "override": case "override":
setShowOverrideModal(true); setShowOverrideModal(true);
break; break;
case "delete":
deleteNode(data.id);
break;
} }
}; };
@ -130,19 +136,84 @@ export default function NodeToolbarComponent({
Object.values(flow).includes(data.node?.display_name!) Object.values(flow).includes(data.node?.display_name!)
); );
const setNode = useFlowStore((state) => state.setNode);
const handleOnNewValue = (
newValue: string | string[] | boolean | Object[]
): void => {
if (data.node!.template[name].value !== newValue) {
takeSnapshot();
}
data.node!.template[name].value = newValue; // necessary to enable ctrl+z inside the input
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
};
newNode.data.node.template[name].value = newValue;
return newNode;
});
};
const handleNodeClass = (newNodeClass: APIClassType, code?: string): void => {
if (!data.node) return;
if (data.node!.template[name].value !== code) {
takeSnapshot();
}
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
node: newNodeClass,
description: newNodeClass.description ?? data.node!.description,
display_name: newNodeClass.display_name ?? data.node!.display_name,
};
newNode.data.node.template[name].value = code;
return newNode;
});
};
const [openModal, setOpenModal] = useState(false);
return ( return (
<> <>
<div className="w-26 h-10"> <div className="w-26 h-10">
<span className="isolate inline-flex rounded-md shadow-sm"> <span className="isolate inline-flex rounded-md shadow-sm">
<ShadTooltip content="Delete" side="top"> <ShadTooltip content="Code" side="top">
<button <button
className="relative inline-flex items-center rounded-l-md bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10" className="relative inline-flex items-center rounded-l-md bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
onClick={() => { onClick={() => {
deleteNode(data.id); setOpenModal(!openModal);
}} }}
data-testid="delete-button-modal" data-testid="delete-button-modal"
> >
<IconComponent name="Trash2" className="h-4 w-4" /> <div className="hidden">
<CodeAreaComponent
openModal={openModal}
readonly={
data.node?.flow && data.node.template[name].dynamic
? true
: false
}
dynamic={data.node?.template[name].dynamic ?? false}
setNodeClass={handleNodeClass}
nodeClass={data.node}
disabled={false}
value={data.node?.template[name].value ?? ""}
onChange={handleOnNewValue}
id={"code-input-node-toolbar-" + name}
/>
</div>
<IconComponent name="Code2" className="h-4 w-4" />
</button> </button>
</ShadTooltip> </ShadTooltip>
@ -288,6 +359,16 @@ export default function NodeToolbarComponent({
</div> </div>
</SelectItem> </SelectItem>
)} )}
<SelectItem value={"delete"}>
<div className="font-red flex text-red-500 hover:text-red-500">
<IconComponent
name="Trash2"
className="relative top-0.5 mr-2 h-4 w-4 "
/>{" "}
Delete{" "}
</div>
</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>

View file

@ -112,6 +112,7 @@ export type CodeAreaComponentType = {
dynamic?: boolean; dynamic?: boolean;
id?: string; id?: string;
readonly?: boolean; readonly?: boolean;
openModal?: boolean;
}; };
export type FileComponentType = { export type FileComponentType = {
@ -480,6 +481,7 @@ export type nodeToolbarPropsType = {
setShowNode: (boolean: any) => void; setShowNode: (boolean: any) => void;
numberOfHandles: number; numberOfHandles: number;
showNode: boolean; showNode: boolean;
name?: string;
}; };
export type parsedDataType = { export type parsedDataType = {
@ -513,6 +515,7 @@ export type codeAreaModalPropsType = {
children: ReactNode; children: ReactNode;
dynamic?: boolean; dynamic?: boolean;
readonly?: boolean; readonly?: boolean;
openModal?: boolean;
}; };
export type chatMessagePropsType = { export type chatMessagePropsType = {

View file

@ -16,6 +16,7 @@ import {
ChevronsUpDown, ChevronsUpDown,
Circle, Circle,
Clipboard, Clipboard,
Code,
Code2, Code2,
Combine, Combine,
Compass, Compass,
@ -395,4 +396,5 @@ export const nodeIconsLucide: iconsType = {
Repeat, Repeat,
io: ArrowDownUp, io: ArrowDownUp,
ScreenShare, ScreenShare,
Code,
}; };