show/hide columns and load default view
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
parent
c976f1ed07
commit
b27a443729
|
@ -7,8 +7,7 @@ module.exports = function(Self) {
|
||||||
required: true,
|
required: true,
|
||||||
description: `Code of the table you ask its configuration`,
|
description: `Code of the table you ask its configuration`,
|
||||||
http: {source: 'body'}
|
http: {source: 'body'}
|
||||||
}
|
}],
|
||||||
],
|
|
||||||
returns: {
|
returns: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
root: true
|
root: true
|
||||||
|
@ -29,6 +28,6 @@ module.exports = function(Self) {
|
||||||
|
|
||||||
config.userFk = ctx.req.accessToken.userId;
|
config.userFk = ctx.req.accessToken.userId;
|
||||||
|
|
||||||
return await Self.app.models.UserConfigView.create(config);
|
return Self.app.models.UserConfigView.create(config);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
"ChatConfig": {
|
"ChatConfig": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"DefaultViewConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Delivery": {
|
"Delivery": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -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';
|
|
@ -2,10 +2,9 @@
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<div class="actions-left">
|
<div class="actions-left">
|
||||||
<vn-button icon="view_column"
|
<vn-button icon="view_column"
|
||||||
ng-click="$ctrl.shownColumns()"
|
ng-click="smartTableColumns.show($event)"
|
||||||
vn-tooltip="Shown columns">
|
vn-tooltip="Shown columns">
|
||||||
</vn-button>
|
</vn-button>
|
||||||
|
|
||||||
<div ng-transclude="actions"></div> <!-- transcluded actions -->
|
<div ng-transclude="actions"></div> <!-- transcluded actions -->
|
||||||
</div>
|
</div>
|
||||||
<div class="actions-right">
|
<div class="actions-right">
|
||||||
|
@ -32,7 +31,6 @@
|
||||||
vn-tooltip="Save data">
|
vn-tooltip="Save data">
|
||||||
</vn-button>
|
</vn-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="button-group">
|
<div class="button-group">
|
||||||
<vn-button icon="refresh"
|
<vn-button icon="refresh"
|
||||||
ng-click="$ctrl.model.refresh()"
|
ng-click="$ctrl.model.refresh()"
|
||||||
|
@ -60,4 +58,30 @@
|
||||||
on-accept="$ctrl.deleteAll()"
|
on-accept="$ctrl.deleteAll()"
|
||||||
question="Are you sure you want to continue?"
|
question="Are you sure you want to continue?"
|
||||||
message="Remove selected rows">
|
message="Remove selected rows">
|
||||||
</vn-confirm>
|
</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>
|
|
@ -2,12 +2,15 @@ import ngModule from '../../module';
|
||||||
import Component from '../../lib/component';
|
import Component from '../../lib/component';
|
||||||
import {buildFilter} from 'vn-loopback/util/filter';
|
import {buildFilter} from 'vn-loopback/util/filter';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
import angular from 'angular';
|
||||||
|
|
||||||
export default class SmartTable extends Component {
|
export default class SmartTable extends Component {
|
||||||
constructor($element, $, $transclude) {
|
constructor($element, $, $transclude) {
|
||||||
super($element, $);
|
super($element, $);
|
||||||
|
this.currentUserId = window.localStorage.currentUserWorkerId;
|
||||||
this.$transclude = $transclude;
|
this.$transclude = $transclude;
|
||||||
this.sortCriteria = [];
|
this.sortCriteria = [];
|
||||||
|
this.columns = [];
|
||||||
this.autoSave = false;
|
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() {
|
get checkedRows() {
|
||||||
const model = this.model;
|
const model = this.model;
|
||||||
if (model && model.data)
|
if (model && model.data)
|
||||||
|
@ -31,16 +80,63 @@ export default class SmartTable extends Component {
|
||||||
return null;
|
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() {
|
registerColumns() {
|
||||||
const header = this.element.querySelector('thead > tr');
|
const header = this.element.querySelector('thead > tr');
|
||||||
if (!header) return;
|
if (!header) return;
|
||||||
const columns = header.querySelectorAll('th');
|
const columns = header.querySelectorAll('th');
|
||||||
|
|
||||||
// Click handler
|
// Click handler
|
||||||
for (let column of columns) {
|
for (const [index, column] of columns.entries()) {
|
||||||
const field = column.getAttribute('field');
|
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));
|
column.addEventListener('click', () => this.orderHandler(column));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +253,6 @@ export default class SmartTable extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
filterSanitizer(field) {
|
filterSanitizer(field) {
|
||||||
// tenemos que eliminar ands vacios al ir borrando filtros
|
|
||||||
const userFilter = this.model.userFilter;
|
const userFilter = this.model.userFilter;
|
||||||
const userParams = this.model.userParams;
|
const userParams = this.model.userParams;
|
||||||
const where = userFilter && userFilter.where;
|
const where = userFilter && userFilter.where;
|
||||||
|
@ -199,15 +294,17 @@ export default class SmartTable extends Component {
|
||||||
return {userFilter, userParams};
|
return {userFilter, userParams};
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFilter(field) {
|
removeFilter() {
|
||||||
//
|
|
||||||
this.model.applyFilter(userFilter, userParams);
|
this.model.applyFilter(userFilter, userParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
createRow() {
|
createRow() {
|
||||||
this.model.insert({
|
let data = {};
|
||||||
nickname: 'New row'
|
|
||||||
});
|
if (this.defaultNewData)
|
||||||
|
data = this.defaultNewData();
|
||||||
|
|
||||||
|
this.model.insert(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAll() {
|
deleteAll() {
|
||||||
|
@ -244,7 +341,9 @@ ngModule.vnComponent('smartTable', {
|
||||||
},
|
},
|
||||||
bindings: {
|
bindings: {
|
||||||
model: '<?',
|
model: '<?',
|
||||||
|
viewConfigId: '@?',
|
||||||
autoSave: '<?',
|
autoSave: '<?',
|
||||||
exprBuilder: '&?'
|
exprBuilder: '&?',
|
||||||
|
defaultNewData: '&?'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
<vn-crud-model vn-id="model" url="{{$ctrl.url}}" filter="$ctrl.filter" link="{originFk: $ctrl.originId}"
|
<vn-crud-model
|
||||||
data="$ctrl.logs" limit="20" auto-load="true">
|
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-crud-model>
|
||||||
<vn-data-viewer model="model" class="vn-w-xl">
|
<vn-data-viewer model="model" class="vn-w-xl">
|
||||||
<vn-card>
|
<vn-card>
|
||||||
|
|
|
@ -11,9 +11,10 @@
|
||||||
<!-- To access table component should be a nested component -->
|
<!-- To access table component should be a nested component -->
|
||||||
<smart-table
|
<smart-table
|
||||||
model="model"
|
model="model"
|
||||||
|
view-config-id="ticketIndex"
|
||||||
auto-save="true"
|
auto-save="true"
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||||
>
|
default-new-data="$ctrl.defaultNewData()">
|
||||||
<slot-actions>
|
<slot-actions>
|
||||||
<vn-button icon="info"
|
<vn-button icon="info"
|
||||||
ng-click="$ctrl.test()"
|
ng-click="$ctrl.test()"
|
||||||
|
|
|
@ -128,6 +128,12 @@ export default class Controller extends Section {
|
||||||
this.$.summary.show();
|
this.$.summary.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultNewData() {
|
||||||
|
return {
|
||||||
|
nickname: 'my nickname',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'nickname':
|
case 'nickname':
|
||||||
|
|
Loading…
Reference in New Issue