mirror of
https://github.com/Av0idD4rk/firegex.git
synced 2026-10-25 10:29:25 +00:00
Fix drag-and-drop reordering of firewall rules
Three separate defects made the rule list impossible to reorder:
- The Card's own `style` was placed after `{...provided.draggableProps}`,
clobbering the `position`/`transform` dnd sets while dragging. The drag
did start, but nothing moved on screen. Styles are now merged with dnd's
winning, and the dragged card is highlighted.
- `Draggable index` used the position in the full `state` array and the
rules of the other table were filtered out afterwards, leaving gaps.
dnd requires contiguous indexes from 0 inside a Droppable, so a single
rule in the other table broke the visible tab entirely. Visible rules
are now re-indexed and mapped back to their `state` position on drop.
- `destination?.index || 0` reordered to the top instead of doing nothing
when a rule was dropped outside the list.
This commit is contained in:
parent
60011612e5
commit
72b3386d3e
@ -136,8 +136,14 @@ export const Firewall = () => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const items = state.map((item, index) => (
|
// Draggable indexes must be contiguous inside a Droppable, so the visible rules are
|
||||||
item.table == selectedTab && <Draggable key={item.rule_id} index={index} draggableId={item.rule_id}>
|
// re-indexed for the tab while keeping their position in `state` for the actual edits.
|
||||||
|
const visibleRules = state
|
||||||
|
.map((item, index) => ({ item, index }))
|
||||||
|
.filter(({ item }) => item.table == selectedTab)
|
||||||
|
|
||||||
|
const items = visibleRules.map(({ item, index }, visibleIndex) => (
|
||||||
|
<Draggable key={item.rule_id} index={visibleIndex} draggableId={item.rule_id}>
|
||||||
{(provided, snapshot) => {
|
{(provided, snapshot) => {
|
||||||
const customInt = [
|
const customInt = [
|
||||||
{ value: "0.0.0.0/0", netint: "ANY IPv4", label: "0.0.0.0/0" },
|
{ value: "0.0.0.0/0", netint: "ANY IPv4", label: "0.0.0.0/0" },
|
||||||
@ -195,7 +201,12 @@ export const Firewall = () => {
|
|||||||
mb="md"
|
mb="md"
|
||||||
w="100%"
|
w="100%"
|
||||||
bg="transparent"
|
bg="transparent"
|
||||||
style={{ borderColor: 'var(--fourth_color)', transition: 'border-color 0.2s ease' }}
|
style={{
|
||||||
|
transition: 'border-color 0.2s ease',
|
||||||
|
// dnd puts the drag transform/transition in here: it has to win over our defaults
|
||||||
|
...provided.draggableProps.style,
|
||||||
|
borderColor: snapshot.isDragging ? 'var(--accent-color)' : 'var(--fourth_color)',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Group wrap="nowrap" align="flex-start" gap="sm">
|
<Group wrap="nowrap" align="flex-start" gap="sm">
|
||||||
<Box {...provided.dragHandleProps} style={{ display: 'flex', alignItems: 'center', height: rem(36) }}>
|
<Box {...provided.dragHandleProps} style={{ display: 'flex', alignItems: 'center', height: rem(36) }}>
|
||||||
@ -316,7 +327,7 @@ export const Firewall = () => {
|
|||||||
</Card>
|
</Card>
|
||||||
}}
|
}}
|
||||||
</Draggable>
|
</Draggable>
|
||||||
)).filter(v => v);
|
));
|
||||||
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
@ -380,9 +391,13 @@ export const Firewall = () => {
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
</Group>
|
</Group>
|
||||||
{items.length > 0 ? <DragDropContext
|
{items.length > 0 ? <DragDropContext
|
||||||
onDragEnd={({ destination, source }) =>
|
onDragEnd={({ destination, source }) => {
|
||||||
handlers.reorder({ from: source.index, to: destination?.index || 0 })
|
if (!destination || destination.index == source.index) return
|
||||||
}
|
handlers.reorder({
|
||||||
|
from: visibleRules[source.index].index,
|
||||||
|
to: visibleRules[destination.index].index,
|
||||||
|
})
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Space h="md" />
|
<Space h="md" />
|
||||||
<Droppable droppableId="dnd-list" direction="vertical">
|
<Droppable droppableId="dnd-list" direction="vertical">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user