Fixed positioning of tableNodeCellRender elements

This commit is contained in:
Lucas Oliveira 2024-06-05 13:52:22 -03:00
commit cf3477b04b
3 changed files with 171 additions and 213 deletions

View file

@ -1,4 +1,4 @@
import { CustomCellRendererProps } from "ag-grid-react"; import { CustomCellEditorProps, CustomCellRendererProps } from "ag-grid-react";
import { classNames, cn, isTimeStampString } from "../../utils/utils"; import { classNames, cn, isTimeStampString } from "../../utils/utils";
import ArrayReader from "../arrayReaderComponent"; import ArrayReader from "../arrayReaderComponent";
import DateReader from "../dateReaderComponent"; import DateReader from "../dateReaderComponent";
@ -30,21 +30,27 @@ import { useState } from "react";
import useFlowStore from "../../stores/flowStore"; import useFlowStore from "../../stores/flowStore";
export default function TableNodeCellRender({ export default function TableNodeCellRender({
node: { data: templateData }, node: { data },
value: { value: {
value: templateValue, value,
nodeClass, nodeClass,
handleOnNewValue, handleOnNewValue: handleOnNewValueNode,
handleOnChangeDb, handleOnChangeDb,
}, },
}: CustomCellRendererProps) { }: CustomCellRendererProps) {
console.log( const handleOnNewValue = (newValue: any, name: string) => {
templateData, handleOnNewValueNode(newValue, name);
templateValue, setTemplateData((old) => {
nodeClass, let newData = cloneDeep(old);
handleOnNewValue, newData.value = newValue;
handleOnChangeDb, return newData;
); });
setTemplateValue(newValue);
};
const [templateValue, setTemplateValue] = useState(value);
const [templateData, setTemplateData] = useState(data);
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
const edges = useFlowStore((state) => state.edges); const edges = useFlowStore((state) => state.edges);
@ -71,79 +77,65 @@ export default function TableNodeCellRender({
switch (templateData.type) { switch (templateData.type) {
case "str": case "str":
if (!templateData.options) { if (!templateData.options) {
return ( return templateData?.list ? (
<div className="w-[300px]"> <InputListComponent
{templateData?.list ? ( componentName={templateData.key ?? undefined}
<InputListComponent editNode={true}
componentName={templateData.key ?? undefined} disabled={disabled}
editNode={true} value={
disabled={disabled} !templateValue || templateValue === "" ? [""] : templateValue
value={ }
!templateValue || templateValue === "" onChange={(value: string[]) => {
? [""] handleOnNewValue(value, templateData.key);
: templateValue }}
} />
onChange={(value: string[]) => { ) : templateData.multiline ? (
handleOnNewValue(value, templateData.key); <TextAreaComponent
}} id={"textarea-edit-" + templateData.name}
/> data-testid={"textarea-edit-" + templateData.name}
) : templateData.multiline ? ( disabled={disabled}
<TextAreaComponent editNode={true}
id={"textarea-edit-" + templateData.name} value={templateValue ?? ""}
data-testid={"textarea-edit-" + templateData.name} onChange={(value: string | string[]) => {
disabled={disabled} handleOnNewValue(value, templateData.key);
editNode={true} }}
value={templateData.value ?? ""} />
onChange={(value: string | string[]) => { ) : (
handleOnNewValue(value, templateData.key); <InputGlobalComponent
}} disabled={disabled}
/> editNode={true}
) : ( onChange={(value) => handleOnNewValue(value, templateData.key)}
<InputGlobalComponent setDb={(value) => {
disabled={disabled} handleOnChangeDb(value, templateData.key);
editNode={true} }}
onChange={(value) => name={templateData.key}
handleOnNewValue(value, templateData.key) data={templateData}
} />
setDb={(value) => {
handleOnChangeDb(value, templateData.key);
}}
name={templateData.key}
data={templateData}
/>
)}
</div>
); );
} else { } else {
return ( return (
<div className="w-[300px]"> <Dropdown
<Dropdown editNode={true}
editNode={true} options={templateData.options}
options={templateData.options} onSelect={(value) => handleOnNewValue(value, templateData.key)}
onSelect={(value) => handleOnNewValue(value, templateData.key)} value={templateValue ?? "Choose an option"}
value={templateData.value ?? "Choose an option"} id={"dropdown-edit-" + templateData.name}
id={"dropdown-edit-" + templateData.name} ></Dropdown>
></Dropdown>
</div>
); );
} }
case "NestedDict": case "NestedDict":
return ( return (
<div className=" w-full"> <DictComponent
<DictComponent disabled={disabled}
disabled={disabled} editNode={true}
editNode={true} value={templateValue.toString() === "{}" ? {} : templateValue}
value={templateValue.toString() === "{}" ? {} : templateValue} onChange={(newValue) => {
onChange={(newValue) => { handleOnNewValue(newValue, templateData.key);
templateValue = newValue; }}
handleOnNewValue(newValue, templateData.key); id="editnode-div-dict-input"
}} />
id="editnode-div-dict-input"
/>
</div>
); );
break;
case "dict": case "dict":
return ( return (
@ -157,14 +149,13 @@ export default function TableNodeCellRender({
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={ value={
templateData.value?.length === 0 || !templateData.value templateValue?.length === 0 || !templateValue
? [{ "": "" }] ? [{ "": "" }]
: convertObjToArray(templateValue, templateData.type) : convertObjToArray(templateValue, templateData.type)
} }
duplicateKey={errorDuplicateKey} duplicateKey={errorDuplicateKey}
onChange={(newValue) => { onChange={(newValue) => {
const valueToNumbers = convertValuesToNumbers(newValue); const valueToNumbers = convertValuesToNumbers(newValue);
templateValue = valueToNumbers;
setErrorDuplicateKey(hasDuplicateKeys(valueToNumbers)); setErrorDuplicateKey(hasDuplicateKeys(valueToNumbers));
handleOnNewValue(valueToNumbers, templateData.key); handleOnNewValue(valueToNumbers, templateData.key);
}} }}
@ -172,128 +163,110 @@ export default function TableNodeCellRender({
/> />
</div> </div>
); );
break;
case "bool": case "bool":
return ( return (
<div className="ml-auto"> <ToggleShadComponent
{" "} id={"toggle-edit-" + templateData.name}
<ToggleShadComponent disabled={disabled}
id={"toggle-edit-" + templateData.name} enabled={templateValue}
disabled={disabled} setEnabled={(isEnabled) => {
enabled={templateData.value} handleOnNewValue(isEnabled, templateData.key);
setEnabled={(isEnabled) => { }}
handleOnNewValue(isEnabled, templateData.key); size="small"
}} editNode={true}
size="small" />
editNode={true}
/>
</div>
); );
case "float": case "float":
return ( return (
<div className="w-[300px]"> <FloatComponent
<FloatComponent disabled={disabled}
disabled={disabled} editNode={true}
editNode={true} rangeSpec={templateData.rangeSpec}
rangeSpec={templateData.rangeSpec} value={templateValue ?? ""}
value={templateData.value ?? ""} onChange={(value) => {
onChange={(value) => { handleOnNewValue(value, templateData.key);
handleOnNewValue(value, templateData.key); }}
}} />
/>
</div>
); );
case "int": case "int":
return ( return (
<div className="w-[300px]"> <IntComponent
<IntComponent rangeSpec={templateData.rangeSpec}
rangeSpec={templateData.rangeSpec} id={"edit-int-input-" + templateData.name}
id={"edit-int-input-" + templateData.name} disabled={disabled}
disabled={disabled} editNode={true}
editNode={true} value={templateValue ?? ""}
value={templateData.value ?? ""} onChange={(value) => {
onChange={(value) => { handleOnNewValue(value, templateData.key);
handleOnNewValue(value, templateData.key); }}
}} />
/>
</div>
); );
break;
case "file": case "file":
return ( return (
<div className="w-[300px]"> <InputFileComponent
<InputFileComponent editNode={true}
editNode={true} disabled={disabled}
disabled={disabled} value={templateValue ?? ""}
value={templateData.value ?? ""} onChange={(value: string | string[]) => {
onChange={(value: string | string[]) => { handleOnNewValue(value, templateData.key);
handleOnNewValue(value, templateData.key); }}
}} fileTypes={templateData.fileTypes}
fileTypes={templateData.fileTypes} onFileChange={(filePath: string) => {
onFileChange={(filePath: string) => { templateData.file_path = filePath;
templateData.file_path = filePath; }}
}} />
></InputFileComponent>
</div>
); );
case "prompt": case "prompt":
return ( return (
<div className="w-[300px]"> <PromptAreaComponent
<PromptAreaComponent readonly={nodeClass.flow ? true : false}
readonly={nodeClass.flow ? true : false} field_name={templateData.key}
field_name={templateData.key} editNode={true}
editNode={true} disabled={disabled}
disabled={disabled} nodeClass={nodeClass}
nodeClass={nodeClass} setNodeClass={(value) => {
setNodeClass={(value) => { nodeClass = value;
nodeClass = value; }}
}} value={templateValue ?? ""}
value={templateValue ?? ""} onChange={(value: string | string[]) => {
onChange={(value: string | string[]) => { handleOnNewValue(value, templateData.key);
handleOnNewValue(value, templateData.key); }}
}} id={"prompt-area-edit-" + templateData.name}
id={"prompt-area-edit-" + templateData.name} data-testid={"modal-prompt-input-" + templateData.name}
data-testid={"modal-prompt-input-" + templateData.name} />
/>
</div>
); );
break;
case "code": case "code":
return ( return (
<div className="w-[300px]"> <CodeAreaComponent
<CodeAreaComponent readonly={nodeClass.flow && templateData.dynamic ? true : false}
readonly={nodeClass.flow && templateData.dynamic ? true : false} dynamic={templateData.dynamic ?? false}
dynamic={templateData.dynamic ?? false} setNodeClass={(value) => {
setNodeClass={(value) => { nodeClass = value;
nodeClass = value; }}
}} nodeClass={nodeClass}
nodeClass={nodeClass} disabled={disabled}
disabled={disabled} editNode={true}
editNode={true} value={templateValue ?? ""}
value={templateData.value ?? ""} onChange={(value: string | string[]) => {
onChange={(value: string | string[]) => { handleOnNewValue(value, templateData.key);
handleOnNewValue(value, templateData.key); }}
}} id={"code-area-edit" + templateData.name}
id={"code-area-edit" + templateData.name} />
/>
</div>
); );
break;
case "Any": case "Any":
return <>-</>; return <>-</>;
break;
default: default:
return String(templateValue); return String(templateValue);
} }
} }
return ( return (
<div className="group flex h-full w-full items-center align-middle"> <div className="group flex h-full w-[300px] items-center justify-center">
{getCellType()} {getCellType()}
</div> </div>
); );

View file

@ -29,20 +29,18 @@ export default function ToggleShadComponent({
} }
return ( return (
<div className={disabled ? "pointer-events-none cursor-not-allowed " : ""}> <Switch
<Switch id={id}
id={id} data-testid={id}
data-testid={id} style={{
style={{ transform: `scaleX(${scaleX}) scaleY(${scaleY})`,
transform: `scaleX(${scaleX}) scaleY(${scaleY})`, }}
}} disabled={disabled}
disabled={disabled} className=""
className="" checked={enabled}
checked={enabled} onCheckedChange={(isEnabled: boolean) => {
onCheckedChange={(isEnabled: boolean) => { setEnabled(isEnabled);
setEnabled(isEnabled); }}
}} ></Switch>
></Switch>
</div>
); );
} }

View file

@ -1,5 +1,5 @@
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { forwardRef, useEffect, useState } from "react"; import { forwardRef, useEffect, useRef, useState } from "react";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import { Badge } from "../../components/ui/badge"; import { Badge } from "../../components/ui/badge";
import { import {
@ -35,36 +35,28 @@ const EditNodeModal = forwardRef(
const dataFromStore = nodes.find((node) => node.id === node.id)?.data; const dataFromStore = nodes.find((node) => node.id === node.id)?.data;
const [myData, setMyData] = useState(dataFromStore ?? data); const myData = useRef(dataFromStore ?? data);
const setNode = useFlowStore((state) => state.setNode); const setNode = useFlowStore((state) => state.setNode);
function changeAdvanced(n) { function changeAdvanced(n) {
setMyData((old) => { myData.current.node!.template[n].advanced =
let newData = cloneDeep(old); !myData.current.node!.template[n].advanced;
newData.node!.template[n].advanced =
!newData.node!.template[n].advanced;
return newData;
});
} }
const handleOnNewValue = (newValue: any, name) => { const handleOnNewValue = (newValue: any, name) => {
setMyData((old) => { myData.current.node!.template[name].value = newValue;
let newData = cloneDeep(old);
newData.node!.template[name].value = newValue;
return newData;
});
}; };
useEffect(() => { useEffect(() => {
if (open) { if (open) {
setMyData(data); // reset data to what it is on node when opening modal myData.current = data; // reset data to what it is on node when opening modal
} }
}, [open]); }, [open]);
const rowData = Object.keys(myData.node!.template) const rowData = Object.keys(myData.current.node!.template)
.filter((key: string) => { .filter((key: string) => {
const templateParam = myData.node!.template[ const templateParam = myData.current.node!.template[
key key
] as TemplateVariableType; ] as TemplateVariableType;
return ( return (
@ -78,7 +70,7 @@ const EditNodeModal = forwardRef(
); );
}) })
.map((key: string) => { .map((key: string) => {
const templateParam = myData.node!.template[ const templateParam = myData.current.node!.template[
key key
] as TemplateVariableType; ] as TemplateVariableType;
return { return {
@ -115,21 +107,16 @@ const EditNodeModal = forwardRef(
field: "value", field: "value",
cellRenderer: TableNodeCellRender, cellRenderer: TableNodeCellRender,
valueGetter: (params: ValueGetterParams) => { valueGetter: (params: ValueGetterParams) => {
console.log("params", params);
return { return {
value: params.data.value, value: params.data.value,
nodeClass: myData.node, nodeClass: myData.current.node,
handleOnNewValue: handleOnNewValue, handleOnNewValue: handleOnNewValue,
handleOnChangeDb: (value, key) => { handleOnChangeDb: (value, key) => {
setMyData((oldData) => { myData.current.node!.template[key].load_from_db = value;
let newData = cloneDeep(oldData);
newData.node!.template[key].load_from_db = value;
return newData;
});
}, },
}; };
}, },
minWidth: 300, minWidth: 330,
flex: 1, flex: 1,
resizable: false, resizable: false,
}, },
@ -159,14 +146,14 @@ const EditNodeModal = forwardRef(
open={open} open={open}
setOpen={setOpen} setOpen={setOpen}
onChangeOpenModal={(open) => { onChangeOpenModal={(open) => {
setMyData(data); myData.current = data;
}} }}
onSubmit={() => { onSubmit={() => {
setNode(data.id, (old) => ({ setNode(data.id, (old) => ({
...old, ...old,
data: { data: {
...old.data, ...old.data,
node: myData.node, node: myData.current.node,
}, },
})); }));
setOpen(false); setOpen(false);
@ -175,9 +162,9 @@ const EditNodeModal = forwardRef(
<BaseModal.Trigger> <BaseModal.Trigger>
<></> <></>
</BaseModal.Trigger> </BaseModal.Trigger>
<BaseModal.Header description={myData.node?.description!}> <BaseModal.Header description={myData.current.node?.description!}>
<span className="pr-2">{myData.type}</span> <span className="pr-2">{myData.current.type}</span>
<Badge variant="secondary">ID: {myData.id}</Badge> <Badge variant="secondary">ID: {myData.current.id}</Badge>
</BaseModal.Header> </BaseModal.Header>
<BaseModal.Content> <BaseModal.Content>
<div className="flex pb-2"> <div className="flex pb-2">