From f3ae368c341f912e581ba82ccc975a5b79abcf3b Mon Sep 17 00:00:00 2001
From: Sarah McAlear and Tira Odhner <pair+smcalear+aodhner@pivotal.io>
Date: Thu, 30 Mar 2017 17:36:59 -0400
Subject: [PATCH 07/11] Adds main checkbox in the upper left corner to
 (de-)select whole grid

---
 web/pgadmin/static/js/selection/grid_selector.js   | 30 +++++++++++++++++++++-
 web/pgadmin/static/js/selection/row_selector.js    |  1 +
 .../javascript/selection/grid_selector_spec.js     | 19 +++++++++++---
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/web/pgadmin/static/js/selection/grid_selector.js b/web/pgadmin/static/js/selection/grid_selector.js
index 0d9e1e78..c0deb071 100644
--- a/web/pgadmin/static/js/selection/grid_selector.js
+++ b/web/pgadmin/static/js/selection/grid_selector.js
@@ -21,11 +21,39 @@ define(['jquery', 'sources/selection/column_selector', 'sources/selection/row_se
         columnDefinitions = columnSelector.getColumnDefinitionsWithCheckboxes(columnDefinitions);
         columnDefinitions = rowSelector.getColumnDefinitionsWithCheckboxes(columnDefinitions);
 
+        columnDefinitions[0].name = '<input type="checkbox" data-id="checkbox-select-all" ' +
+          'title="Select/Deselect All"/>' + columnDefinitions[0].name;
         return columnDefinitions;
       };
 
       function toggleSelectAll(grid) {
-        var range = new Slick.Range(0, 1, grid.getDataLength() - 1, grid.getColumns().length - 1);
+        var selectionModel = grid.getSelectionModel();
+        var selectedRanges = selectionModel.getSelectedRanges();
+
+        var entireGridIsSelected = selectedRanges.length == 1 && isSameRange(selectedRanges[0], getRangeOfWholeGrid(grid));
+        if (entireGridIsSelected){
+          deselect(grid);
+        } else {
+          selectAll(grid)
+        }
+      }
+
+      function deselect(grid) {
+        var selectionModel = grid.getSelectionModel();
+        selectionModel.setSelectedRanges([]);
+      }
+
+      var isSameRange = function (range, otherRange) {
+        return range.fromCell == otherRange.fromCell && range.toCell == otherRange.toCell &&
+          range.fromRow == otherRange.fromRow && range.toRow == otherRange.toRow;
+      };
+
+      function getRangeOfWholeGrid(grid) {
+        return new Slick.Range(0, 1, grid.getDataLength() - 1, grid.getColumns().length - 1);
+      }
+
+      function selectAll(grid) {
+        var range = getRangeOfWholeGrid(grid);
         var selectionModel = grid.getSelectionModel();
 
         selectionModel.setSelectedRanges([range]);
diff --git a/web/pgadmin/static/js/selection/row_selector.js b/web/pgadmin/static/js/selection/row_selector.js
index 353efdc8..09e4aa78 100644
--- a/web/pgadmin/static/js/selection/row_selector.js
+++ b/web/pgadmin/static/js/selection/row_selector.js
@@ -95,6 +95,7 @@ define(['jquery', 'slickgrid'], function ($) {
     var getColumnDefinitionsWithCheckboxes = function (columnDefinitions) {
       columnDefinitions.unshift({
         id: 'row-header-column',
+        name: '',
         selectable: false,
         focusable: false,
         formatter: function (rowIndex) {
diff --git a/web/regression/javascript/selection/grid_selector_spec.js b/web/regression/javascript/selection/grid_selector_spec.js
index df71049a..915e72a4 100644
--- a/web/regression/javascript/selection/grid_selector_spec.js
+++ b/web/regression/javascript/selection/grid_selector_spec.js
@@ -52,11 +52,11 @@ define(["jquery",
         expect(container.find('[data-test="output-column-header"] input').length).toBe(2)
       });
 
-      xit("renders a checkbox for selecting all the cells", function () {
+      it("renders a checkbox for selecting all the cells", function () {
           expect(container.find("[title='Select/Deselect All']").length).toBe(1);
       });
 
-      xdescribe("when the main checkbox in the corner gets selected", function () {
+      describe("when the main checkbox in the corner gets selected", function () {
         it("unchecks all the columns", function () {
           container.find("[title='Select/Deselect All']").click();
 
@@ -74,7 +74,20 @@ define(["jquery",
           expect(selectedRange.toCell).toBe(2);
           expect(selectedRange.fromRow).toBe(0);
           expect(selectedRange.toRow).toBe(9);
-        })
+        });
+
+        describe("when the main checkbox in the corner gets deselected", function () {
+          beforeEach(function () {
+            container.find("[title='Select/Deselect All']").click();
+          });
+
+          it("deselects all the cells", function () {
+            container.find("[title='Select/Deselect All']").click();
+
+            var selectedRanges = rowSelectionModel.getSelectedRanges();
+            expect(selectedRanges.length).toBe(0);
+          });
+        });
       });
     });
   });
\ No newline at end of file
-- 
2.12.0

