🐛 fix(parameterComponent): import missing utility functions from reactflowUtils to fix error

✨ feat(parameterComponent): add error handling for duplicate keys in dictionary input field to prevent saving invalid data
🐛 fix(keypairListComponent): fix logic for handling duplicate keys in key-value pairs to prevent saving invalid data
🚚 chore(types): add optional duplicateKey property to KeyPairListComponent type
✨ feat(reactflowUtils): add utility functions to convert object to array and array to object, and check for duplicate keys in an array of objects
This commit is contained in:
Cristhian Zanforlin Lousa 2023-08-31 10:27:04 -03:00
commit 2b2c677f7c
4 changed files with 57 additions and 37 deletions

View file

@ -25,7 +25,7 @@ import { TabsContext } from "../../../../contexts/tabsContext";
import { typesContext } from "../../../../contexts/typesContext"; import { typesContext } from "../../../../contexts/typesContext";
import { ParameterComponentType } from "../../../../types/components"; import { ParameterComponentType } from "../../../../types/components";
import { TabsState } from "../../../../types/tabs"; import { TabsState } from "../../../../types/tabs";
import { isValidConnection } from "../../../../utils/reactflowUtils"; import { convertArrayToObj, convertObjToArray, hasDuplicateKeys, isValidConnection } from "../../../../utils/reactflowUtils";
import { import {
nodeColors, nodeColors,
nodeIconsLucide, nodeIconsLucide,
@ -53,6 +53,7 @@ export default function ParameterComponent({
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const [position, setPosition] = useState(0); const [position, setPosition] = useState(0);
const { setTabsState, tabId, save, flows } = useContext(TabsContext); const { setTabsState, tabId, save, flows } = useContext(TabsContext);
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
const flow = flows.find((flow) => flow.id === tabId)?.data?.nodes ?? null; const flow = flows.find((flow) => flow.id === tabId)?.data?.nodes ?? null;
@ -105,34 +106,9 @@ export default function ParameterComponent({
const [dictArr, setDictArr] = useState([]); const [dictArr, setDictArr] = useState([]);
useEffect(() => { useEffect(() => {
convertToArray(dict); setDictArr(convertObjToArray(dict));
}, [dict]); }, [dict]);
const convertToArray = (singleObject) => {
let arrConverted: any = [];
for (const key in singleObject) {
if (singleObject.hasOwnProperty(key)) {
const newObj = {};
newObj[key] = singleObject[key];
arrConverted.push(newObj);
}
}
setDictArr(arrConverted);
};
const convertToDict = (newValue): void => {
const flattenedObject = {};
for (const obj of newValue) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
flattenedObject[key] = obj[key];
}
}
}
let newData = cloneDeep(flattenedObject);
setDict(newData);
};
useEffect(() => { useEffect(() => {
if (name === "openai_api_base") console.log(info); if (name === "openai_api_base") console.log(info);
// @ts-ignore // @ts-ignore
@ -254,7 +230,12 @@ export default function ParameterComponent({
disabled={disabled} disabled={disabled}
editNode={false} editNode={false}
value={dictArr} value={dictArr}
onChange={convertToDict} duplicateKey={errorDuplicateKey}
onChange={(newValue) => {
setErrorDuplicateKey(hasDuplicateKeys(newValue));
if(hasDuplicateKeys(newValue)) return;
setDict(convertArrayToObj(newValue));
}}
/> />
</div> </div>
) : ( ) : (

View file

@ -13,6 +13,7 @@ export default function KeypairListComponent({
onChange, onChange,
disabled, disabled,
editNode = false, editNode = false,
duplicateKey
}: KeyPairListComponent): JSX.Element { }: KeyPairListComponent): JSX.Element {
useEffect(() => { useEffect(() => {
if (disabled) { if (disabled) {
@ -20,19 +21,17 @@ export default function KeypairListComponent({
} }
}, [disabled]); }, [disabled]);
const handleChangeKey = (event, idx) => { console.log(duplicateKey);
const handleChangeKey = (event, idx) => {
const newInputList = _.cloneDeep(value); const newInputList = _.cloneDeep(value);
const oldKey = Object.keys(newInputList[idx])[0]; const oldKey = Object.keys(newInputList[idx])[0];
let counter = 1; const updatedObj = { [event.target.value]: newInputList[idx][oldKey] };
let newKey = event.target.value; newInputList[idx] = updatedObj;
while (newInputList.some(obj => Object.keys(obj)[0] === newKey)) {
newKey = `${event.target.value}_${counter}`;
counter++;
}
newInputList[idx] = { [newKey]: newInputList[idx][oldKey] };
onChange(newInputList); onChange(newInputList);
}; };
const handleChangeValue = (newValue, idx) => { const handleChangeValue = (newValue, idx) => {
const newInputList = _.cloneDeep(value); const newInputList = _.cloneDeep(value);
const key = Object.keys(newInputList[idx])[0]; const key = Object.keys(newInputList[idx])[0];

View file

@ -59,6 +59,7 @@ export type KeyPairListComponent = {
onChange: (value: string[]) => void; onChange: (value: string[]) => void;
disabled: boolean; disabled: boolean;
editNode?: boolean; editNode?: boolean;
duplicateKey?: boolean;
}; };
export type TextAreaComponentType = { export type TextAreaComponentType = {

View file

@ -289,3 +289,42 @@ export function getConnectedNodes(
const targetId = edge.target; const targetId = edge.target;
return nodes.filter((node) => node.id === targetId || node.id === sourceId); return nodes.filter((node) => node.id === targetId || node.id === sourceId);
} }
export function convertObjToArray(singleObject){
let arrConverted: any = [];
for (const key in singleObject) {
if (singleObject.hasOwnProperty(key)) {
const newObj = {};
newObj[key] = singleObject[key];
arrConverted.push(newObj);
}
}
return arrConverted;
}
export function convertArrayToObj(newValue){
const flattenedObject = {};
for (const obj of newValue) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
flattenedObject[key] = obj[key];
}
}
}
let newData = _.cloneDeep(flattenedObject);
return newData;
}
export function hasDuplicateKeys(array) {
const keys = {};
for (const obj of array) {
for (const key in obj) {
if (keys[key]) {
return true; // Duplicate key found
}
keys[key] = true;
}
}
return false; // No duplicate keys found
}