flow icon indicating copy to clipboard operation
flow copied to clipboard

TreeGrid.getTreeData().setParent() may duplicate data item in the TreeGrid, and forgets moving children. See video.

Open enver-haase opened this issue 3 months ago • 1 comments

Description of the bug

Please see the video. It is hard to explain. The problem may also be a refresh that's not properly working.

Expected behavior

I'd like to move node D with all its children. See video.

Minimal reproducible example

package org.vaadin.example;

import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.dnd.GridDropLocation;
import com.vaadin.flow.component.grid.dnd.GridDropMode;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.treegrid.TreeGrid;

import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.provider.hierarchy.TreeData;
import com.vaadin.flow.router.Route;

import java.util.ArrayList;
import java.util.List;


@Route
public class MainView extends VerticalLayout {

    private static class DemoTreeData extends TreeData<String> {
        private DemoTreeData() {
            final String[] five = {"A", "B", "C", "D", "E"};

            addRootItems(five);

            for (String s : five) {
                List<String> children = new ArrayList<>();
                for (String ch : five) {
                    String child = s+ch;
                    children.add(child);
                }

                addItems(s, children);
            }
        }
    }
    public MainView() {

        TreeGrid<String> treeGrid = new TreeGrid<>();

        treeGrid.addHierarchyColumn(String::toString).setHeader("Name");

        treeGrid.setTreeData(new DemoTreeData());

        treeGrid.setDropMode(GridDropMode.ON_TOP_OR_BETWEEN);
        treeGrid.setSelectionMode(Grid.SelectionMode.SINGLE);
        treeGrid.setRowsDraggable(true);

        List<String> dragged = new ArrayList<>();
        treeGrid.addDragStartListener( evt -> {
            dragged.clear();
            dragged.addAll(evt.getDraggedItems());
        } );

        treeGrid.addDropListener( evt -> {
            try {
                if (GridDropLocation.ON_TOP == evt.getDropLocation()) {
                    evt.getDropTargetItem().ifPresent(s -> {
                        for (String drag : dragged) {
                            String oldParent = treeGrid.getTreeData().getParent(s);
                            treeGrid.getTreeData().setParent(drag, s);

                            if (oldParent != null) {
                                // This throws a NullPointerException for the NULL parent.
                                treeGrid.getDataProvider().refreshItem(oldParent, true);
                                treeGrid.getDataProvider().refreshItem(s, true);
                            }
                            else {
                                treeGrid.getDataProvider().refreshAll();
                            }
                        }
                    });
                }
            }
            catch (Exception e) {
                Notification.show("Exception: "+e);
            }
        } );

        treeGrid.setWidthFull();
        treeGrid.setHeight("800px");
        add(treeGrid);
    }

}

Versions

  • Vaadin / Flow version: 24.3.10
  • Java version: n/a
  • OS version: n/a
  • Browser version (if applicable): n/a
  • Application Server (if applicable): n/a
  • IDE (if applicable): n/a

enver-haase avatar May 14 '24 15:05 enver-haase

https://github.com/vaadin/flow/assets/7870436/2e929d2d-957f-41ca-a1ce-cedf02dd99be

enver-haase avatar May 14 '24 15:05 enver-haase