import './rows/renderer/Head' import './rows/renderer/Row' import './filter/ColumnFilter' import './filter/RowFilter' import {UnitOfWorkTracker} from '../mixins/UnitOfWorkTracker' import {RowState} from './rows/RowObjectBase' const TEMPLATE =`
`; let PillarTable = Vue.component('pillar-table-base', { template: TEMPLATE, mixins: [UnitOfWorkTracker], // columnFactory, // rowsSource, props: { projectId: String, selectedIds: Array, canChangeSelectionCB: { type: Function, default: () => true }, canMultiSelect: { type: Boolean, default: true }, }, data: function() { return { columns: [], visibleColumns: [], visibleRowObjects: [], rowsSource: {}, isInitialized: false, compareRows: (row1, row2) => 0 } }, computed: { rowObjects() { return this.rowsSource.rowObjects || []; }, sortedRowObjects() { return this.rowObjects.concat().sort(this.compareRows); }, rowAndChildObjects() { let all = []; for (const row of this.rowObjects) { all.push(row, ...row.getChildObjects()); } return all; }, selectedItems() { return this.rowAndChildObjects.filter(it => it.isSelected) .map(it => it.underlyingObject); } }, watch: { selectedIds(newValue) { this.rowAndChildObjects.forEach(item => { item.isSelected = newValue.includes(item.getId()); }); }, selectedItems(newValue, oldValue) { this.$emit('selectItemsChanged', newValue); }, isInitialized(newValue) { if (newValue) { this.$emit('isInitialized'); } } }, created() { let columnFactory = new this.$options.columnFactory(this.projectId); this.rowsSource = new this.$options.rowsSource(this.projectId); let rowState = new RowState(this.selectedIds); this.unitOfWork( Promise.all([ columnFactory.thenGetColumns(), this.rowsSource.thenFetchObjects() ]) .then((resp) => { this.columns = resp[0]; return this.rowsSource.thenInit(); }) .then(() => { this.rowAndChildObjects.forEach(rowState.applyState.bind(rowState)); this.isInitialized = true; }) ); }, methods: { onVisibleColumnsChanged(visibleColumns) { this.visibleColumns = visibleColumns; }, onVisibleRowObjectsChanged(visibleRowObjects) { this.visibleRowObjects = visibleRowObjects; }, onSort(column, direction) { function compareRows(r1, r2) { return column.compareRows(r1, r2) * direction; } this.compareRows = compareRows; }, onItemClicked(clickEvent, itemId) { if(!this.canChangeSelectionCB()) return; if(this.isMultiToggleClick(clickEvent) && this.canMultiSelect) { let slectedIdsWithoutClicked = this.selectedIds.filter(id => id !== itemId); if (slectedIdsWithoutClicked.length < this.selectedIds.length) { this.selectedIds = slectedIdsWithoutClicked; } else { this.selectedIds = [itemId, ...this.selectedIds]; } } else if(this.isSelectBetween(clickEvent) && this.canMultiSelect) { if (this.selectedIds.length > 0) { let betweenA = this.selectedIds[this.selectedIds.length -1]; let betweenB = itemId; this.selectedIds = this.rowsBetween(betweenA, betweenB).map(it => it.getId()); } else { this.selectedIds = [itemId]; } } else { if (this.selectedIds.length === 1 && this.selectedIds[0] === itemId) { this.selectedIds = []; } else { this.selectedIds = [itemId]; } } }, isSelectBetween(clickEvent) { return clickEvent.shiftKey; }, isMultiToggleClick(clickEvent) { return clickEvent.ctrlKey || clickEvent.metaKey; // Mac command key }, rowsBetween(id1, id2) { let hasFoundFirst = false; let hasFoundLast = false; return this.visibleRowObjects.filter((it) => { if (hasFoundLast) return false; if (!hasFoundFirst) { hasFoundFirst = [id1, id2].includes(it.getId()); return hasFoundFirst; } hasFoundLast = [id1, id2].includes(it.getId()); return true; }) } } }); export { PillarTable }