salix/front/core/components/smart-table/index.js

142 lines
3.7 KiB
JavaScript
Raw Normal View History

2021-10-23 12:26:42 +00:00
import ngModule from '../../module';
import Component from '../../lib/component';
import './style.scss';
export default class SmartTable extends Component {
constructor($element, $, $transclude) {
super($element, $);
this.$transclude = $transclude;
2021-10-25 12:20:17 +00:00
this.sortCriteria = [];
2021-10-25 15:18:57 +00:00
this.autoSave = false;
2021-10-23 12:26:42 +00:00
}
get model() {
return this._model;
}
set model(value) {
this._model = value;
if (value) {
this.$.model = value;
this.transclude();
}
}
2021-10-25 15:18:57 +00:00
get checkedRows() {
const model = this.model;
if (model && model.data)
return model.data.filter(row => row.$checked);
return null;
}
2021-10-23 12:26:42 +00:00
registerColumns() {
const header = this.element.querySelector('thead > tr');
if (!header) return;
const columns = header.querySelectorAll('th');
// Click handler
for (let column of columns) {
const field = column.getAttribute('field');
if (field)
column.addEventListener('click', () => this.orderHandler(column));
}
}
// Creo que se puede hacer directamente desde ng-transclude
transclude() {
const slotTable = this.element.querySelector('#table');
this.$transclude(($clone, $scope) => {
const table = $clone[0];
$scope.hasChanges = this.hasChanges;
slotTable.appendChild(table);
this.registerColumns();
}, null, 'table');
}
orderHandler(element) {
const field = element.getAttribute('field');
2021-10-25 12:20:17 +00:00
const existingCriteria = this.sortCriteria.find(criteria => {
return criteria.field == field;
});
2021-10-26 07:18:31 +00:00
const isASC = existingCriteria && existingCriteria.sortType == 'ASC';
const isDESC = existingCriteria && existingCriteria.sortType == 'DESC';
2021-10-25 12:20:17 +00:00
if (!existingCriteria) {
this.sortCriteria.push({field: field, sortType: 'ASC'});
element.classList.remove('desc');
element.classList.add('asc');
}
2021-10-26 07:18:31 +00:00
if (isDESC) {
2021-10-25 12:20:17 +00:00
this.sortCriteria.splice(this.sortCriteria.findIndex(criteria => {
return criteria.field == field;
}), 1);
element.classList.remove('desc');
element.classList.remove('asc');
}
2021-10-26 07:18:31 +00:00
if (isASC) {
2021-10-25 12:20:17 +00:00
existingCriteria.sortType = 'DESC';
element.classList.remove('asc');
element.classList.add('desc');
}
this.applySort();
}
applySort() {
let order = this.sortCriteria.map(criteria => `${criteria.field} ${criteria.sortType}`);
order = order.join(', ');
if (order)
this.model.order = order;
this.model.refresh();
2021-10-23 12:26:42 +00:00
}
createRow() {
this.model.insert({
nickname: 'New row'
});
}
deleteAll() {
2021-10-26 07:18:31 +00:00
const checkedRows = this.checkedRows;
for (let row of checkedRows)
2021-10-25 15:18:57 +00:00
this.model.removeRow(row);
2021-10-23 12:26:42 +00:00
if (this.autoSave)
2021-10-24 11:35:37 +00:00
this.saveAll();
2021-10-23 12:26:42 +00:00
}
saveAll() {
const model = this.model;
2021-10-25 15:18:57 +00:00
2021-10-23 12:26:42 +00:00
if (!model.isChanged)
return this.vnApp.showError(this.$t('No changes to save'));
this.model.save()
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
}
hasChanges() {
return true;
}
}
SmartTable.$inject = ['$element', '$scope', '$transclude'];
ngModule.vnComponent('smartTable', {
template: require('./index.html'),
controller: SmartTable,
transclude: {
table: '?slotTable',
actions: '?slotActions'
},
bindings: {
model: '<?',
autoSave: '<?'
}
});