import ngModule from '../module'; import template from './smart-table.html'; import './smart-table.scss'; /** * Directive to hide/show selected columns of a table, don't use with rowspan. * Property smart-table-ignore ignores one or more vn-th with prop field. */ directive.$inject = ['$http', '$compile', 'vnApp', '$translate']; export function directive($http, $compile, vnApp, $translate) { function getHeaderList($element, $scope) { let filtrableHeaders = $element[0].querySelectorAll('vn-th[field]:not([smart-table-ignore])'); let headerList = Array.from(filtrableHeaders); let ids = []; let titles = {}; headerList.forEach(header => { let id = header.getAttribute('field'); ids.push(id); titles[id] = header.innerText || id.charAt(0).toUpperCase() + id.slice(1); }); $scope.fields = ids; $scope.titles = titles; $scope.allHeaders = Array.from($element[0].querySelectorAll('vn-th')); return headerList; } function getTableConfig(tableCode) { return $http.get(`UserConfigViews/getConfig?tableCode=${tableCode}`); } function createViewConfig(config, fields) { fields.forEach(field => { if (config.configuration[field] == null) config.configuration[field] = true; }); } function addHideClass($scope, headerList, userConfig) { let selectors = []; Object.keys(userConfig.configuration).forEach(key => { let index; if (userConfig.configuration[key] === false) { index = $scope.allHeaders.findIndex(el => { return el.getAttribute('field') == key; }); let baseSelector = `vn-table[vn-smart-table=${userConfig.tableCode}] > div`; selectors.push(`${baseSelector} vn-thead > vn-tr > vn-th:nth-child(${index + 1})`); selectors.push(`${baseSelector} vn-tbody > vn-tr > vn-td:nth-child(${index + 1})`); selectors.push(`${baseSelector} vn-tbody > .vn-tr > vn-td:nth-child(${index + 1})`); } }); if (document.querySelector('style[id="smart-table"]')) { let child = document.querySelector('style[id="smart-table"]'); child.parentNode.removeChild(child); } if (selectors.length) { let rule = selectors.join(', ') + '{display: none;}'; $scope.css = document.createElement('style'); $scope.css.setAttribute('id', 'smart-table'); document.head.appendChild($scope.css); $scope.css.appendChild(document.createTextNode(rule)); } $scope.$on('$destroy', () => { if ($scope.css && document.querySelector('style[id="smart-table"]')) { let child = document.querySelector('style[id="smart-table"]'); child.parentNode.removeChild(child); } }); } function saveConfiguration(tableConfiguration) { tableConfiguration.configuration = JSON.parse(JSON.stringify(tableConfiguration.configuration)); return $http.post(`UserConfigViews/save`, tableConfiguration); } return { restrict: 'A', link: async function($scope, $element, $attrs) { let cTemplate = $compile(template)($scope)[0]; $scope.$ctrl.showSmartTable = event => { event.preventDefault(); event.stopImmediatePropagation(); $scope.smartTable.show(event.target); }; let tableCode = $attrs.vnSmartTable.trim(); let headerList = getHeaderList($element, $scope); let defaultConfigView = {tableCode: tableCode, configuration: {}}; let userView = await getTableConfig(tableCode); let config = userView.data || defaultConfigView; $scope.tableConfiguration = config; createViewConfig(config, $scope.fields); addHideClass($scope, headerList, config); let table = document.querySelector(`vn-table[vn-smart-table=${tableCode}]`); table.insertBefore(cTemplate, table.firstChild); $scope.$ctrl.saveConfiguration = async tableConfiguration => { let newConfig = await saveConfiguration(tableConfiguration); vnApp.showSuccess($translate.instant('Data saved!')); addHideClass($scope, headerList, newConfig.data); $scope.smartTable.hide(); }; } }; } ngModule.directive('vnSmartTable', directive);