Merge pull request '2176-contextmenu' (#302) from 2176-contextmenu into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-by: Carlos Jimenez <carlosjr@verdnatura.es>
This commit is contained in:
Carlos Jimenez Ruiz 2020-06-08 12:59:59 +00:00
commit d8593ea3e0
12 changed files with 272 additions and 57 deletions

View File

@ -0,0 +1,5 @@
<section vn-id="contextmenu">
<vn-menu vn-id="menu">
<div ng-transclude="menu"></div>
</vn-menu>
</section>

View File

@ -0,0 +1,176 @@
import ngModule from '../../module';
import './style.scss';
export default class Contextmenu {
constructor($element, $, $transclude) {
this.$element = $element;
this.element = $element[0];
this.$ = $;
this.$transclude = $transclude;
}
get targets() {
return this._targets;
}
set targets(value) {
this._targets = value;
if (!value) return;
for (let selector of value) {
const target = document.querySelector(selector);
if (!target) continue;
target.addEventListener('contextmenu', event => {
this.target = event.target;
if (!event.defaultPrevented)
event.preventDefault();
if (!this.isFilterEnabled()) return;
const parent = this.$.contextmenu;
parent.style.top = event.pageY + 'px';
parent.style.left = event.pageX + 'px';
this.$.menu.show(parent);
});
}
}
get row() {
if (!this.target) return null;
return this.target.closest('vn-tr, .vn-tr');
}
get rowIndex() {
if (!this.row) return null;
const table = this.row.closest('vn-table, .vn-table');
const tBody = table.querySelector('vn-tbody, .vn-tbody');
const rows = tBody.querySelectorAll('vn-tr, .vn-tr');
return Array.from(rows).findIndex(
rowItem => rowItem == this.row
);
}
get rowData() {
const model = this.model;
const rowData = model.data[this.rowIndex];
return rowData;
}
get cell() {
if (!this.target) return null;
return this.target.closest('vn-td, .vn-td');
}
get cellIndex() {
if (!this.row) return null;
const cells = this.row.querySelectorAll('vn-td, .vn-td');
return Array.from(cells).findIndex(
cellItem => cellItem == this.cell
);
}
get rowHeader() {
if (!this.row) return null;
const table = this.row.closest('vn-table, .vn-table');
const headerCells = table && table.querySelectorAll('vn-thead vn-th');
const headerCell = headerCells && headerCells[this.cellIndex];
return headerCell;
}
/**
* Selected model field name
*
* @return {string}
*/
get fieldName() {
if (!this.rowHeader) return null;
return this.rowHeader.getAttribute('field');
}
/**
* Selected field value
*
* @return {any}
*/
get fieldValue() {
return this.rowData[this.fieldName];
}
/**
* Returns true if filter is not disabled
*
* @return {Boolean}
*/
isFilterEnabled() {
if (!this.rowHeader) return true;
const isEnabled = this.rowHeader.getAttribute('filter-enabled');
return isEnabled != 'false';
}
/**
* Returns true if filter
* by selection is allowed
*
* @return {Boolean}
*/
isFilterAllowed() {
if (!this.target) return false;
const isTableCell = this.target.closest('vn-td, .vn-td');
return isTableCell && this.fieldName;
}
/**
* Filter by current field selection
*/
filterBySelection() {
const filter = {where: {}};
filter['where'][this.fieldName] = this.fieldValue;
this.model.addFilter(filter);
}
/**
* Exclude by current field selection
*/
excludeSelection() {
const filter = {where: {}};
filter['where'][this.fieldName] = {neq: this.fieldValue};
this.model.addFilter(filter);
}
/**
* Removes all applied filters
*/
removeFilter() {
this.model.removeFilter();
}
}
Contextmenu.$inject = ['$element', '$scope', '$transclude'];
ngModule.vnComponent('vnContextmenu', {
controller: Contextmenu,
template: require('./index.html'),
bindings: {
targets: '<?',
model: '<?'
},
transclude: {
menu: '?slotMenu'
}
});

View File

@ -0,0 +1,3 @@
section[vn-id="contextmenu"] {
position: absolute
}

View File

@ -50,3 +50,4 @@ import './th';
import './treeview'; import './treeview';
import './wday-picker'; import './wday-picker';
import './datalist'; import './datalist';
import './contextmenu';

View File

@ -16,7 +16,7 @@
<vn-item <vn-item
ng-click="consumerReportDialog.show()" ng-click="consumerReportDialog.show()"
translate> translate>
Send consumer report View consumer report
</vn-item> </vn-item>
</slot-menu> </slot-menu>
<slot-body> <slot-body>

View File

@ -1,4 +1,4 @@
Simple ticket: Ticket simple Simple ticket: Ticket simple
Send consumer report: Enviar informe de consumo View consumer report: Ver informe de consumo
From date: Fecha desde From date: Fecha desde
To date: Fecha hasta To date: Fecha hasta

View File

@ -56,7 +56,7 @@
<div ng-transclude="btnTwo"> <div ng-transclude="btnTwo">
<vn-quick-link <vn-quick-link
tooltip="Invoice ticket list" tooltip="Invoice ticket list"
state="['ticket.card.summary', {id: $ctrl.invoiceOut.ref}]" state="['ticket.index', {q: $ctrl.filter}]"
icon="icon-ticket"> icon="icon-ticket">
</vn-quick-link> </vn-quick-link>
</div> </div>

View File

@ -22,6 +22,13 @@ class Controller extends Descriptor {
.then(() => this.vnApp.showSuccess(this.$t('InvoiceOut booked'))); .then(() => this.vnApp.showSuccess(this.$t('InvoiceOut booked')));
} }
get filter() {
if (this.invoiceOut)
return JSON.stringify({refFk: this.invoiceOut.ref});
return null;
}
loadData() { loadData() {
const filter = { const filter = {
include: [ include: [

View File

@ -138,22 +138,22 @@ module.exports = Self => {
switch (param) { switch (param) {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
? {'t.id': {inq: value}} ? {'id': {inq: value}}
: {'t.nickname': {like: `%${value}%`}}; : {'nickname': {like: `%${value}%`}};
case 'from': case 'from':
return {'t.shipped': {gte: value}}; return {'shipped': {gte: value}};
case 'to': case 'to':
return {'t.shipped': {lte: value}}; return {'shipped': {lte: value}};
case 'nickname': case 'nickname':
return {'t.nickname': {like: `%${value}%`}}; return {'nickname': {like: `%${value}%`}};
case 'refFk': case 'refFk':
return {'t.refFk': value}; return {'refFk': value};
case 'salesPersonFk': case 'salesPersonFk':
return {'c.salesPersonFk': value}; return {'salesPersonFk': value};
case 'provinceFk': case 'provinceFk':
return {'a.provinceFk': value}; return {'provinceFk': value};
case 'stateFk': case 'stateFk':
return {'ts.stateFk': value}; return {'stateFk': value};
case 'mine': case 'mine':
case 'myTeam': case 'myTeam':
return {'c.salesPersonFk': {inq: teamIds}}; return {'c.salesPersonFk': {inq: teamIds}};
@ -162,13 +162,13 @@ module.exports = Self => {
case 'pending': case 'pending':
if (value) { if (value) {
return {and: [ return {and: [
{'st.alertLevel': 0}, {'alertLevel': 0},
{'st.code': {neq: 'OK'}}, {'alertLevelCode': {neq: 'OK'}},
{'st.code': {neq: 'BOARDING'}} {'alertLevelCode': {neq: 'BOARDING'}}
]}; ]};
} else { } else {
return {and: [ return {and: [
{'st.alertLevel': {gt: 0}} {'alertLevel': {gt: 0}}
]}; ]};
} }
case 'id': case 'id':
@ -186,22 +186,25 @@ module.exports = Self => {
let stmt; let stmt;
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter'); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter');
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
`CREATE TEMPORARY TABLE tmp.filter `CREATE TEMPORARY TABLE tmp.filter
(INDEX (id)) (INDEX (id))
ENGINE = MEMORY ENGINE = MEMORY
SELECT * FROM (
SELECT SELECT
t.id, t.id,
t.shipped, t.shipped,
CAST(DATE(t.shipped) AS CHAR) AS shippedDate,
t.nickname, t.nickname,
t.refFk, t.refFk,
t.routeFk, t.routeFk,
t.warehouseFk, t.warehouseFk,
t.clientFk, t.clientFk,
a.provinceFk,
p.name AS province, p.name AS province,
w.name AS warehouse, w.name AS warehouse,
am.name AS agencyMode, am.name AS agencyMode,
am.id AS agencyModeFk,
st.name AS state, st.name AS state,
wk.lastName AS salesPerson, wk.lastName AS salesPerson,
ts.stateFk as stateFk, ts.stateFk as stateFk,
@ -222,7 +225,7 @@ module.exports = Self => {
LEFT JOIN state st ON st.id = ts.stateFk LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN client c ON c.id = t.clientFk LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk LEFT JOIN worker wk ON wk.id = c.salesPersonFk
LEFT JOIN account.user u ON u.id = wk.userFk`); LEFT JOIN account.user u ON u.id = wk.userFk) t`);
if (args.orderFk) { if (args.orderFk) {
stmt.merge({ stmt.merge({

View File

@ -15,14 +15,14 @@
</vn-th> </vn-th>
<vn-th></vn-th> <vn-th></vn-th>
<vn-th field="id" number>Id</vn-th> <vn-th field="id" number>Id</vn-th>
<vn-th field="salesPerson" class="expendable">Salesperson</vn-th> <vn-th field="salesPersonFk" class="expendable">Salesperson</vn-th>
<vn-th field="shipped">Date</vn-th> <vn-th field="shippedDate">Date</vn-th>
<vn-th>Hour</vn-th> <vn-th>Hour</vn-th>
<vn-th field="nickname">Alias</vn-th> <vn-th field="nickname">Alias</vn-th>
<vn-th field="province" class="expendable">Province</vn-th> <vn-th field="provinceFk" class="expendable">Province</vn-th>
<vn-th field="state" >State</vn-th> <vn-th field="stateFk" >State</vn-th>
<vn-th field="agencyMode">Agency</vn-th> <vn-th field="agencyModeFk">Agency</vn-th>
<vn-th field="warehouse">Warehouse</vn-th> <vn-th field="warehouseFk">Warehouse</vn-th>
<vn-th field="refFk" class="expendable">Invoice</vn-th> <vn-th field="refFk" class="expendable">Invoice</vn-th>
<vn-th field="zoneHour" shrink>Closure</vn-th> <vn-th field="zoneHour" shrink>Closure</vn-th>
<vn-th number>Total</vn-th> <vn-th number>Total</vn-th>
@ -151,3 +151,21 @@
<vn-client-balance-create <vn-client-balance-create
vn-id="balanceCreateDialog"> vn-id="balanceCreateDialog">
</vn-client-balance-create> </vn-client-balance-create>
<vn-contextmenu vn-id="contextmenu" targets="['vn-data-viewer']" model="model">
<slot-menu>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.filterBySelection()">
Filter by selection
</vn-item>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.excludeSelection()">
Exclude selection
</vn-item>
<vn-item translate
ng-click="contextmenu.removeFilter()" >
Remove filter
</vn-item>
</slot-menu>
</vn-contextmenu>

View File

@ -4,3 +4,6 @@ Not available: No disponible
Payment on account...: Pago a cuenta... Payment on account...: Pago a cuenta...
Closure: Cierre Closure: Cierre
You cannot make a payment on account from multiple clients: No puedes realizar un pago a cuenta de clientes diferentes You cannot make a payment on account from multiple clients: No puedes realizar un pago a cuenta de clientes diferentes
Filter by selection: Filtro por selección
Exclude selection: Excluir selección
Remove filter: Eliminar filtro

View File

@ -19,7 +19,6 @@ class Controller extends Descriptor {
const ticketsAmount = res.data.length; const ticketsAmount = res.data.length;
if (ticketsAmount) { if (ticketsAmount) {
const params = {ticketsAmount}; const params = {ticketsAmount};
console.log('ticketsAmount', res.data);
const question = $t('This zone contains tickets', params, null, null, 'sanitizeParameters'); const question = $t('This zone contains tickets', params, null, null, 'sanitizeParameters');
this.$.deleteZone.question = question; this.$.deleteZone.question = question;
this.$.deleteZone.show(); this.$.deleteZone.show();