🐛 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 { 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>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -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];
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue