From 74453a64ad430ff6aad08cc1c805462244095269 Mon Sep 17 00:00:00 2001 From: Florian Renaut Date: Tue, 31 Jul 2018 14:16:50 +0200 Subject: [PATCH 1/3] feat(oui-datagrid): add global actions --- packages/oui-datagrid/README.md | 32 ++++++++++++++++ .../oui-datagrid/src/cell/cell.component.js | 3 +- .../oui-datagrid/src/cell/cell.controller.js | 5 +++ .../oui-datagrid/src/datagrid.controller.js | 38 ++++++++++++++++++- .../oui-datagrid/src/datagrid.directive.js | 1 + packages/oui-datagrid/src/datagrid.html | 28 +++++++++++--- .../src/extra-top/extra-top.component.js | 3 ++ .../src/extra-top/extra-top.controller.js | 4 ++ 8 files changed, 106 insertions(+), 8 deletions(-) diff --git a/packages/oui-datagrid/README.md b/packages/oui-datagrid/README.md index a4efa896..be7ec039 100644 --- a/packages/oui-datagrid/README.md +++ b/packages/oui-datagrid/README.md @@ -91,6 +91,38 @@ Clicked row action 1: {{$ctrl.action1Row.lastName}}, {{$ctrl.action1Row.firstName}} ``` +### Global Actions + +```html:preview + + + + + {{$row.parents.mother.lastName}}, {{$row.parents.mother.firstName}} + + + {{$row.parents.father.lastName}}, {{$row.parents.father.firstName}} + + + {{$ctrl.label}}: {{$value}} + + + + {{$value|date:short}} + + + {{ $selected }} + + + + + + +
You have selected {{ $selectedRows.length }} row(s).
+
+
+``` + ### Empty datagrid ```html:preview diff --git a/packages/oui-datagrid/src/cell/cell.component.js b/packages/oui-datagrid/src/cell/cell.component.js index cbe82b07..f2cf0a65 100644 --- a/packages/oui-datagrid/src/cell/cell.component.js +++ b/packages/oui-datagrid/src/cell/cell.component.js @@ -7,6 +7,7 @@ export default { }, bindings: { row: "<", - column: "<" + column: "<", + index: " this.datagridCtrl.selectedRows[this.index], (selected) => { + this.cellScope.$selected = selected || false; + }); } $onChanges (changes) { diff --git a/packages/oui-datagrid/src/datagrid.controller.js b/packages/oui-datagrid/src/datagrid.controller.js index 024c1b2d..ecbda616 100644 --- a/packages/oui-datagrid/src/datagrid.controller.js +++ b/packages/oui-datagrid/src/datagrid.controller.js @@ -35,6 +35,8 @@ export default class DatagridController { this.columnElements = []; this.actionColumnElements = []; this.extraTopElements = []; + this.selectedRows = []; + this.selectAllRows = false; this.config = ouiDatagridConfiguration; @@ -103,7 +105,7 @@ export default class DatagridController { } // Manage responsiveness - if (this.hasActionMenu || this.customizable) { + if (this.hasActionMenu || this.customizable || this.globalActions) { this.scrollablePanel = this.$element[0].querySelector(".oui-datagrid-responsive-container__overflow-container"); if (this.scrollablePanel) { angular.element(this.$window).on("resize", this.checkScroll); @@ -271,6 +273,9 @@ export default class DatagridController { this.displayedRows = DatagridController.createEmptyRows(this.paging.getCurrentPageSize()); } + this.selectedRows = this.selectedRows.map(() => false); + this.selectAllRows = false; + this.refreshDatagridPromise = this.$q.when((callback || angular.noop)()) .then(() => this.paging.loadData(skipSortAndFilter, forceLoadRows)) .then(result => { @@ -313,6 +318,37 @@ export default class DatagridController { }; } + getSelectedRows () { + return this.selectedRows.reduce((result, selected, index) => { + if (selected) { + result.push(this.displayedRows[index]); + } + return result; + }, []); + } + + onSelectRow (index, selected) { + const rowCount = this.displayedRows.length; + this.selectedRows[index] = selected; + const selectedRowsCount = this.getSelectedRows().length; + + if (selectedRowsCount === rowCount) { + this.selectAllRows = true; + } else if (selectedRowsCount === 0) { + this.selectAllRows = false; + } else { + this.selectAllRows = null; + } + } + + toggleSelectAllRows (modelValue) { + if (modelValue === null) { + this.selectedRows = this.displayedRows.map(() => true); + } else { + this.selectedRows = this.displayedRows.map(() => modelValue); + } + } + static createEmptyRows (pageSize) { return Array(...{ length: pageSize }) .map(() => undefined); diff --git a/packages/oui-datagrid/src/datagrid.directive.js b/packages/oui-datagrid/src/datagrid.directive.js index 1e4f200b..32a46b40 100644 --- a/packages/oui-datagrid/src/datagrid.directive.js +++ b/packages/oui-datagrid/src/datagrid.directive.js @@ -26,6 +26,7 @@ export default () => { return (scope, elem, attrs, tableCtrl) => { tableCtrl.htmlContent = htmlContent; + tableCtrl.globalActions = "globalActions" in attrs; }; } }; diff --git a/packages/oui-datagrid/src/datagrid.html b/packages/oui-datagrid/src/datagrid.html index 807c41ff..17ac9f24 100644 --- a/packages/oui-datagrid/src/datagrid.html +++ b/packages/oui-datagrid/src/datagrid.html @@ -18,18 +18,25 @@ items="$ctrl.appliedCriteria">
+ + ng-repeat="row in $ctrl.displayedRows track by $index" + ng-init="rowIndex = $index"> + diff --git a/packages/oui-datagrid/src/extra-top/extra-top.component.js b/packages/oui-datagrid/src/extra-top/extra-top.component.js index 94100dc2..6adab478 100644 --- a/packages/oui-datagrid/src/extra-top/extra-top.component.js +++ b/packages/oui-datagrid/src/extra-top/extra-top.component.js @@ -4,5 +4,8 @@ export default { controller, require: { datagridCtrl: "^^ouiDatagrid" + }, + bindings: { + selectedItems: "<" } }; diff --git a/packages/oui-datagrid/src/extra-top/extra-top.controller.js b/packages/oui-datagrid/src/extra-top/extra-top.controller.js index 51809cc1..09eb4813 100644 --- a/packages/oui-datagrid/src/extra-top/extra-top.controller.js +++ b/packages/oui-datagrid/src/extra-top/extra-top.controller.js @@ -7,6 +7,10 @@ export default class { $postLink () { this.extraTopScope = this.datagridCtrl.getParentScope().$new(false); + this.extraTopScope.$selectedRows = []; + this.extraTopScope.$watchCollection(() => this.datagridCtrl.getSelectedRows(), (rows) => { + this.extraTopScope.$selectedRows = rows || []; + }); this._compileElement(); } From 864d05d152ec96ebbb344e61c2446b02244c06ba Mon Sep 17 00:00:00 2001 From: Florian Renaut Date: Wed, 1 Aug 2018 14:30:40 +0200 Subject: [PATCH 2/3] feat(oui-datagrid): global actions code review changes --- packages/oui-datagrid/README.md | 5 +++-- packages/oui-datagrid/src/cell/cell.controller.js | 5 ++++- packages/oui-datagrid/src/datagrid.controller.js | 10 ++++++---- packages/oui-datagrid/src/datagrid.directive.js | 1 - packages/oui-datagrid/src/datagrid.html | 12 ++++++------ 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/packages/oui-datagrid/README.md b/packages/oui-datagrid/README.md index be7ec039..614dabd1 100644 --- a/packages/oui-datagrid/README.md +++ b/packages/oui-datagrid/README.md @@ -91,10 +91,10 @@ Clicked row action 1: {{$ctrl.action1Row.lastName}}, {{$ctrl.action1Row.firstName}} ``` -### Global Actions +### Selectable rows ```html:preview - + @@ -688,6 +688,7 @@ call `rows-loader` and then a `row-loader` call for each line. | `rows-loader` | function | &? | yes | | | gets all rows (returns a promise with all rows) | | `row-loader` | function | &? | yes | | | gets row details (returns a promise with details) | | `customizable` | boolean | this.datagridCtrl.selectedRows[this.index], (selected) => { this.cellScope.$selected = selected || false; }); diff --git a/packages/oui-datagrid/src/datagrid.controller.js b/packages/oui-datagrid/src/datagrid.controller.js index ecbda616..47383bff 100644 --- a/packages/oui-datagrid/src/datagrid.controller.js +++ b/packages/oui-datagrid/src/datagrid.controller.js @@ -71,6 +71,8 @@ export default class DatagridController { this.filterableColumns = []; this.criteria = []; + addBooleanParameter(this, "selectableRows"); + if (this.id) { this.ouiDatagridService.registerDatagrid(this); } @@ -105,7 +107,7 @@ export default class DatagridController { } // Manage responsiveness - if (this.hasActionMenu || this.customizable || this.globalActions) { + if (this.hasActionMenu || this.customizable || this.selectableRows) { this.scrollablePanel = this.$element[0].querySelector(".oui-datagrid-responsive-container__overflow-container"); if (this.scrollablePanel) { angular.element(this.$window).on("resize", this.checkScroll); @@ -327,9 +329,9 @@ export default class DatagridController { }, []); } - onSelectRow (index, selected) { + toggleRowSelection (index, isSelected) { const rowCount = this.displayedRows.length; - this.selectedRows[index] = selected; + this.selectedRows[index] = isSelected; const selectedRowsCount = this.getSelectedRows().length; if (selectedRowsCount === rowCount) { @@ -341,7 +343,7 @@ export default class DatagridController { } } - toggleSelectAllRows (modelValue) { + toggleAllRowsSelection (modelValue) { if (modelValue === null) { this.selectedRows = this.displayedRows.map(() => true); } else { diff --git a/packages/oui-datagrid/src/datagrid.directive.js b/packages/oui-datagrid/src/datagrid.directive.js index 32a46b40..1e4f200b 100644 --- a/packages/oui-datagrid/src/datagrid.directive.js +++ b/packages/oui-datagrid/src/datagrid.directive.js @@ -26,7 +26,6 @@ export default () => { return (scope, elem, attrs, tableCtrl) => { tableCtrl.htmlContent = htmlContent; - tableCtrl.globalActions = "globalActions" in attrs; }; } }; diff --git a/packages/oui-datagrid/src/datagrid.html b/packages/oui-datagrid/src/datagrid.html index 17ac9f24..ea03452a 100644 --- a/packages/oui-datagrid/src/datagrid.html +++ b/packages/oui-datagrid/src/datagrid.html @@ -20,21 +20,21 @@
+ + +
+ + + + column="column" + index="rowIndex"> + column="$ctrl.actionColumn" + index="rowIndex">
+ ng-if="$ctrl.selectableRows"> + on-change="$ctrl.toggleAllRowsSelection(modelValue)"> + ng-if="$ctrl.selectableRows"> + on-change="$ctrl.toggleRowSelection($index, modelValue)"> Date: Wed, 1 Aug 2018 16:59:37 +0200 Subject: [PATCH 3/3] feat(oui-datagrid): add selectable-rows unit tests --- packages/oui-datagrid/README.md | 4 +- .../oui-datagrid/src/cell/cell.controller.js | 4 +- .../oui-datagrid/src/datagrid.controller.js | 4 +- packages/oui-datagrid/src/index.spec.js | 88 +++++++++++++++++++ 4 files changed, 94 insertions(+), 6 deletions(-) diff --git a/packages/oui-datagrid/README.md b/packages/oui-datagrid/README.md index 614dabd1..d1fe6b50 100644 --- a/packages/oui-datagrid/README.md +++ b/packages/oui-datagrid/README.md @@ -111,10 +111,10 @@ Clicked row action 1: {{$ctrl.action1Row.lastName {{$value|date:short}} - {{ $selected }} + {{ $isSelected }} - + diff --git a/packages/oui-datagrid/src/cell/cell.controller.js b/packages/oui-datagrid/src/cell/cell.controller.js index f3b625a8..d17d3cdd 100644 --- a/packages/oui-datagrid/src/cell/cell.controller.js +++ b/packages/oui-datagrid/src/cell/cell.controller.js @@ -24,8 +24,8 @@ export default class { this._compileCell(); } - this.cellScope.$watch(() => this.datagridCtrl.selectedRows[this.index], (selected) => { - this.cellScope.$selected = selected || false; + this.cellScope.$watch(() => this.datagridCtrl.selectedRows[this.index], (isSelected) => { + this.cellScope.$isSelected = isSelected || false; }); } diff --git a/packages/oui-datagrid/src/datagrid.controller.js b/packages/oui-datagrid/src/datagrid.controller.js index 47383bff..4d1dde80 100644 --- a/packages/oui-datagrid/src/datagrid.controller.js +++ b/packages/oui-datagrid/src/datagrid.controller.js @@ -321,8 +321,8 @@ export default class DatagridController { } getSelectedRows () { - return this.selectedRows.reduce((result, selected, index) => { - if (selected) { + return this.selectedRows.reduce((result, isSelected, index) => { + if (isSelected) { result.push(this.displayedRows[index]); } return result; diff --git a/packages/oui-datagrid/src/index.spec.js b/packages/oui-datagrid/src/index.spec.js index 51a9dfed..0af9c61f 100644 --- a/packages/oui-datagrid/src/index.spec.js +++ b/packages/oui-datagrid/src/index.spec.js @@ -417,6 +417,94 @@ describe("ouiDatagrid", () => { }); }); + describe("Selectable rows", () => { + + it("should toggle row selection", () => { + const element = TestUtils.compileTemplate(` + + + + `, { + rows: fakeData.slice(0, 5) + }); + const ctrl = element.controller("ouiDatagrid"); + + let selection = []; + ctrl.toggleRowSelection(0, true); + selection = ctrl.getSelectedRows(); + expect(selection.length).toBe(1); + expect(selection[0]).toEqual(fakeData[0]); + + ctrl.toggleRowSelection(0, false); + selection = ctrl.getSelectedRows(); + expect(selection.length).toBe(0); + }); + + it("should toggle all rows", () => { + const element = TestUtils.compileTemplate(` + + + + `, { + rows: fakeData.slice(0, 5) + }); + const ctrl = element.controller("ouiDatagrid"); + + let selection = []; + expect(ctrl.selectAllRows).toBe(false); + ctrl.toggleAllRowsSelection(true); + selection = ctrl.getSelectedRows(); + expect(selection.length).toBe(5); + + ctrl.toggleAllRowsSelection(false); + selection = ctrl.getSelectedRows(); + expect(selection.length).toBe(0); + }); + + it("should update global selection checkbox", () => { + const element = TestUtils.compileTemplate(` + + + + `, { + rows: fakeData.slice(0, 5) + }); + const ctrl = element.controller("ouiDatagrid"); + + expect(ctrl.selectAllRows).toBe(false); + ctrl.toggleRowSelection(0, true); + expect(ctrl.selectAllRows).toBe(null); + ctrl.toggleRowSelection(1, true); + ctrl.toggleRowSelection(2, true); + ctrl.toggleRowSelection(3, true); + expect(ctrl.selectAllRows).toBe(null); + ctrl.toggleRowSelection(4, true); + expect(ctrl.selectAllRows).toBe(true); + ctrl.toggleRowSelection(4, false); + expect(ctrl.selectAllRows).toBe(null); + ctrl.toggleRowSelection(0, false); + ctrl.toggleRowSelection(1, false); + ctrl.toggleRowSelection(2, false); + ctrl.toggleRowSelection(3, false); + expect(ctrl.selectAllRows).toBe(false); + }); + + it("should updates extra-top content", () => { + const element = TestUtils.compileTemplate(` + + + + {{ $selectedRows.length }} + `, { + rows: fakeData.slice(0, 5) + }); + const ctrl = element.controller("ouiDatagrid"); + ctrl.toggleAllRowsSelection(true); + element.scope().$apply(); + expect(element.find("oui-datagrid-extra-top").text()).toBe("5"); + }); + }); + describe("Remote rows", () => { let rowsLoaderSpy;