From 7da12468a8f72365e041848e98306aa5e453590f Mon Sep 17 00:00:00 2001
From: "Ahmad K. Bawaneh" <ahmad.bawaneh@dominokit.com>
Date: Mon, 15 Apr 2024 18:29:23 +0300
Subject: [PATCH] fix #910 SelectionPlugin: MultiSelectHeader checkbox should
 get unchecked if not all table entries are checked

---
 .../plugins/selection/SelectionPlugin.java    | 39 ++++++++++++-------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/datatable/plugins/selection/SelectionPlugin.java b/domino-ui/src/main/java/org/dominokit/domino/ui/datatable/plugins/selection/SelectionPlugin.java
index c33c05de3..36cd93575 100644
--- a/domino-ui/src/main/java/org/dominokit/domino/ui/datatable/plugins/selection/SelectionPlugin.java
+++ b/domino-ui/src/main/java/org/dominokit/domino/ui/datatable/plugins/selection/SelectionPlugin.java
@@ -21,7 +21,6 @@
 import static java.util.Objects.nonNull;
 import static org.dominokit.domino.ui.datatable.DataTableStyles.dui_datatable_row_selected;
 import static org.dominokit.domino.ui.forms.FormsStyles.dui_form_select_check_box;
-import static org.dominokit.domino.ui.utils.Domino.*;
 
 import elemental2.dom.Element;
 import elemental2.dom.HTMLElement;
@@ -34,6 +33,7 @@
 import jsinterop.base.Js;
 import org.dominokit.domino.ui.datatable.*;
 import org.dominokit.domino.ui.datatable.events.OnBeforeDataChangeEvent;
+import org.dominokit.domino.ui.datatable.events.TableDataUpdatedEvent;
 import org.dominokit.domino.ui.datatable.events.TableEvent;
 import org.dominokit.domino.ui.datatable.plugins.DataTablePlugin;
 import org.dominokit.domino.ui.forms.CheckBox;
@@ -58,6 +58,7 @@ public class SelectionPlugin<T> implements DataTablePlugin<T> {
   private DataTable<T> datatable;
   private List<T> oldSelection = new ArrayList<>();
   private boolean retainSelectionOnDataChange = false;
+  private CheckBox headerCheckBox;
 
   /** Creates a new `SelectionPlugin` with default settings. */
   public SelectionPlugin() {}
@@ -300,8 +301,8 @@ private void deselectRow(DataTable<T> dataTable, TableRow<T> tableRow) {
    * @return The selection indicator element for a multi-selection header.
    */
   private HTMLElement createMultiSelectHeader(DataTable<T> dataTable) {
-    CheckBox checkBox = createCheckBox(Optional.empty());
-    checkBox.addChangeListener(
+    headerCheckBox = createCheckBox(Optional.empty());
+    headerCheckBox.addChangeListener(
         (oldValue, checked) -> {
           if (checked) {
             dataTable.selectAll(selectionCondition);
@@ -312,20 +313,24 @@ private HTMLElement createMultiSelectHeader(DataTable<T> dataTable) {
 
     dataTable.addSelectionDeselectionListener(
         (source, selectedRows) -> {
-          long selectableCount =
-              dataTable.getRows().stream()
-                  .filter(tableRow -> selectionCondition.isAllowSelection(dataTable, tableRow))
-                  .count();
-          if (selectedRows.size() > 0 && selectedRows.size() < selectableCount) {
-            checkBox.indeterminate();
-          } else if (selectedRows.size() == selectableCount) {
-            checkBox.check(true);
-          } else if (selectedRows.isEmpty()) {
-            checkBox.uncheck(true);
-          }
+          updateHeaderCheckBox(selectedRows);
         });
 
-    return checkBox.element();
+    return headerCheckBox.element();
+  }
+
+  private void updateHeaderCheckBox(List<TableRow<T>> selectedRows) {
+    long selectableCount =
+        this.datatable.getRows().stream()
+            .filter(tableRow -> selectionCondition.isAllowSelection(this.datatable, tableRow))
+            .count();
+    if (selectedRows.size() > 0 && selectedRows.size() < selectableCount) {
+      headerCheckBox.indeterminate();
+    } else if (selectedRows.size() == selectableCount) {
+      headerCheckBox.check(true);
+    } else if (selectedRows.isEmpty()) {
+      headerCheckBox.uncheck(true);
+    }
   }
 
   /**
@@ -402,6 +407,10 @@ public void handleEvent(TableEvent event) {
         this.oldSelection = this.datatable.getSelectedRecords();
       }
     }
+
+    if (TableDataUpdatedEvent.DATA_UPDATED.equals(event.getType())) {
+      updateHeaderCheckBox(this.datatable.getSelectedItems());
+    }
   }
 
   /**