Created
November 22, 2016 15:08
-
-
Save tristanpendergrass/9f52985172c0e705ad3ed97fcc0f09e4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // contentGrid.directive.js | |
| import angular from 'angular'; | |
| import gridTpl from './contentGrid.tpl.html'; | |
| import angularServices from 'common/services/angular/index'; | |
| import coreServices from 'common/services/core/index'; | |
| import 'common/vaadinGrid.css!'; | |
| function contentGrid() { | |
| return { | |
| restrict: 'E', | |
| template: ` | |
| <script src="https://cdn.vaadin.com/vaadin-core-elements/latest/webcomponentsjs/webcomponents-lite.min.js"></script> | |
| <link rel="import" href="https://cdn.vaadin.com/vaadin-core-elements/latest/vaadin-grid/vaadin-grid.html"> | |
| <vaadin-grid | |
| class="content-grid" | |
| selection-mode="multi"> | |
| </vaadin-grid> | |
| `, | |
| controller: ($scope, $element) => new ContentGridCtrl($scope, angularServices, coreServices, $element), | |
| controllerAs: 'contentGridCtrl', | |
| bindToController: true, | |
| scope: { | |
| items: '=', | |
| selected: '=', | |
| rowClick: '&', | |
| rowSelect: '&', | |
| query: '=' | |
| } | |
| }; | |
| } | |
| const contentGridCtrlModule = angular.module('contentGrid.directive.js', []) | |
| .directive('contentGrid', contentGrid); | |
| export default contentGridCtrlModule; | |
| //contentGrid.controller.js | |
| export default class ExpVaadinGridCtrl { | |
| constructor($scope, angularServices, coreServices, $element) { | |
| const { $window, $timeout, $filter, $compile} = angularServices; | |
| const { shiftKey, fileType, color } = coreServices; | |
| this.$scope = $scope; | |
| this.$element = $element; | |
| this.$window = $window; | |
| this.$timeout = $timeout; | |
| this.$filter = $filter; | |
| this.$compile = $compile; | |
| this.shiftKey = shiftKey; | |
| this.fileType = fileType; | |
| this.color = color; | |
| const grid = $element.find('vaadin-grid')[0]; | |
| this.grid = grid; | |
| grid.rowClassGenerator = this.rowClassGenerator.bind(this); | |
| grid.columns = [ | |
| { | |
| name: 'name', | |
| hidable: true, | |
| hidingToggleText: 'Name', | |
| renderer: this.nameRenderer.bind(this) | |
| // resizable throws a funky error. uncomment to see what i mean. | |
| //resizable: true | |
| }, | |
| { | |
| name: 'lastModified', | |
| hidable: true, | |
| hidingToggleText: 'Last Modified', | |
| renderer: this.dateRenderer.bind(this) | |
| }, | |
| { | |
| name: 'created', | |
| hidable: true, | |
| hidingToggleText: 'Created', | |
| renderer: this.dateRenderer.bind(this) | |
| } | |
| ]; | |
| grid.then(() => { | |
| //setTimeout(() => { | |
| console.log('setting sortable to true'); | |
| grid.columns.forEach(column => column.sortable = true); | |
| grid.sortOrder = [ | |
| { column: 0, direction: 'asc' } | |
| ]; | |
| //}, 1000); | |
| }); | |
| this.selectedIndices = []; | |
| this.selectionListener = () => { | |
| this.selectedIndices = grid.selection.selected(); | |
| $timeout(); | |
| }; | |
| grid.addEventListener('selected-items-changed', this.selectionListener); | |
| grid.addEventListener('sort-order-changed', (e) => { | |
| console.log('sort-order-changed'); | |
| const columnIndex = grid.sortOrder[0].column; | |
| const columnName = grid.columns[columnIndex].name; | |
| const direction = grid.sortOrder[0].direction; | |
| this.query.order = direction === 'asc' ? | |
| columnName : | |
| '-' + columnName; | |
| if (columnIndex === 0) { | |
| // sorting by name, since name is an object rather than string have to do sort manually | |
| e.preventDefault(); // prevents vaadin trying to sort | |
| this.gridItems.sort((a, b) => { | |
| return direction === 'asc' ? | |
| a.name.name.localeCompare(b.name.name) : | |
| b.name.name.localeCompare(a.name.name); | |
| }); | |
| } | |
| this.$timeout(); | |
| }); | |
| $scope.$watch(() => this.items, (newVal, oldVal) => { | |
| this.gridItems = this.items.map((item) => { | |
| return { | |
| uuid: item.uuid, | |
| name: { name: item.name, fileType: fileType.getName(item), fileIcon: fileType.getIcon(item), colorObj: fileType.getType(item).colorVal }, | |
| lastModified: item.lastModified, | |
| created: item.created | |
| }; | |
| }); | |
| }, true); | |
| $scope.$watch(() => this.gridItems, (newVal, oldVal) => { | |
| grid.items = this.gridItems; | |
| if (grid.refreshItems) { | |
| grid.refreshItems(); | |
| } | |
| }, true); | |
| $scope.$watch(() => this.selectedIndices, (newVal, oldVal) => { | |
| this.selected = newVal.map(index => this.items[index]); | |
| // support shift-click to select multiple rows at once | |
| if (newVal.length === oldVal.length + 1) { | |
| const selectedIndex = newVal[newVal.length - 1]; | |
| this.rowSelect({ item: this.items[selectedIndex] }); | |
| if (this.shiftKey.shifted && this.lastSelectedIndex !== undefined) { | |
| // select all rows between lastSelectedIndex and selectedIndex | |
| const lower = Math.min(selectedIndex, this.lastSelectedIndex); | |
| const higher = Math.max(selectedIndex, this.lastSelectedIndex); | |
| // we're about to cause the listener to fire a bunch of times unnecessarily, so remove it for the duration of the for-loop | |
| // this was observed to save as much as 500 ms for a large shift-select operation | |
| grid.removeEventListener('selected-items-changed', this.selectionListener); | |
| for (let i = lower; i <= higher; i++) { | |
| if (!newVal.includes(i)) { | |
| grid.selection.select(i); | |
| } | |
| } | |
| grid.addEventListener('selected-items-changed', this.selectionListener); | |
| this.selectionListener(); // fire this listener once, manually, since it was disabled above | |
| } | |
| this.lastSelectedIndex = selectedIndex; | |
| } | |
| }, true); | |
| } | |
| dateRenderer(cell) { | |
| cell.element.innerHTML = this.$filter('fromNow')(cell.data); | |
| cell.element.classList.add('date-cell'); | |
| }; | |
| // alternate nameRenderer with much better performance but no md-icon | |
| //nameRenderer(cell) { | |
| //cell.element.innerHTML = cell.data.name; | |
| //} | |
| nameRenderer(cell) { | |
| const scope = this.$scope.$new(); | |
| scope.fileName = cell.data.name; | |
| scope.fileType = cell.data.fileType; | |
| scope.fileIcon = cell.data.fileIcon; | |
| scope.color = `rgb(${ this.color.map[cell.data.colorObj[0]][cell.data.colorObj[1] - 400].value.join(', ') })`; | |
| const tpl = ` | |
| <span layout="row" layout-align="start center"> | |
| <md-icon | |
| size="lg" | |
| md-svg-icon="{{:: fileIcon }}" | |
| alt="{{:: fileType }}" | |
| ng-style="{ color: color }"> | |
| </md-icon> | |
| <span> {{:: fileName.replace('.fabric.json', '') }}</span> | |
| </span>`; | |
| const el = this.$compile(tpl)(scope); | |
| cell.element.innerHTML = ''; | |
| angular.element(cell.element).append(el); | |
| scope.$digest(); | |
| } | |
| rowClassGenerator(row) { | |
| const data = row.data; | |
| const index = row.index; | |
| // don't use addEventListener because this rowClassGenerator function gets called many times per row | |
| row.element.onclick = () => { | |
| // we want clicking on rows to select them as well, so have to do it manually since the vaadin grid doesn't support it | |
| if (this.selectedIndices.length === 0) { | |
| this.grid.selection.select(index); | |
| } else if (this.selectedIndices.length === 1 && this.selectedIndices.includes(index)) { | |
| this.grid.selection.deselect(index); | |
| } else if (this.selectedIndices.length === 1 && !this.selectedIndices.includes(index)) { | |
| if (!this.shiftKey.shifted) { | |
| this.grid.selection.clear(); | |
| } | |
| this.grid.selection.select(index); | |
| } else { | |
| this.selectedIndices.includes(index) ? | |
| this.grid.selection.deselect(index) : | |
| this.grid.selection.select(index); | |
| } | |
| this.rowClick({ | |
| clickedItem: this.items.find(item => item.uuid === data.uuid) | |
| }); | |
| this.$timeout(); | |
| }.bind(this); | |
| return ''; | |
| }; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment