org.dominokit.domino.ui.datatable.plugins.GroupingPlugin Maven / Gradle / Ivy
package org.dominokit.domino.ui.datatable.plugins;
import elemental2.dom.HTMLTableCellElement;
import elemental2.dom.Node;
import org.dominokit.domino.ui.datatable.CellRenderer;
import org.dominokit.domino.ui.datatable.DataTable;
import org.dominokit.domino.ui.datatable.TableConfig;
import org.dominokit.domino.ui.datatable.TableRow;
import org.dominokit.domino.ui.datatable.events.OnBeforeDataChangeEvent;
import org.dominokit.domino.ui.datatable.events.TableEvent;
import org.dominokit.domino.ui.grid.flex.FlexItem;
import org.dominokit.domino.ui.grid.flex.FlexLayout;
import org.dominokit.domino.ui.icons.BaseIcon;
import org.dominokit.domino.ui.icons.Icons;
import org.dominokit.domino.ui.utils.DominoElement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import static java.util.Objects.nonNull;
import static org.dominokit.domino.ui.style.Unit.px;
import static org.jboss.elemento.Elements.td;
import static org.jboss.elemento.Elements.tr;
public class GroupingPlugin implements DataTablePlugin, TableConfig.RowAppender {
private Map> dataGroups = new HashMap<>();
private final GroupSupplier groupSupplier;
private CellRenderer groupRenderer;
private Supplier> groupExpandedIconSupplier = Icons.ALL::minus_box_mdi;
private Supplier> groupCollapsedIconSupplier = Icons.ALL::plus_box_mdi;
public GroupingPlugin(GroupSupplier groupSupplier, CellRenderer groupRenderer) {
this.groupSupplier = groupSupplier;
this.groupRenderer = groupRenderer;
}
@Override
public void init(DataTable dataTable) {
dataTable.getTableConfig()
.setRowAppender(this);
}
public GroupingPlugin setGroupExpandedIcon(Supplier> groupExpandedIconSupplier){
this.groupExpandedIconSupplier = groupExpandedIconSupplier;
return this;
}
public GroupingPlugin setGroupCollapsedIcon(Supplier> groupCollapsedIconSupplier){
this.groupCollapsedIconSupplier = groupCollapsedIconSupplier;
return this;
}
@Override
public void appendRow(DataTable dataTable, TableRow tableRow) {
String groupId = groupSupplier.getRecordGroupId(tableRow);
if (!dataGroups.containsKey(groupId)) {
DataGroup dataGroup = new DataGroup<>(tableRow);
HTMLTableCellElement cellElement = td()
.attr("colspan", dataTable.getTableConfig().getColumns().size() + "")
.element();
CellRenderer.CellInfo cellInfo = new CellRenderer.CellInfo<>(tableRow, cellElement);
BaseIcon> groupIconSupplier = groupExpandedIconSupplier.get()
.clickable()
.setToggleIcon(groupCollapsedIconSupplier.get())
.toggleOnClick(true)
.addClickListener(evt -> dataGroup.toggleGroup());
dataGroup.setGroupIconSupplier(groupIconSupplier);
cellElement.appendChild(FlexLayout.create()
.appendChild(FlexItem.create()
.appendChild(groupIconSupplier))
.appendChild(FlexItem.create()
.styler(style -> style.setLineHeight(px.of(35))
.setPaddingLeft(px.of(10)))
.setFlexGrow(1)
.appendChild(groupRenderer.asElement(cellInfo)))
.element());
dataTable.bodyElement().appendChild(tr().add(cellElement));
dataTable.bodyElement().appendChild(tableRow.element());
dataGroups.put(groupId, dataGroup);
} else {
DataGroup dataGroup = dataGroups.get(groupId);
Node nextSibling = dataGroup.lastRow.element().nextSibling;
if (nonNull(nextSibling)) {
DominoElement.of(dataTable.bodyElement()).insertBefore(tableRow.element(), nextSibling);
} else {
dataTable.bodyElement().appendChild(tableRow.element());
}
dataGroup.lastRow = tableRow;
dataGroup.addRow(tableRow);
}
}
public void expandAll() {
for (DataGroup dataGroup : dataGroups.values()) {
if (!dataGroup.expanded) {
dataGroup.toggleGroup();
dataGroup.getGroupIconSupplier().toggleIcon();
}
}
}
public void collapseAll() {
for (DataGroup dataGroup : dataGroups.values()) {
if (dataGroup.expanded) {
dataGroup.toggleGroup();
dataGroup.getGroupIconSupplier().toggleIcon();
}
}
}
@Override
public void handleEvent(TableEvent event) {
if (event.getType().equalsIgnoreCase(OnBeforeDataChangeEvent.ON_BEFORE_DATA_CHANGE)) {
dataGroups.clear();
}
}
private class DataGroup {
private List> groupRows = new ArrayList<>();
private TableRow lastRow;
private boolean expanded = true;
private BaseIcon> groupIconSupplier;
public DataGroup(TableRow lastRow) {
this.lastRow = lastRow;
groupRows.add(lastRow);
}
public void toggleGroup() {
expanded = !expanded;
groupRows.forEach(tableRow -> DominoElement.of(tableRow.element())
.toggleDisplay(expanded));
}
public void addRow(TableRow tableRow) {
groupRows.add(tableRow);
}
private void setGroupIconSupplier(BaseIcon> groupIconSupplier) {
this.groupIconSupplier = groupIconSupplier;
}
private BaseIcon> getGroupIconSupplier() {
return this.groupIconSupplier;
}
}
@FunctionalInterface
public interface GroupSupplier {
String getRecordGroupId(TableRow tableRow);
}
}