🐛 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:
parent
646fd7f1e5
commit
2b2c677f7c
4 changed files with 57 additions and 37 deletions
|
|
@ -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>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ export type KeyPairListComponent = {
|
|||
onChange: (value: string[]) => void;
|
||||
disabled: boolean;
|
||||
editNode?: boolean;
|
||||
duplicateKey?: boolean;
|
||||
};
|
||||
|
||||
export type TextAreaComponentType = {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue