128 lines
5.1 KiB
TypeScript
128 lines
5.1 KiB
TypeScript
import React from "react";
|
|
|
|
function ConfigEditor({config, setConfig}) {
|
|
const handleValueChange = (key, value) => {
|
|
setConfig((prev) => ({...prev, [key]: value}));
|
|
};
|
|
|
|
const handleAddToList = (key) => {
|
|
setConfig((prev) => ({
|
|
...prev,
|
|
[key]: [...prev[key], {}], // Add an empty object
|
|
}));
|
|
};
|
|
|
|
const handleRemoveFromList = (key, index) => {
|
|
setConfig((prev) => ({
|
|
...prev,
|
|
[key]: prev[key].filter((_, i) => i !== index),
|
|
}));
|
|
};
|
|
|
|
const handleNestedChange = (key, nestedKey, value) => {
|
|
setConfig((prev) => ({
|
|
...prev,
|
|
[key]: {...prev[key], [nestedKey]: value},
|
|
}));
|
|
};
|
|
|
|
const handleObjectInListChange = (listKey, index, fieldKey, value) => {
|
|
setConfig((prev) => ({
|
|
...prev,
|
|
[listKey]: prev[listKey].map((item, i) =>
|
|
i === index ? {...item, [fieldKey]: value} : item
|
|
),
|
|
}));
|
|
};
|
|
|
|
const renderField = (key, value) => {
|
|
if (Array.isArray(value)) {
|
|
// Render a list editor
|
|
return (
|
|
<div key={key}>
|
|
<label>{key}</label>
|
|
{value.map((item, index) => (
|
|
<div key={index} style={{marginLeft: "20px", marginBottom: "10px"}}>
|
|
{typeof item === "object" && item !== null ? (
|
|
// Render object fields
|
|
<div>
|
|
{Object.entries(item).map(([fieldKey, fieldValue]: [string, any]) => (
|
|
<div key={fieldKey}>
|
|
<label>{fieldKey}</label>
|
|
<input
|
|
type="text"
|
|
value={fieldValue}
|
|
onChange={(e) =>
|
|
handleObjectInListChange(
|
|
key,
|
|
index,
|
|
fieldKey,
|
|
e.target.value
|
|
)
|
|
}
|
|
/>
|
|
</div>
|
|
))}
|
|
<button
|
|
onClick={() => handleRemoveFromList(key, index)}
|
|
style={{marginTop: "5px"}}
|
|
>
|
|
Remove Object
|
|
</button>
|
|
</div>
|
|
) : (
|
|
// Render primitive values in the list
|
|
<div>
|
|
<input
|
|
type="text"
|
|
value={item}
|
|
onChange={(e) =>
|
|
handleValueChange(key, [
|
|
...value.slice(0, index),
|
|
e.target.value,
|
|
...value.slice(index + 1),
|
|
])
|
|
}
|
|
/>
|
|
<button onClick={() => handleRemoveFromList(key, index)}>
|
|
Remove
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
))}
|
|
<button onClick={() => handleAddToList(key)}>Add Item</button>
|
|
</div>
|
|
);
|
|
} else if (typeof value === "object" && value !== null) {
|
|
// Render nested objects
|
|
return (
|
|
<div key={key}>
|
|
<label>{key}</label>
|
|
<div style={{marginLeft: "20px"}}>
|
|
{Object.entries(value).map(([nestedKey, nestedValue]) =>
|
|
renderField(nestedKey, nestedValue)
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
} else {
|
|
// Render a single value editor
|
|
return (
|
|
<div key={key}>
|
|
<label>{key}</label>
|
|
<input
|
|
type="text"
|
|
value={value}
|
|
onChange={(e) => handleValueChange(key, e.target.value)}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
};
|
|
|
|
return <div>{Object.entries(config).map(([key, value]) => renderField(key, value))}</div>;
|
|
}
|
|
|
|
export default ConfigEditor;
|