show/hide columns and load default view
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Carlos Jimenez Ruiz 2021-10-27 17:11:33 +02:00
parent c976f1ed07
commit b27a443729
9 changed files with 188 additions and 19 deletions

View File

@ -7,8 +7,7 @@ module.exports = function(Self) {
required: true,
description: `Code of the table you ask its configuration`,
http: {source: 'body'}
}
],
}],
returns: {
type: 'object',
root: true
@ -29,6 +28,6 @@ module.exports = function(Self) {
config.userFk = ctx.req.accessToken.userId;
return await Self.app.models.UserConfigView.create(config);
return Self.app.models.UserConfigView.create(config);
};
};

View File

@ -29,6 +29,9 @@
"ChatConfig": {
"dataSource": "vn"
},
"DefaultViewConfig": {
"dataSource": "vn"
},
"Delivery": {
"dataSource": "vn"
},

View File

@ -0,0 +1,25 @@
{
"name": "DefaultViewConfig",
"base": "VnModel",
"options": {
"mysql": {
"table": "salix.defaultViewConfig"
}
},
"properties": {
"tableCode": {
"id": true,
"type": "string",
"required": true
},
"columns": {
"type": "object"
}
},
"acls": [{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}]
}

View File

@ -0,0 +1,6 @@
CREATE TABLE `salix`.`defaultViewConfig`
(
tableCode VARCHAR(25) not null,
columns JSON not null
)
comment 'The default configuration of columns for views';

View File

@ -2,10 +2,9 @@
<vn-horizontal>
<div class="actions-left">
<vn-button icon="view_column"
ng-click="$ctrl.shownColumns()"
ng-click="smartTableColumns.show($event)"
vn-tooltip="Shown columns">
</vn-button>
<div ng-transclude="actions"></div> <!-- transcluded actions -->
</div>
<div class="actions-right">
@ -32,7 +31,6 @@
vn-tooltip="Save data">
</vn-button>
</div>
<div class="button-group">
<vn-button icon="refresh"
ng-click="$ctrl.model.refresh()"
@ -61,3 +59,29 @@
question="Are you sure you want to continue?"
message="Remove selected rows">
</vn-confirm>
<vn-crud-model
vn-id="userViewModel"
url="UserConfigViews"
link="{tableCode: $ctrl.viewConfigId, userFk: $ctrl.currentUserId}"
data="$ctrl.viewConfig"
auto-load="true">
</vn-crud-model>
<vn-popover class="modal-form" vn-id="smart-table-columns" message="Fields to show">
<tpl-body>
<div class="vn-pa-md">
<vn-horizontal ng-repeat="column in $ctrl.columns">
<vn-check vn-one
label="{{column.caption}}"
ng-model="$ctrl.viewConfig[0].configuration[column.field]">
</vn-check>
</vn-horizontal>
<vn-horizontal>
<vn-button
label="Save"
ng-click="$ctrl.saveViewConfig()">
</vn-button>
</vn-horizontal>
</div>
</tpl-body>
</vn-popover>

View File

@ -2,12 +2,15 @@ import ngModule from '../../module';
import Component from '../../lib/component';
import {buildFilter} from 'vn-loopback/util/filter';
import './style.scss';
import angular from 'angular';
export default class SmartTable extends Component {
constructor($element, $, $transclude) {
super($element, $);
this.currentUserId = window.localStorage.currentUserWorkerId;
this.$transclude = $transclude;
this.sortCriteria = [];
this.columns = [];
this.autoSave = false;
}
@ -23,6 +26,52 @@ export default class SmartTable extends Component {
}
}
get viewConfigId() {
return this._viewConfigId;
}
set viewConfigId(value) {
this._viewConfigId = value;
if (value) {
this.defaultViewConfig = {};
const url = 'DefaultViewConfigs';
this.$http.get(url, {where: {tableCode: value}})
.then(res => {
if (res && res.data.length) {
const columns = res.data[0].columns;
this.defaultViewConfig = columns;
}
});
}
}
get viewConfig() {
return this._viewConfig;
}
set viewConfig(value) {
this._viewConfig = value;
if (!value) return;
if (!value.length) {
const userViewModel = this.$.userViewModel;
for (const column of this.columns) {
if (this.defaultViewConfig[column.field] == undefined)
this.defaultViewConfig[column.field] = true;
}
userViewModel.insert({
userFk: this.currentUserId,
tableConfig: this.viewConfigId,
configuration: this.defaultViewConfig ? this.defaultViewConfig : {}
});
}
this.applyViewConfig();
}
get checkedRows() {
const model = this.model;
if (model && model.data)
@ -31,18 +80,65 @@ export default class SmartTable extends Component {
return null;
}
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());
}
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));
}
this.$.$on('$destroy', () => {
if (this.$.css && styleElement)
styleElement.parentNode.removeChild(styleElement);
});
}
registerColumns() {
const header = this.element.querySelector('thead > tr');
if (!header) return;
const columns = header.querySelectorAll('th');
// Click handler
for (let column of columns) {
for (const [index, column] of columns.entries()) {
const field = column.getAttribute('field');
if (field)
if (field) {
const columnElement = angular.element(column);
const caption = columnElement.text().trim();
this.columns.push({field, caption, index});
column.addEventListener('click', () => this.orderHandler(column));
}
}
}
// Creo que se puede hacer directamente desde ng-transclude
transclude() {
@ -157,7 +253,6 @@ export default class SmartTable extends Component {
}
filterSanitizer(field) {
// tenemos que eliminar ands vacios al ir borrando filtros
const userFilter = this.model.userFilter;
const userParams = this.model.userParams;
const where = userFilter && userFilter.where;
@ -199,15 +294,17 @@ export default class SmartTable extends Component {
return {userFilter, userParams};
}
removeFilter(field) {
//
removeFilter() {
this.model.applyFilter(userFilter, userParams);
}
createRow() {
this.model.insert({
nickname: 'New row'
});
let data = {};
if (this.defaultNewData)
data = this.defaultNewData();
this.model.insert(data);
}
deleteAll() {
@ -244,7 +341,9 @@ ngModule.vnComponent('smartTable', {
},
bindings: {
model: '<?',
viewConfigId: '@?',
autoSave: '<?',
exprBuilder: '&?'
exprBuilder: '&?',
defaultNewData: '&?'
}
});

View File

@ -1,5 +1,11 @@
<vn-crud-model vn-id="model" url="{{$ctrl.url}}" filter="$ctrl.filter" link="{originFk: $ctrl.originId}"
data="$ctrl.logs" limit="20" auto-load="true">
<vn-crud-model
vn-id="model"
url="{{$ctrl.url}}"
filter="$ctrl.filter"
link="{originFk: $ctrl.originId}"
data="$ctrl.logs"
limit="20"
auto-load="true">
</vn-crud-model>
<vn-data-viewer model="model" class="vn-w-xl">
<vn-card>

View File

@ -11,9 +11,10 @@
<!-- To access table component should be a nested component -->
<smart-table
model="model"
view-config-id="ticketIndex"
auto-save="true"
expr-builder="$ctrl.exprBuilder(param, value)"
>
default-new-data="$ctrl.defaultNewData()">
<slot-actions>
<vn-button icon="info"
ng-click="$ctrl.test()"

View File

@ -128,6 +128,12 @@ export default class Controller extends Section {
this.$.summary.show();
}
defaultNewData() {
return {
nickname: 'my nickname',
};
}
exprBuilder(param, value) {
switch (param) {
case 'nickname':