import ngModule from '../../module'; import Component from '../../lib/component'; import {buildFilter} from 'vn-loopback/util/filter'; import angular from 'angular'; import {camelToKebab} from '../../lib/string'; import './style.scss'; import './table.scss'; export default class SmartTable extends Component { constructor($element, $, $transclude) { super($element, $); this.currentUserId = window.localStorage.currentUserWorkerId; this.$transclude = $transclude; this.sortCriteria = []; this.$inputsScope; this.columns = []; this.autoSave = false; this.transclude(); } $onDestroy() { const styleElement = document.querySelector('style[id="smart-table"]'); if (this.$.css && styleElement) styleElement.parentNode.removeChild(styleElement); } get options() { return this._options; } set options(options) { this._options = options; if (!options) return; const activeButtons = options.activeButtons; const missingId = activeButtons && activeButtons.shownColumns && !this.viewConfigId; if (missingId) throw new Error('vnSmartTable: View identifier not defined'); } get model() { return this._model; } set model(value) { this._model = value; if (value) { this.$.model = value; this.defaultOrder(); } } getDefaultViewConfig() { const url = 'DefaultViewConfigs'; const filter = {where: {tableCode: this.viewConfigId}}; return this.$http.get(url, {filter}) .then(res => { if (res && res.data.length) return res.data[0].columns; }); } get viewConfig() { return this._viewConfig; } set viewConfig(value) { this._viewConfig = value; if (!value) return; if (!value.length) { this.getDefaultViewConfig().then(columns => { const defaultViewConfig = columns ? columns : {}; const userViewModel = this.$.userViewModel; for (const column of this.columns) { if (defaultViewConfig[column.field] == undefined) defaultViewConfig[column.field] = true; } userViewModel.insert({ userFk: this.currentUserId, tableConfig: this.viewConfigId, configuration: defaultViewConfig }); }).finally(() => this.applyViewConfig()); } else this.applyViewConfig(); } get checkedRows() { const model = this.model; if (model && model.data) return model.data.filter(row => row.$checked); return null; } get checkAll() { return this._checkAll; } set checkAll(value) { this._checkAll = value; if (value !== undefined) { const shownColumns = this.viewConfig[0].configuration; for (let param in shownColumns) shownColumns[param] = value; } } transclude() { const slotTable = this.element.querySelector('#table'); this.$transclude($clone => { const table = $clone[0]; slotTable.appendChild(table); this.registerColumns(); this.emptyDataRows(); }, null, 'table'); } saveViewConfig() { const userViewModel = this.$.userViewModel; const [viewConfig] = userViewModel.data; viewConfig.configuration = Object.assign({}, viewConfig.configuration); userViewModel.save() .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))) .then(() => this.applyViewConfig()) .then(() => this.$.smartTableColumns.hide()); } applyViewConfig() { const userViewModel = this.$.userViewModel; const [viewConfig] = userViewModel.data; const selectors = []; for (const column of this.columns) { if (viewConfig.configuration[column.field] == false) { const baseSelector = `smart-table[view-config-id="${this.viewConfigId}"] table`; selectors.push(`${baseSelector} thead > tr > th:nth-child(${column.index + 1})`); selectors.push(`${baseSelector} tbody > tr > td:nth-child(${column.index + 1})`); } } const styleElement = document.querySelector('style[id="smart-table"]'); if (styleElement) styleElement.parentNode.removeChild(styleElement); if (selectors.length) { const rule = selectors.join(', ') + '{display: none}'; this.$.css = document.createElement('style'); this.$.css.setAttribute('id', 'smart-table'); document.head.appendChild(this.$.css); this.$.css.appendChild(document.createTextNode(rule)); } } defaultOrder() { const order = this.model.order; if (!order) return; const orderFields = order.split(', '); for (const fieldString of orderFields) { const field = fieldString.split(' '); const fieldName = field[0]; let sortType = 'ASC'; if (field.length === 2) sortType = field[1]; const column = this.columns.find(column => column.field == fieldName); if (column) { this.sortCriteria.push({field: fieldName, sortType: sortType}); const isASC = sortType == 'ASC'; const isDESC = sortType == 'DESC'; if (isDESC) { column.element.classList.remove('asc'); column.element.classList.add('desc'); } if (isASC) { column.element.classList.remove('desc'); column.element.classList.add('asc'); } } } } registerColumns() { const header = this.element.querySelector('thead > tr'); if (!header) return; const columns = header.querySelectorAll('th'); // Click handler for (const [index, column] of columns.entries()) { const field = column.getAttribute('field'); if (field) { const columnElement = angular.element(column); const caption = columnElement.text().trim(); this.columns.push({field, caption, index, element: column}); column.addEventListener('click', () => this.orderHandler(column)); } } } emptyDataRows() { const header = this.element.querySelector('thead > tr'); const columns = header.querySelectorAll('th'); const tbody = this.element.querySelector('tbody'); if (tbody) { const noSearch = this.$compile(`