All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dominokit.domino.ui.datatable.plugins.GroupingPlugin Maven / Gradle / Ivy

/*
 * Copyright © 2019 Dominokit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.dominokit.domino.ui.datatable.plugins;

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;

import elemental2.dom.HTMLTableCellElement;
import elemental2.dom.Node;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
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;

/**
 * This plugin renders the table rows in groups.
 *
 * @param  the type of the data table records
 */
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;

  /**
   * Create an instance with custom group supplier and group cell renderer
   *
   * @param groupSupplier the {@link GroupSupplier}
   * @param groupRenderer the {@link CellRenderer}
   */
  public GroupingPlugin(GroupSupplier groupSupplier, CellRenderer groupRenderer) {
    this.groupSupplier = groupSupplier;
    this.groupRenderer = groupRenderer;
  }

  /** {@inheritDoc} */
  @Override
  public void init(DataTable dataTable) {
    dataTable.getTableConfig().setRowAppender(this);
  }

  /**
   * Changes the group expand icon
   *
   * @param groupExpandedIconSupplier Supplier of {@link BaseIcon} to change the icon
   * @return same plugin instance
   */
  public GroupingPlugin setGroupExpandedIcon(Supplier> groupExpandedIconSupplier) {
    this.groupExpandedIconSupplier = groupExpandedIconSupplier;
    return this;
  }

  /**
   * Changes the group collapse icon
   *
   * @param groupCollapsedIconSupplier Supplier of {@link BaseIcon} to change the icon
   * @return same plugin instance
   */
  public GroupingPlugin setGroupCollapsedIcon(Supplier> groupCollapsedIconSupplier) {
    this.groupCollapsedIconSupplier = groupCollapsedIconSupplier;
    return this;
  }

  /**
   * {@inheritDoc}
   *
   * 

the plugin will create a group based on the GroupSupplier and will append rows to the first * group matching the criteria */ @Override public void appendRow(DataTable dataTable, TableRow tableRow) { String groupId = groupSupplier.getRecordGroupId(tableRow); if (!dataGroups.containsKey(groupId)) { HTMLTableCellElement cellElement = td().attr("colspan", dataTable.getTableConfig().getColumns().size() + "").element(); CellRenderer.CellInfo cellInfo = new CellRenderer.CellInfo<>(tableRow, cellElement); DataGroup dataGroup = new DataGroup<>(tableRow, cellInfo); BaseIcon groupIconSupplier = groupExpandedIconSupplier .get() .clickable() .setToggleIcon(groupCollapsedIconSupplier.get()) .toggleOnClick(true) .addClickListener(evt -> dataGroup.toggleGroup()); dataGroup.setGroupIconSupplier(groupIconSupplier).setGroupRenderer(groupRenderer).render(); 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); } } /** Expands all the current groups in the data table */ public void expandAll() { for (DataGroup dataGroup : dataGroups.values()) { if (!dataGroup.expanded) { dataGroup.toggleGroup(); dataGroup.getGroupIconSupplier().toggleIcon(); } } } /** Collapse all the current groups in the data table */ public void collapseAll() { for (DataGroup dataGroup : dataGroups.values()) { if (dataGroup.expanded) { dataGroup.toggleGroup(); dataGroup.getGroupIconSupplier().toggleIcon(); } } } public Map> getDataGroups() { return dataGroups; } /** {@inheritDoc} */ @Override public void handleEvent(TableEvent event) { if (event.getType().equalsIgnoreCase(OnBeforeDataChangeEvent.ON_BEFORE_DATA_CHANGE)) { dataGroups.clear(); } } public static class DataGroup implements TableRow.RowMetaObject { private static final String KEY = "dataGroup"; private List> groupRows = new ArrayList<>(); private TableRow lastRow; private CellRenderer.CellInfo cellInfo; private boolean expanded = true; private BaseIcon groupIconSupplier; private CellRenderer groupRenderer; public DataGroup(TableRow lastRow, CellRenderer.CellInfo cellInfo) { this.lastRow = lastRow; this.cellInfo = cellInfo; addRow(lastRow); } public static DataGroup fromRow(TableRow tableRow) { return tableRow.getMetaObject(KEY); } public void toggleGroup() { expanded = !expanded; groupRows.forEach(tableRow -> DominoElement.of(tableRow.element()).toggleDisplay(expanded)); } public void addRow(TableRow tableRow) { groupRows.add(tableRow); tableRow.addMetaObject(this); } private DataGroup setGroupIconSupplier(BaseIcon groupIconSupplier) { this.groupIconSupplier = groupIconSupplier; return this; } private BaseIcon getGroupIconSupplier() { return this.groupIconSupplier; } private DataGroup setGroupRenderer(CellRenderer groupRenderer) { this.groupRenderer = groupRenderer; return this; } @Override public String getKey() { return KEY; } public void render() { DominoElement.of(cellInfo.getElement()) .clearElement() .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)))); } } /** * this interface is to provide an implementation to define each row group * * @param the type of the table row record */ @FunctionalInterface public interface GroupSupplier { /** * determines the row group * * @param tableRow the {@link TableRow} * @return String group name the table row belongs to */ String getRecordGroupId(TableRow tableRow); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy