🐛 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 { ParameterComponentType } from "../../../../types/components";
import { TabsState } from "../../../../types/tabs";
import { isValidConnection } from "../../../../utils/reactflowUtils";
import { convertArrayToObj, convertObjToArray, hasDuplicateKeys, isValidConnection } from "../../../../utils/reactflowUtils";
import {
nodeColors,
nodeIconsLucide,
@ -53,6 +53,7 @@ export default function ParameterComponent({
const updateNodeInternals = useUpdateNodeInternals();
const [position, setPosition] = useState(0);
const { setTabsState, tabId, save, flows } = useContext(TabsContext);
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
const flow = flows.find((flow) => flow.id === tabId)?.data?.nodes ?? null;
@ -105,34 +106,9 @@ export default function ParameterComponent({
const [dictArr, setDictArr] = useState([]);
useEffect(() => {
convertToArray(dict);
setDictArr(convertObjToArray(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(() => {
if (name === "openai_api_base") console.log(info);
// @ts-ignore
@ -254,7 +230,12 @@ export default function ParameterComponent({
disabled={disabled}
editNode={false}
value={dictArr}
onChange={convertToDict}
duplicateKey={errorDuplicateKey}
onChange={(newValue) => {
setErrorDuplicateKey(hasDuplicateKeys(newValue));
if(hasDuplicateKeys(newValue)) return;
setDict(convertArrayToObj(newValue));
}}
/>
</div>
) : (

View file

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

View file

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

View file

@ -289,3 +289,42 @@ export function getConnectedNodes(
const targetId = edge.target;
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
}