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,
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
"ChatConfig": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"DefaultViewConfig": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Delivery": {
|
||||
"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>
|
||||
<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()"
|
||||
|
@ -60,4 +58,30 @@
|
|||
on-accept="$ctrl.deleteAll()"
|
||||
question="Are you sure you want to continue?"
|
||||
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 {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,16 +80,63 @@ 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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: '&?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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()"
|
||||
|
|
|
@ -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':
|
||||
|
|
Loading…
Reference in New Issue