Merge pull request '2176-contextmenu' (#302) from 2176-contextmenu into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-by: Carlos Jimenez <carlosjr@verdnatura.es>
This commit is contained in:
commit
d8593ea3e0
|
@ -0,0 +1,5 @@
|
||||||
|
<section vn-id="contextmenu">
|
||||||
|
<vn-menu vn-id="menu">
|
||||||
|
<div ng-transclude="menu"></div>
|
||||||
|
</vn-menu>
|
||||||
|
</section>
|
|
@ -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'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
section[vn-id="contextmenu"] {
|
||||||
|
position: absolute
|
||||||
|
}
|
|
@ -50,3 +50,4 @@ import './th';
|
||||||
import './treeview';
|
import './treeview';
|
||||||
import './wday-picker';
|
import './wday-picker';
|
||||||
import './datalist';
|
import './datalist';
|
||||||
|
import './contextmenu';
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
|
@ -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>
|
||||||
|
|
|
@ -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: [
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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>
|
|
@ -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
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue