I have a Grid
with mui
which is dragable. On drop, I want it to edit my configuration state to save its position in database.
Here is how my state is constructed :
interface SocialMediaState {
socialLinks: string;
conf: {
confId: string;
conf: {
hasIcon: boolean;
hasLabel: boolean;
position: number;
}
};
}
Here is my try, but the problem is that the position only stays at 0
or 1
. So this works nice when there are only 2 items, but when there is more, it doesn’t work.
I’m trying to figure out how to adapt this logic to multiple items.
const SocialMediaSettings = () => {
const [socialMedia, setSocialMedia] = useAtom(socialMediaHeaderAtom);
[...]
const handleDragStart = (event, index) => {
event.dataTransfer.setData("index", index.toString());
};
const handleDrop = (event, newIndex) => {
const oldIndex = parseInt(event.dataTransfer.getData("index"));
const networkKeys = Object.keys(socialMedia.conf.conf);
const draggedNetwork = networkKeys[oldIndex];
const targetNetwork = networkKeys[newIndex];
const updatedConf = { ...socialMedia.conf.conf };
const draggedConfig = updatedConf[draggedNetwork];
const targetConfig = updatedConf[targetNetwork];
const tempPosition = draggedConfig.position;
draggedConfig.position = targetConfig.position;
targetConfig.position = tempPosition;
setSocialMedia({
...socialMedia,
conf: {
...socialMedia.conf,
conf: updatedConf,
},
});
};
return (
<Grid container direction="column">
{Object.entries(socialMedia.conf.conf)
.sort(([, a], [, b]) => a.position - b.position)
.map(([network, config], index) => (
<Grid
item
key={network}
draggable="true"
onDragStart={(event) => handleDragStart(event, index)}
onDrop={(event) => handleDrop(event, index)}
onDragOver={(event) => event.preventDefault()}
>