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 './wday-picker';
import './datalist';
import './contextmenu';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,14 +15,14 @@
</vn-th>
<vn-th></vn-th>
<vn-th field="id" number>Id</vn-th>
<vn-th field="salesPerson" class="expendable">Salesperson</vn-th>
<vn-th field="shipped">Date</vn-th>
<vn-th field="salesPersonFk" class="expendable">Salesperson</vn-th>
<vn-th field="shippedDate">Date</vn-th>
<vn-th>Hour</vn-th>
<vn-th field="nickname">Alias</vn-th>
<vn-th field="province" class="expendable">Province</vn-th>
<vn-th field="state" >State</vn-th>
<vn-th field="agencyMode">Agency</vn-th>
<vn-th field="warehouse">Warehouse</vn-th>
<vn-th field="provinceFk" class="expendable">Province</vn-th>
<vn-th field="stateFk" >State</vn-th>
<vn-th field="agencyModeFk">Agency</vn-th>
<vn-th field="warehouseFk">Warehouse</vn-th>
<vn-th field="refFk" class="expendable">Invoice</vn-th>
<vn-th field="zoneHour" shrink>Closure</vn-th>
<vn-th number>Total</vn-th>
@ -151,3 +151,21 @@
<vn-client-balance-create
vn-id="balanceCreateDialog">
</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

@ -3,4 +3,7 @@ Go to lines: Ir a lineas
Not available: No disponible
Payment on account...: Pago a cuenta...
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;
if (ticketsAmount) {
const params = {ticketsAmount};
console.log('ticketsAmount', res.data);
const question = $t('This zone contains tickets', params, null, null, 'sanitizeParameters');
this.$.deleteZone.question = question;
this.$.deleteZone.show();