0
1
Fork 0

refs 3971 Rest requests promisified

This commit is contained in:
Juan Ferrer 2022-11-28 09:51:31 +01:00
parent 922f27e71a
commit 6640314879
38 changed files with 875 additions and 1041 deletions

2
debian/changelog vendored
View File

@ -1,4 +1,4 @@
hedera-web (22.46.18) stable; urgency=low hedera-web (22.48.0) stable; urgency=low
* Initial Release. * Initial Release.

View File

@ -26,17 +26,17 @@ export default new Class({
Htk.Toast.showMessage(_('DefaultAddressModified')); Htk.Toast.showMessage(_('DefaultAddressModified'));
} }
,onRemoveAddressClick(form) { ,async onRemoveAddressClick(form) {
if (confirm(_('AreYouSureDeleteAddress'))) { if (confirm(_('AreYouSureDeleteAddress'))) {
form.set('isActive', false); await form.set('isActive', false);
form.refresh(); await form.refresh();
} }
} }
,onEditAddressClick(id) { ,onEditAddressClick(address) {
this.hash.setAll({ this.hash.setAll({
form: 'account/address', form: 'account/address',
address: id address
}); });
} }
}); });

View File

@ -38,40 +38,35 @@ export default new Class({
throw new Error(_('Passwords doesn\'t match')); throw new Error(_('Passwords doesn\'t match'));
var verificationToken = this.hash.$.verificationToken; var verificationToken = this.hash.$.verificationToken;
var params = {newPassword: newPassword}; var params = {newPassword};
let err;
try {
if (verificationToken) { if (verificationToken) {
params.verificationToken = verificationToken; params.verificationToken = verificationToken;
this.conn.send('user/restore-password', params, await this.conn.send('user/restore-password', params);
this._onPassChange.bind(this));
} else { } else {
try {
let userId = this.gui.user.id; let userId = this.gui.user.id;
params.oldPassword = oldPassword; params.oldPassword = oldPassword;
await this.conn.lbSend('PATCH', await this.conn.patch(
`Accounts/${userId}/changePassword`, params, `Accounts/${userId}/changePassword`, params);
);
this._onPassChange();
} catch(err) {
this._onPassChange(null, err);
} }
} } catch(e) {
} err = e;
Htk.Toast.showError(err.message);
,_onPassChange(json, error) {
if (!error) {
this.$.changePassword.hide();
this.hash.unset('verificationToken');
Htk.Toast.showMessage(_('Password changed!'));
this.$.userForm.refresh();
} else {
Htk.Toast.showError(error.message);
if (this.hash.$.verificationToken) if (this.hash.$.verificationToken)
this.$.newPassword.select(); this.$.newPassword.select();
else else
this.$.oldPassword.select(); this.$.oldPassword.select();
return;
} }
this.$.changePassword.hide();
this.hash.unset('verificationToken');
Htk.Toast.showMessage(_('Password changed!'));
this.$.userForm.refresh();
} }
,onPassInfoClick() { ,onPassInfoClick() {

View File

@ -21,12 +21,8 @@ export default new Class({
clearTimeout(this._timeoutId); clearTimeout(this._timeoutId);
} }
,onChangeUserClick(userName) { ,async onChangeUserClick(userName) {
this.gui.supplantUser(userName, await this.gui.supplantUser(userName);
this._onUserSupplant.bind(this));
}
,_onUserSupplant() {
this.hash.setAll({form: 'ecomerce/orders'}); this.hash.setAll({form: 'ecomerce/orders'});
} }

View File

@ -13,8 +13,6 @@ export default new Class({
,filesData: [] ,filesData: []
,uploadCount: 0 ,uploadCount: 0
,errors: false
,uploadQueue: []
,isUploading: false ,isUploading: false
,activate() { ,activate() {
@ -77,70 +75,58 @@ export default new Class({
this.setImageStatus(fileData, Status.NONE, 'add', _('Pending upload')); this.setImageStatus(fileData, Status.NONE, 'add', _('Pending upload'));
} }
,onUploadClick() { ,async onUploadClick() {
var filesData = this.filesData; if (this.isUploading) return;
var count = 0;
for (var i = 0; i < filesData.length; i++) { const uploadQueue = [];
var fileData = filesData[i]; let hasFiles = false;
if (fileData.status === Status.NONE) { for (const fileData of this.filesData) {
if (fileData.status !== Status.NONE) continue;
this.setImageStatus( this.setImageStatus(
fileData, Status.WAITING, 'cloud_upload', _('Waiting for upload')); fileData, Status.WAITING, 'cloud_upload', _('Waiting for upload'));
fileData.name.disabled = true; fileData.name.disabled = true;
this.uploadQueue.push(fileData); uploadQueue.push(fileData);
count++; hasFiles = true;
}
} }
if (count === 0) if (!hasFiles) {
Htk.Toast.showWarning(_('There are no files to upload')); Htk.Toast.showWarning(_('There are no files to upload'));
else
this.uploadNextFile();
}
,uploadNextFile() {
if (this.isUploading)
return; return;
}
this.isUploading = true; this.isUploading = true;
let hasErrors = false;
var fileData = this.uploadQueue.shift(); for (const fileData of uploadQueue) {
this.setImageStatus( this.setImageStatus(
fileData, Status.UPLOADING, 'upload', _('Uploading file')); fileData, Status.UPLOADING, 'upload', _('Uploading file'));
var formData = new FormData(); const formData = new FormData();
formData.append('updateMatching', this.$.updateMatching.value); formData.append('updateMatching', this.$.updateMatching.value);
formData.append('image', fileData.file); formData.append('image', fileData.file);
formData.append('name', fileData.name.value); formData.append('name', fileData.name.value);
formData.append('schema', this.$.schema.value); formData.append('schema', this.$.schema.value);
formData.append('srv', 'json:image/upload'); formData.append('srv', 'json:image/upload');
this.conn.sendFormData(formData,
this.onFileUpload.bind(this, fileData));
}
,onFileUpload(fileData, data, error) { try {
this.isUploading = false; await this.conn.sendFormData(formData);
if (data) {
this.setImageStatus( this.setImageStatus(
fileData, Status.UPLOADED, 'cloud_done', _('Image uploaded')); fileData, Status.UPLOADED, 'cloud_done', _('Image uploaded'));
} else { } catch(err) {
this.setImageStatus( this.setImageStatus(
fileData, Status.NONE, 'error', error.message); fileData, Status.NONE, 'error', err.message);
fileData.name.disabled = false; fileData.name.disabled = false;
this.errors = true; hasErrors = true;
}
} }
if (this.uploadQueue.length === 0) { this.isUploading = false;
if (this.errors)
if (hasErrors)
Htk.Toast.showError(_('Some errors happened on upload')); Htk.Toast.showError(_('Some errors happened on upload'));
else else
Htk.Toast.showMessage(_('Upload finished successfully')); Htk.Toast.showMessage(_('Upload finished successfully'));
this.errors = false;
} else
this.uploadNextFile();
} }
,setImageStatus(fileData, status, icon, title) { ,setImageStatus(fileData, status, icon, title) {

View File

@ -12,12 +12,8 @@ export default new Class({
'block' : 'none'; 'block' : 'none';
} }
,onChangeUserClick(userName) { ,async onChangeUserClick(userName) {
this.gui.supplantUser(userName, await this.gui.supplantUser(userName);
this.onUserSupplant.bind(this));
}
,onUserSupplant() {
this.hash.setAll({form: 'ecomerce/orders'}); this.hash.setAll({form: 'ecomerce/orders'});
} }
}); });

View File

@ -5,11 +5,9 @@ export default new Class({
Template: require('./ui.xml') Template: require('./ui.xml')
,activate() { ,activate() {
var self = this; this.$.contactForm.onsubmit = () => {
this.$.contactForm.onsubmit = function() { this._onSubmit(); return false;
self._onSubmit(); return false;
}; };
this.refreshCaptcha(); this.refreshCaptcha();
} }
@ -21,22 +19,21 @@ export default new Class({
this.$.captchaImg.src = '?'+ Vn.Url.makeUri(params); this.$.captchaImg.src = '?'+ Vn.Url.makeUri(params);
} }
,_onSubmit() { ,async _onSubmit() {
this.conn.sendForm(this.$.contactForm, const form = this.$.contactForm;
this._onResponse.bind(this));
}
,_onResponse(json) { try {
var form = this.$.contactForm; await this.conn.sendForm(this.$.contactForm);
} catch (err) {
if (json) {
form.reset();
Htk.Toast.showMessage(_('DataSentSuccess'));
} else
Htk.Toast.showError(_('ErrorSendingData')); Htk.Toast.showError(_('ErrorSendingData'));
return;
} finally {
form['captcha'].value = ''; form['captcha'].value = '';
this.refreshCaptcha(); this.refreshCaptcha();
} }
form.reset();
Htk.Toast.showMessage(_('DataSentSuccess'));
}
}); });

View File

@ -8,11 +8,12 @@ export default new Class({
,locations: null ,locations: null
,activate() { ,async activate() {
this.gui.loaderPush(); this.gui.loaderPush();
var sql = 'SELECT lat, lng, title, address, postcode, city, province, phone, language FROM location'; var sql = 'SELECT lat, lng, title, address, postcode, city, province, phone, language FROM location';
this.conn.execQuery(sql, this.onLocationsDone.bind(this)); const resultSet = await this.conn.execQuery(sql);
this.locations = resultSet.fetchData();
if (!gmapsIsLoaded) { if (!gmapsIsLoaded) {
gmapsLoadedCallback = this.gmapsLoaded.bind(this); gmapsLoadedCallback = this.gmapsLoaded.bind(this);
@ -25,18 +26,11 @@ export default new Class({
this.gmapsLoaded(); this.gmapsLoaded();
} }
,onLocationsDone(resultSet) {
this.locations = resultSet.fetchData();
this.allLoaded();
}
,gmapsLoaded() { ,gmapsLoaded() {
this.gui.loaderPop(); this.gui.loaderPop();
gmapsIsLoaded = true; gmapsIsLoaded = true;
this.allLoaded(); this.allLoaded();
}
,allLoaded() {
if (!this.locations || !gmapsIsLoaded) if (!this.locations || !gmapsIsLoaded)
return; return;

View File

@ -4,17 +4,9 @@ export default new Class({
Extends: Hedera.Form, Extends: Hedera.Form,
Template: require('./ui.xml'), Template: require('./ui.xml'),
open() { async open() {
this.close(); const isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
this.isOpen = true; if (isOk) await Hedera.Form.prototype.open.call(this);
Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this));
},
onBasketCheck(isOk) {
if (isOk)
this.loadUi();
}, },
activate() { activate() {

View File

@ -6,22 +6,15 @@ const Catalog = new Class({
,_menuShown: false ,_menuShown: false
,open() { ,async open() {
this.close(); let isOk = true;
this.isOpen = true;
if (!localStorage.getItem('hederaGuest')) { if (!localStorage.getItem('hederaGuest'))
Hedera.BasketChecker.check(this.conn, this.hash, isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
this.onBasketCheck.bind(this)); else
} else { await this.conn.execQuery('CALL mybasket_configureForGuest');
var query = 'CALL mybasket_configureForGuest';
this.conn.execQuery(query, this.loadUi.bind(this));
}
}
,onBasketCheck(isOk) { if (isOk) await Hedera.Form.prototype.open.call(this);
if (isOk)
this.loadUi();
} }
,activate() { ,activate() {
@ -289,7 +282,7 @@ const Catalog = new Class({
Htk.Toast.showError(_('NoMoreAmountAvailable')); Htk.Toast.showError(_('NoMoreAmountAvailable'));
} }
,onConfirmClick() { ,async onConfirmClick() {
var sql = ''; var sql = '';
var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'}); var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'});
var amountSum = 0; var amountSum = 0;

View File

@ -56,16 +56,17 @@ export default new Class({
this.$.assistantBar.disabled = disable; this.$.assistantBar.disabled = disable;
}, },
onConfirmClick() { async onConfirmClick() {
this.disableButtons(true); this.disableButtons(true);
const query = 'CALL myBasket_configure(#date, #method, #agency, #address)'; const query = 'CALL myBasket_configure(#date, #method, #agency, #address)';
this.conn.execQuery(query, let resultSet;
this.onBasketConfigured.bind(this), this.$.lot.$);
},
onBasketConfigured(resultSet) { try {
resultSet = await this.conn.execQuery(query, this.$.lot.$);
} finally {
this.disableButtons(false); this.disableButtons(false);
}
if (!resultSet.fetchResult()) if (!resultSet.fetchResult())
return; return;

View File

@ -4,17 +4,9 @@ export default new Class({
Extends: Hedera.Form, Extends: Hedera.Form,
Template: require('./ui.xml'), Template: require('./ui.xml'),
open() { async open() {
this.close(); const isOk = await Hedera.BasketChecker.check(this.conn, this.hash);
this.isOpen = true; if (isOk) await Hedera.Form.prototype.open.call(this);
Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this));
},
onBasketCheck(isOk) {
if (isOk)
this.loadUi();
}, },
onOrderReady(form) { onOrderReady(form) {
@ -123,9 +115,9 @@ export default new Class({
window.history.back(); window.history.back();
}, },
onConfirmClick() { async onConfirmClick() {
this.disableButtons(true); this.disableButtons(true);
this.$.confirmQuery.execute(); await this.$.confirmQuery.execute();
}, },
onConfirm(query, resultSet) { onConfirm(query, resultSet) {
@ -135,7 +127,7 @@ export default new Class({
this.$.successDialog.show(); this.$.successDialog.show();
}, },
onDialogResponse() { async onDialogResponse() {
if (this.$.payMethod.value === 'CARD') { if (this.$.payMethod.value === 'CARD') {
if (this.$.payAmount.value === 'EXCEEDED') if (this.$.payAmount.value === 'EXCEEDED')
var payAmount = this.$.excessAmount.value; var payAmount = this.$.excessAmount.value;
@ -146,9 +138,8 @@ export default new Class({
conn: this.conn, conn: this.conn,
hash: this.hash hash: this.hash
}); });
tpv.pay(payAmount, this.$.order.companyFk); await tpv.pay(payAmount, this.$.order.companyFk);
} else } else
this.hash.setAll({form: 'ecomerce/orders'}); this.hash.setAll({form: 'ecomerce/orders'});
} }
}); });

View File

@ -9,12 +9,8 @@ export default new Class({
conn: this.conn, conn: this.conn,
hash: this.hash hash: this.hash
}); });
this.tpv.check(this._onTpvCheck.bind(this)); const tpvStatus = this.tpv.check();
}, if (tpvStatus === 'ko') this.$.errorDialog.show();
_onTpvCheck(tpv, tpvOrder, tpvStatus) {
if (tpvStatus === 'ko')
this.$.errorDialog.show();
}, },
onBasketClick() { onBasketClick() {
@ -30,14 +26,14 @@ export default new Class({
// TPV // TPV
balanceConditionalFunc(field, value) { balanceConditionalFunc(_, value) {
if (value >= 0) if (value >= 0)
Vn.Node.removeClass(this.$.balance, 'negative'); Vn.Node.removeClass(this.$.balance, 'negative');
else else
Vn.Node.addClass(this.$.balance, 'negative'); Vn.Node.addClass(this.$.balance, 'negative');
}, },
onPayButtonClick() { async onPayButtonClick() {
var amount = -this.$.debt.value; var amount = -this.$.debt.value;
amount = amount <= 0 ? null : amount; amount = amount <= 0 ? null : amount;
@ -50,13 +46,12 @@ export default new Class({
if (amount != null) { if (amount != null) {
amount = parseFloat(amount.replace(',', '.')); amount = parseFloat(amount.replace(',', '.'));
this.tpv.pay(amount, null); await this.tpv.pay(amount, null);
} }
}, },
onDialogResponse(dialog, response) { async onDialogResponse(_, response) {
if (response == Htk.Dialog.Button.RETRY) if (response == Htk.Dialog.Button.RETRY)
this.tpv.retryPay(); await this.tpv.retryPay();
} }
}); });

View File

@ -4,12 +4,10 @@ export default new Class({
Extends: Hedera.Form, Extends: Hedera.Form,
Template: require('./ui.xml'), Template: require('./ui.xml'),
onTicketChange(ticket) { async onTicketChange(ticket) {
if (!ticket.value) if (!ticket.value) return;
return; await this.conn.execQuery('CALL myTicket_logAccess(#ticket)',
{ticket: ticket.value});
var params = {ticket: ticket.value};
this.conn.execQuery('CALL myTicket_logAccess(#ticket)', null, params);
}, },
onPrintClick() { onPrintClick() {

View File

@ -2,20 +2,20 @@ import './style.scss';
export default new Class({ export default new Class({
Extends: Hedera.Form, Extends: Hedera.Form,
Template: require('./ui.xml') Template: require('./ui.xml'),
,activate() { activate() {
this.$.lot.assign({ this.$.lot.assign({
date: new Date(), date: new Date(),
useIds: false useIds: false
}); });
} },
,onConfigChange() { onConfigChange() {
this.$.lot.assignLot(this.$.config); this.$.lot.assignLot(this.$.config);
} },
,onPreviewClick() { onPreviewClick() {
this.gui.openReport('shelves-report', this.$.lot); this.gui.openReport('shelves-report', this.$.lot);
} }
}); });

View File

@ -1,4 +1,3 @@
export const locales = { export const locales = {
ca: cb => require([], ca: cb => require([],
() => cb(require.context('js', true, /locale\/ca.yml$/))), () => cb(require.context('js', true, /locale\/ca.yml$/))),

View File

@ -39,47 +39,12 @@ Connection.implement({
* Runs a SQL query on the database. * Runs a SQL query on the database.
* *
* @param {String} sql The SQL statement * @param {String} sql The SQL statement
* @param {Function} callback The function to call when operation is done * @return {ResultSet} The result
*/ */
,execSql(sql, callback) { ,async execSql(sql) {
this.send('core/query', {'sql': sql}, const json = await this.send('core/query', {sql});
this._onExec.bind(this, callback));
}
/**
* Runs a stmt on the database.
*
* @param {Sql.Stmt} stmt The statement
* @param {Function} callback The function to call when operation is done
* @param {Object} params The query params
*/
,execStmt(stmt, callback, params) {
this.execSql(stmt.render(params), callback);
}
/**
* Runs a query on the database.
*
* @param {String} query The SQL statement
* @param {Function} callback The function to call when operation is done
* @param {Object} params The query params
*/
,execQuery(query, callback, params) {
this.execStmt(new Sql.String({query: query}), callback, params);
}
/*
* Parses a value to date.
*/
,valueToDate(value) {
return fixTz(new Date(value));
}
/*
* Called when a query is executed.
*/
,_onExec(callback, json, error) {
const results = []; const results = [];
let err;
if (json) if (json)
try { try {
@ -126,11 +91,39 @@ Connection.implement({
} else } else
results.push(json[i]); results.push(json[i]);
} catch (e) { } catch (e) {
error = e; err = e;
} }
if (callback) return new Db.ResultSet(results, err);
callback(new Db.ResultSet(results, error)); }
/**
* Runs a stmt on the database.
*
* @param {Sql.Stmt} stmt The statement
* @param {Object} params The query params
* @return {ResultSet} The result
*/
,async execStmt(stmt, params) {
return await this.execSql(stmt.render(params));
}
/**
* Runs a query on the database.
*
* @param {String} query The SQL statement
* @param {Object} params The query params
* @return {ResultSet} The result
*/
,async execQuery(query, params) {
return await this.execStmt(new Sql.String({query}), params);
}
/*
* Parses a value to date.
*/
,valueToDate(value) {
return fixTz(new Date(value));
} }
}); });

View File

@ -38,9 +38,9 @@ module.exports = new Class({
,_model: null ,_model: null
,_row: -1 ,_row: -1
,refresh() { ,async refresh() {
if (this._model) if (this._model)
this._model.refresh(); await this._model.refresh();
} }
/** /**
@ -68,17 +68,17 @@ module.exports = new Class({
this.row = this._model.insertRow(); this.row = this._model.insertRow();
} }
,performOperations() { ,async performOperations() {
if (this._model) if (this._model)
this._model.performOperations(); await this._model.performOperations();
} }
/** /**
* Removes the current row. * Removes the current row.
*/ */
,deleteRow() { ,async deleteRow() {
if (this._row >= 0) if (this._row >= 0)
this._model.deleteRow(this._row); await this._model.deleteRow(this._row);
} }
/** /**
@ -106,8 +106,8 @@ module.exports = new Class({
* @param {String} columnName The column name * @param {String} columnName The column name
* @param {Object} value The new value * @param {Object} value The new value
*/ */
,set(columnName, value) { ,async set(columnName, value) {
return this._model.set(this._row, columnName, value); return await this._model.set(this._row, columnName, value);
} }
/** /**

View File

@ -302,25 +302,9 @@ Model.implement({
return true; return true;
} }
,lazyRefresh() { ,async lazyRefresh() {
if (this._paramsChanged) if (this._paramsChanged)
this.refresh(); await this.refresh();
}
/**
* Refresh the model data reexecuting the query on the database.
*/
,refresh() {
const params = this._getHolderParams();
if (this._isReady(params)) {
this._setStatus(Status.LOADING);
this._lastParams = this._getHolderValues();
this._paramsChanged = false;
this._conn.execStmt(this._stmt,
this._selectDone.bind(this), params);
} else
this.clean();
} }
,clean() { ,clean() {
@ -328,14 +312,29 @@ Model.implement({
this._setStatus(Status.CLEAN); this._setStatus(Status.CLEAN);
} }
,_selectDone(resultSet) { /**
var result; * Refresh the model data reexecuting the query on the database.
var dataResult; */
,async refresh() {
const params = this._getHolderParams();
if (!this._isReady(params)) {
this.clean();
return;
}
this._setStatus(Status.LOADING);
this._lastParams = this._getHolderValues();
this._paramsChanged = false;
let result;
let dataResult;
this._cleanData(); this._cleanData();
try { try {
for (var i = 0; result = resultSet.fetchResult(); i++) const resultSet = await this._conn.execStmt(this._stmt, params);
for (let i = 0; result = resultSet.fetchResult(); i++)
if (i == this._resultIndex) if (i == this._resultIndex)
dataResult = result; dataResult = result;
@ -357,7 +356,7 @@ Model.implement({
for (column in this._requestedIndexes) for (column in this._requestedIndexes)
this._buildIndex(column); this._buildIndex(column);
var sortColumn = null; let sortColumn = null;
if (this._requestedSortName) if (this._requestedSortName)
sortColumn = this._requestedSortName; sortColumn = this._requestedSortName;
@ -560,7 +559,7 @@ Model.implement({
* @param {string} columnName The column name * @param {string} columnName The column name
* @param {mixed} value The new value * @param {mixed} value The new value
*/ */
,set(rowIndex, columnName, value) { ,async set(rowIndex, columnName, value) {
if (!this.checkRowExists(rowIndex) if (!this.checkRowExists(rowIndex)
&& !this.checkColName(columnName)) && !this.checkColName(columnName))
return; return;
@ -605,7 +604,7 @@ Model.implement({
if (this.mode == Mode.ON_CHANGE if (this.mode == Mode.ON_CHANGE
&& !(op.type & Operation.INSERT)) && !(op.type & Operation.INSERT))
this.performOperations(); await this.performOperations();
} }
/** /**
@ -631,11 +630,11 @@ Model.implement({
* @param {number} columnIndex The column index * @param {number} columnIndex The column index
* @param {mixed} value The new value * @param {mixed} value The new value
*/ */
,setByIndex(rowIndex, columnIndex, value) { ,async setByIndex(rowIndex, columnIndex, value) {
var columnName = this.getColumnName(columnIndex); var columnName = this.getColumnName(columnIndex);
if (columnName) if (columnName)
this.set(rowIndex, columnName, value); await this.set(rowIndex, columnName, value);
else else
console.warn('Db.Model: Column %d doesn\'t exist', columnIndex); console.warn('Db.Model: Column %d doesn\'t exist', columnIndex);
} }
@ -645,7 +644,7 @@ Model.implement({
* *
* @param {number} rowIndex The row index * @param {number} rowIndex The row index
*/ */
,deleteRow(rowIndex) { ,async deleteRow(rowIndex) {
if (!this.checkRowExists(rowIndex) if (!this.checkRowExists(rowIndex)
|| !this._checkTableUpdatable(this._mainTable)) || !this._checkTableUpdatable(this._mainTable))
return; return;
@ -681,7 +680,7 @@ Model.implement({
} }
if (this.mode === Mode.ON_CHANGE) if (this.mode === Mode.ON_CHANGE)
this.performOperations(); await this.performOperations();
} }
/** /**
@ -716,28 +715,28 @@ Model.implement({
/** /**
* Performs all model changes on the database. * Performs all model changes on the database.
*/ */
,performOperations() { ,async performOperations() {
var ops = this._operations; const ops = this._operations;
if (ops.length === 0) { if (ops.length === 0) {
this.emit('operations-done'); this.emit('operations-done');
return; return;
} }
var stmts = new Sql.MultiStmt(); const stmts = new Sql.MultiStmt();
var query = new Sql.String({query: 'START TRANSACTION'}); let query = new Sql.String({query: 'START TRANSACTION'});
stmts.push(query); stmts.push(query);
for (var i = 0; i < ops.length; i++) { for (let i = 0; i < ops.length; i++) {
query = null; query = null;
var op = ops[i]; let op = ops[i];
if (op.type & Operation.DELETE) { if (op.type & Operation.DELETE) {
if (op.type & Operation.INSERT) if (op.type & Operation.INSERT)
continue; continue;
var where = this._createWhere(this._mainTable, op, true); const where = this._createWhere(this._mainTable, op, true);
if (where) { if (where) {
query = new Sql.Delete({where}); query = new Sql.Delete({where});
@ -746,8 +745,8 @@ Model.implement({
} else if (op.type & (Operation.INSERT | Operation.UPDATE)) { } else if (op.type & (Operation.INSERT | Operation.UPDATE)) {
query = new Sql.MultiStmt(); query = new Sql.MultiStmt();
for (var tableIndex in op.tables) { for (const tableIndex in op.tables) {
var stmt = this._createDmlQuery(op, parseInt(tableIndex)); const stmt = this._createDmlQuery(op, parseInt(tableIndex));
query.push(stmt); query.push(stmt);
} }
} }
@ -760,11 +759,72 @@ Model.implement({
} }
} }
var query = new Sql.String({query: 'COMMIT'}); query = new Sql.String({query: 'COMMIT'});
stmts.push(query); stmts.push(query);
this._conn.execStmt(stmts, const resultSet = await this._conn.execStmt(stmts);
this._onOperationsDone.bind(this, ops)); const error = resultSet.getError();
if (error) {
this._operations = this._operations.concat(ops);
for (let i = 0; i < ops.length; i++)
this._operationsMap[ops[i].row.index] = ops[i];
throw error;
}
resultSet.fetchResult();
let isOperation = false;
for (let i = 0; i < ops.length; i++) {
const op = ops[i];
const row = op.row;
if (!(op.type & Operation.DELETE
&& op.type & Operation.INSERT))
// eslint-disable-next-line no-unused-vars
isOperation = true;
if (op.type & Operation.DELETE) {
resultSet.fetchResult();
} else if (op.type & (Operation.INSERT | Operation.UPDATE)) {
this.emit('row-updated-before', row.index);
const updatedCols = [];
const cols = this.columns;
for (let tableIndex in op.tables) {
let j = 0;
tableIndex = parseInt(tableIndex);
resultSet.fetchResult();
const newValues = resultSet.fetchRow();
if (op.tables[tableIndex] & Operation.INSERT) {
for (let i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex) {
row[cols[i].name] = newValues[j++];
updatedCols.push(i);
}
} else {
for (let i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex
&& op.oldValues[i] !== undefined) {
row[cols[i].name] = newValues[j++];
updatedCols.push(i);
}
}
}
this.emit('row-updated', row.index, updatedCols);
}
}
resultSet.fetchResult();
// if (isOperation)
this.emit('operations-done');
this._resetOperations(); this._resetOperations();
} }
@ -827,71 +887,6 @@ Model.implement({
return multiStmt; return multiStmt;
} }
,_onOperationsDone(ops, resultSet) {
var error = resultSet.getError();
if (error) {
this._operations = this._operations.concat(ops);
for (var i = 0; i < ops.length; i++)
this._operationsMap[ops[i].row.index] = ops[i];
throw error;
}
resultSet.fetchResult();
var isOperation = false;
for (var i = 0; i < ops.length; i++) {
var op = ops[i];
var row = op.row;
if (!(op.type & Operation.DELETE
&& op.type & Operation.INSERT))
// eslint-disable-next-line no-unused-vars
isOperation = true;
if (op.type & Operation.DELETE) {
resultSet.fetchResult();
} else if (op.type & (Operation.INSERT | Operation.UPDATE)) {
this.emit('row-updated-before', row.index);
var updatedCols = [];
var cols = this.columns;
for (var tableIndex in op.tables) {
var j = 0;
tableIndex = parseInt(tableIndex);
resultSet.fetchResult();
var newValues = resultSet.fetchRow();
if (op.tables[tableIndex] & Operation.INSERT) {
for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex) {
row[cols[i].name] = newValues[j++];
updatedCols.push(i);
}
} else {
for (var i = 0; i < cols.length; i++)
if (cols[i].table === tableIndex
&& op.oldValues[i] !== undefined) {
row[cols[i].name] = newValues[j++];
updatedCols.push(i);
}
}
}
this.emit('row-updated', row.index, updatedCols);
}
}
resultSet.fetchResult();
// if (isOperation)
this.emit('operations-done');
}
/** /**
* Undoes all unsaved changes made to the model. * Undoes all unsaved changes made to the model.
*/ */

View File

@ -80,13 +80,10 @@ module.exports = new Class({
this.query = query; this.query = query;
} }
,execute() { ,async execute() {
this._conn.execStmt(this._stmt, const resultSet = await this._conn.execStmt(this._stmt, this._lot);
this.onQueryDone.bind(this), this._lot);
}
,onQueryDone(resultSet) {
this.emit('ready', resultSet); this.emit('ready', resultSet);
return resultSet;
} }
,onChange() { ,onChange() {

View File

@ -1,6 +1,5 @@
const Login = require('./login');
var Login = require('./login'); const Gui = require('./gui');
var Gui = require('./gui');
module.exports = new Class({ module.exports = new Class({
Extends: Vn.Object, Extends: Vn.Object,
@ -14,23 +13,28 @@ module.exports = new Class({
} }
,initialize() { ,initialize() {
window.onerror = this._onWindowError.bind(this); window.addEventListener('error',
window.onunhandledrejection = e => this._onWindowRejection(e); e => this._onWindowError(e));
window.onunload = this._onWindowUnload.bind(this); window.addEventListener('unhandledrejection',
e => this._onWindowRejection(e));
window.addEventListener('unload',
() => this._onWindowUnload());
this._hash = new Vn.Hash({window: window}); this._hash = new Vn.Hash({window: window});
var conn = new Db.Connection(); const conn = new Db.Connection();
this.link({_conn: conn}, {'error': this._onConnError}); this.link({_conn: conn}, {'error': this._onConnError});
this.initAutoLogin(); this.initAutoLogin();
} }
,run() { ,run() {
if (this.tryAutoLogin()) if (this.tryAutoLogin()) return;
return; this.showLogin();
}
var login = this._login = new Login({ ,showLogin() {
const login = this._login = new Login({
conn: this._conn, conn: this._conn,
hash: this._hash hash: this._hash
}); });
@ -38,97 +42,41 @@ module.exports = new Class({
login.show(); login.show();
} }
,_onLogin() { ,async _onLogin() {
this._freeLogin(); this._freeLogin();
if (this._gui) return;
if (this._gui) const gui = this._gui = new Gui({
return;
var gui = this._gui = new Gui({
conn: this._conn, conn: this._conn,
hash: this._hash hash: this._hash
}); });
gui.on('logout', this._onLogout, this); gui.on('logout', this._onLogout, this);
gui.show(); await gui.show();
} }
,_onLogout() { ,async _onLogout() {
this.clearAutoLogin(); this.clearAutoLogin();
this._freeGui(); await this._freeGui();
this.run(); this.loggingOut = false;
this.showLogin();
} }
,_onWindowUnload() { ,_onWindowUnload() {
this.unref(); this.unref();
} }
,_onWindowError(message, file, line) { ,async _logout() {
var error = new Error(message); if (this._gui && !this.loggingOut) {
error.fileName = file; this.loggingOut = true;
error.lineNumber = line; await this._gui.logout();
this._notifyError(error);
} }
,_onWindowRejection(event) {
const err = event.reason;
this._onConnError(null, err);
event.preventDefault();
}
,_onConnError(conn, error) {
if (error instanceof Vn.JsonException) {
if (error.message)
Htk.Toast.showError(error.message);
else
switch (error.exception) {
case 'BadLogin':
Htk.Toast.showError(_('Invalid login'));
this._logout();
break;
case 'Forbidden':
Htk.Toast.showError(_('You don\'t have enough privileges'));
break;
case 'UserDisabled':
Htk.Toast.showError(_('User disabled'));
this._logout();
break;
case 'SessionExpired':
Htk.Toast.showError(_('Session expired'));
this._logout();
break;
case 'OutdatedVersion':
this._newVersion(error);
break;
default:
Htk.Toast.showError(error.message);
}
} else if (error.statusCode) {
switch (error.statusCode) {
case 401:
Htk.Toast.showError(_('Invalid login'));
this._logout();
break;
default:
Htk.Toast.showError(error.message);
}
} else {
console.error(error);
this._notifyError(error);
}
}
,_logout() {
if (this._gui)
this._gui.logout();
} }
,_newVersion() { ,_newVersion() {
if (this.ignoreVersion) if (this.ignoreVersion) return;
return;
this.ignoreVersion = true; this.ignoreVersion = true;
var dialog = new Htk.Dialog({ const dialog = new Htk.Dialog({
message: _('New version available') message: _('New version available')
,buttons: Htk.Dialog.Button.ACCEPT ,buttons: Htk.Dialog.Button.ACCEPT
,icon: 'warning' ,icon: 'warning'
@ -141,59 +89,43 @@ module.exports = new Class({
location.reload(); location.reload();
} }
,_notifyError(error) {
Htk.Toast.showError(_('Something went wrong'));
var params = {
file: error.fileName
,line: error.lineNumber
,message: error.message
,stack: error.stack
,agent: navigator.userAgent
,location: location.href
};
this._conn.send('core/log', params);
}
,_freeLogin() { ,_freeLogin() {
if (this._login) { if (!this._login) return;
this._login.disconnectByInstance(this); this._login.disconnectByInstance(this);
this._login.hide(); this._login.hide();
this._login.unref(); this._login.unref();
this._login = null; this._login = null;
} }
}
,_freeGui() { ,async _freeGui() {
if (this._gui) { if (!this._gui) return;
this._gui.disconnectByInstance(this); this._gui.disconnectByInstance(this);
this._gui.hide(); await this._gui.hide();
this._gui.unref(); this._gui.unref();
this._gui = null; this._gui = null;
} }
}
,_destroy() { ,_destroy() {
this._freeLogin(); this._freeLogin();
this._freeGui(); this._freeGui();
this.deinitAutoLogin(); this.deinitAutoLogin();
this._conn.unref(); if (this._conn) this._conn.unref();
this._hash.unref(); if (this._hash) this._hash.unref();
} }
// Auto login functionality // Auto login
,_firstLogin: true ,_firstLogin: true
,initAutoLogin() { ,initAutoLogin() {
var isGuest = new Vn.Param({ const isGuest = new Vn.Param({
lot: this._hash, lot: this._hash,
type: Boolean, type: Boolean,
name: 'guest' name: 'guest'
}); });
this.link({_isGuest: isGuest}, {'changed': this._onGuestChange}); this.link({_isGuest: isGuest}, {'changed': this._onGuestChange});
var token = new Vn.Param({ const token = new Vn.Param({
lot: this._hash, lot: this._hash,
type: String, type: String,
name: 'token' name: 'token'
@ -212,12 +144,12 @@ module.exports = new Class({
} }
,deinitAutoLogin() { ,deinitAutoLogin() {
this._isGuest.unref(); if (this._isGuest) this._isGuest.unref();
this._token.unref(); if (this._token) this._token.unref();
} }
,autoLogin() { ,autoLogin() {
var guest = localStorage.getItem('hederaGuest'); const guest = localStorage.getItem('hederaGuest');
if (this._isGuest.value || guest) { if (this._isGuest.value || guest) {
localStorage.setItem('hederaGuest', true); localStorage.setItem('hederaGuest', true);
@ -236,7 +168,7 @@ module.exports = new Class({
} }
,tryAutoLogin() { ,tryAutoLogin() {
var ok = this.autoLogin(); const ok = this.autoLogin();
this._firstLogin = false; this._firstLogin = false;
this._isGuest.value = undefined; this._isGuest.value = undefined;
@ -252,5 +184,69 @@ module.exports = new Class({
,clearAutoLogin() { ,clearAutoLogin() {
localStorage.removeItem('hederaGuest'); localStorage.removeItem('hederaGuest');
} }
// Error management
,_onWindowError(event) {
this.globalHandler(event.error);
}
,_onWindowRejection(event) {
this.globalHandler(event.reason);
}
,async _onConnError(conn, err) {
if (!(err instanceof Vn.JsonException)) return;
switch (err.exception) {
case 'UserDisabled':
Htk.Toast.showError(_('User disabled'));
await this._logout();
return;
case 'OutdatedVersion':
this._newVersion();
return;
}
if (err.statusCode == 401 && !this._login) {
Htk.Toast.showError(_('Session expired'));
this._logout();
}
}
,async globalHandler(err) {
try {
if (!err) return;
if (err instanceof Vn.JsonException) {
const statusCode = err.statusCode;
if (statusCode >= 400 && statusCode < 500) {
if (err.statusCode == 403)
Htk.Toast.showError(_('You don\'t have enough privileges'));
else {
switch (err.exception) {
case 'UserDisabled':
case 'OutdatedVersion':
return;
}
if (err.statusCode == 401)
return;
Htk.Toast.showError(err.message);
}
} else
Htk.Toast.showError(err.message);
} else {
Htk.Toast.showError(_('Something went wrong'));
if (this._conn)
await this._conn.send('core/log', {
file: err.fileName
,line: err.lineNumber
,message: err.message
,stack: err.stack
,agent: navigator.userAgent
,location: location.href
});
}
} catch(e) {
console.error(e);
}
}
}); });

View File

@ -1,25 +1,21 @@
module.exports = { module.exports = {
check(conn, hash, callback) { async check(conn, hash) {
this.hash = hash; this.hash = hash;
conn.execQuery('CALL myBasket_check', const resultSet = await conn.execQuery('CALL myBasket_check');
this._onBasketCheck.bind(this, callback));
},
_onBasketCheck(callback, resultSet) { const status = resultSet.fetchValue();
var status = resultSet.fetchValue(); if (!status) return;
if (!status) const isOk = status == 'UPDATED' || status == 'OK';
return;
var isOk = status == 'UPDATED' || status == 'OK';
if (status == 'UPDATED') if (status == 'UPDATED')
Htk.Toast.showWarning(_('Order items updated')); Htk.Toast.showWarning(_('Order items updated'));
if (callback)
callback(isOk);
if (!isOk) if (!isOk)
this.hash.setAll({form: 'ecomerce/checkout'}); this.hash.setAll({form: 'ecomerce/checkout'});
return isOk;
} }
}; };

View File

@ -11,7 +11,7 @@ module.exports = new Class({
this.hash = gui.hash; this.hash = gui.hash;
} }
,loadUi() { ,async loadUi() {
if (!this.isOpen) if (!this.isOpen)
return; return;
@ -47,22 +47,22 @@ module.exports = new Class({
this.gui.setForm(this.node); this.gui.setForm(this.node);
this.gui.setTitle(scope.$.title); this.gui.setTitle(scope.$.title);
this.gui.setActions(scope.$.actions); this.gui.setActions(scope.$.actions);
this.activate(); await this.activate();
} }
this.uiLoaded = true; this.uiLoaded = true;
} }
,unloadUi() { ,async unloadUi() {
if (!this.uiLoaded) if (!this.uiLoaded)
return; return;
if (this.node) { if (this.node) {
this.deactivate(); await this.deactivate();
this.gui.setTitle(null); this.gui.setTitle(null);
this.gui.setActions(null); this.gui.setActions(null);
Vn.Node.remove(this.node); Vn.Node.remove(this.node);
this.deactivate(); await this.deactivate();
this.node = null; this.node = null;
} }
if (this.builder) { if (this.builder) {
@ -74,32 +74,30 @@ module.exports = new Class({
/** /**
* Called when the form is opened. * Called when the form is opened.
*/ */
,open() { ,async open() {
this.close(); await this.close();
this.isOpen = true; this.isOpen = true;
this.loadUi(); await this.loadUi();
} }
/** /**
* Called when the form is closed. * Called when the form is closed.
*/ */
,close() { ,async close() {
if (!this.isOpen) if (!this.isOpen) return;
return;
this.isOpen = false; this.isOpen = false;
this.unloadUi(); await this.unloadUi();
} }
/** /**
* Called when the form is activated. * Called when the form is activated.
*/ */
,activate() {} ,async activate() {}
/** /**
* Called when the form is deactivated. * Called when the form is deactivated.
*/ */
,deactivate() {} ,async deactivate() {}
,_destroy() { ,_destroy() {
this.close(); this.close();

View File

@ -41,80 +41,23 @@ module.exports = new Class({
}); });
Vn.Component.prototype.initialize.call(this, props); Vn.Component.prototype.initialize.call(this, props);
var sql = 'SELECT id, name, nickname FROM account.myUser;'
+'SELECT defaultForm FROM config;'
+'SELECT url FROM imageConfig;'
+'SELECT dbproduccion FROM vn.config;'
+'SELECT productionDomain, testDomain FROM config;';
this._conn.execQuery(sql, this.onMainQueryDone.bind(this));
this.loadMenu();
} }
,show() { ,async show() {
if (this._shown) if (this._shown) return;
return;
this._shown = true; this._shown = true;
this.doc.body.appendChild(this.node); this.doc.body.appendChild(this.node);
Htk.Toast.pushTop(this.$.formHolder); Htk.Toast.pushTop(this.$.formHolder);
if (Vn.isMobile()) { const resultSet = await this._conn.execQuery(
this._onScrollHandler = this._onScroll.bind(this); 'SELECT id, name, nickname FROM account.myUser;'
window.addEventListener('scroll', this._onScrollHandler ); +'SELECT defaultForm FROM config;'
} +'SELECT url FROM imageConfig;'
+'SELECT dbproduccion FROM vn.config;'
+'SELECT productionDomain, testDomain FROM config;'
);
this.formParam = new Vn.Param({
lot: this.hash,
name: 'form',
});
this.formParam.on('changed', this._onFormChange, this);
if (!localStorage.getItem('hederaCookies')) {
localStorage.setItem('hederaCookies', true);
Htk.Toast.showWarning(_('By using this site you accept cookies'));
}
this.supplantInit();
}
,hide() {
if (!this._shown)
return;
this._shown = false;
if (Vn.isMobile())
window.removeEventListener('scroll', this._onScrollHandler);
Htk.Toast.popTop();
this.formParam.unref();
this.closeForm();
this.hideMenu();
Vn.Node.remove(this.node);
}
,logout() {
this.onLogoutClick();
}
,async onLogoutClick() {
try {
await this._conn.close();
} finally {
this.emit('logout');
}
}
,_onConnLoadChange(conn, isLoading) {
if (isLoading)
this.loaderPush();
else
this.loaderPop();
}
,onMainQueryDone(resultSet) {
// Retrieving the user name // Retrieving the user name
this.user = resultSet.fetchObject(); this.user = resultSet.fetchObject();
@ -161,17 +104,70 @@ module.exports = new Class({
} else } else
this.$.testLink.style.display = 'none'; this.$.testLink.style.display = 'none';
// Loading the default form await this.loadMenu();
this._onFormChange(); if (Vn.isMobile()) {
this._onScrollHandler = this._onScroll.bind(this);
window.addEventListener('scroll', this._onScrollHandler );
} }
,loadMenu() { await this.supplantInit();
var sql = 'SELECT * FROM myMenu';
this._conn.execQuery(sql, this._onMenuLoad.bind(this)); this.formParam = new Vn.Param({
lot: this.hash,
name: 'form',
});
this.formParam.on('changed', this._onFormChange, this);
await this._onFormChange();
if (!localStorage.getItem('hederaCookies')) {
localStorage.setItem('hederaCookies', true);
Htk.Toast.showWarning(_('By using this site you accept cookies'));
}
} }
,_onMenuLoad(resultSet) { ,async hide() {
if (!this._shown)
return;
this._shown = false;
if (Vn.isMobile())
window.removeEventListener('scroll', this._onScrollHandler);
Htk.Toast.popTop();
if (this.formParam) {
this.formParam.unref();
this.formParam = null;
}
await this.closeForm();
this.hideMenu();
Vn.Node.remove(this.node);
}
,async logout() {
await this.onLogoutClick();
}
,async onLogoutClick() {
try {
if (!localStorage.getItem('hederaGuest'))
this._conn.close();
} finally {
this.emit('logout');
}
}
,_onConnLoadChange(conn, isLoading) {
if (isLoading)
this.loaderPush();
else
this.loaderPop();
}
,async loadMenu() {
const resultSet = await this._conn.execQuery('SELECT * FROM myMenu');
// Retrieving menu sections // Retrieving menu sections
var res = resultSet.fetchData(); var res = resultSet.fetchData();
@ -359,7 +355,7 @@ module.exports = new Class({
this.hideMenu(); this.hideMenu();
this.loaderPush(); this.loaderPush();
this.closeForm(); await this.closeForm();
this.requestedForm = formPath; this.requestedForm = formPath;
var newChoosedOption = this.menuOptions[formPath]; var newChoosedOption = this.menuOptions[formPath];
@ -387,7 +383,7 @@ module.exports = new Class({
return; return;
this.activeForm = new FormKlass(this); this.activeForm = new FormKlass(this);
this.activeForm.open(); await this.activeForm.open();
} }
,async importForm(path) { ,async importForm(path) {
@ -435,10 +431,10 @@ module.exports = new Class({
this.$.actionBar.appendChild(actions); this.$.actionBar.appendChild(actions);
} }
,closeForm() { ,async closeForm() {
if (this.activeForm) { if (this.activeForm) {
Vn.Node.removeClass(this.$.formHolder, 'show'); Vn.Node.removeClass(this.$.formHolder, 'show');
this.activeForm.close(); await this.activeForm.close();
this.activeForm._destroy(); this.activeForm._destroy();
this.activeForm = null; this.activeForm = null;
} }
@ -456,64 +452,44 @@ module.exports = new Class({
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Reports //++++++++++++++++++++++++++++++++++++++++++++++++++++++ Reports
,openReport(reportName, lot) { ,async openReport(reportName, lot) {
try {
this.loaderPush(); this.loaderPush();
const module = new Module('reports', reportName);
await module.load();
var module = new Module('reports', reportName); const report = new module.klass(module, this);
module.addCallback(this._onReportLoad.bind(this, lot));
}
,_onReportLoad(lot, module) {
this.loaderPop();
if (module.error) {
Htk.Toast.showError(_('Error loading report'));
return;
}
var report = new module.klass(module, this);
report.open(lot); report.open(lot);
} catch(err) {
Htk.Toast.showError(_('Error loading report'));
} finally {
this.loaderPop();
}
} }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant //++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant
,supplantInit() { ,async supplantInit() {
var user = sessionStorage.getItem('supplantUser'); var user = sessionStorage.getItem('supplantUser');
if (user == null) return;
if (user != null) await this._conn.supplantUser(user);
this.supplantUser(user);
}
,supplantUser(user, callback) {
this._conn.supplantUser(user,
this._onUserSupplant.bind(this, callback, user));
}
,_onUserSupplant(callback, user, supplantOk, err) {
if (err) throw err;
sessionStorage.setItem('supplantUser', user); sessionStorage.setItem('supplantUser', user);
this.loadMenu(); await this.loadMenu();
var sql = 'SELECT nickname FROM account.myUser'; const res = await this._conn.execQuery(
this._conn.execQuery(sql, this._onSupplantName.bind(this)); 'SELECT nickname FROM account.myUser');
if (callback) const userName = res.fetchValue();
callback();
}
,_onSupplantName(resultSet) {
var userName = resultSet.fetchValue();
Vn.Node.setText(this.$.supplanted, userName); Vn.Node.setText(this.$.supplanted, userName);
this.$.supplant.classList.toggle('show', true); this.$.supplant.classList.toggle('show', true);
} }
,onSupplantExitClick() { ,async onSupplantExitClick() {
this.$.supplant.classList.toggle('show', false); this.$.supplant.classList.toggle('show', false);
this._conn.supplantEnd(); await this._conn.supplantEnd();
sessionStorage.removeItem('supplantUser', sessionStorage.removeItem('supplantUser');
sessionStorage.getItem('supplantUser')); await this.loadMenu();
this.loadMenu();
this._onFormChange(); this._onFormChange();
} }

View File

@ -3,10 +3,8 @@ require('./login.scss');
module.exports = new Class({ module.exports = new Class({
Extends: Vn.Component, Extends: Vn.Component,
Properties: Properties: {
{ conn: {
conn:
{
type: Db.Connection type: Db.Connection
,set(x) { ,set(x) {
this.link({_conn: x}, {'loading-changed': this._onConnLoadChange}); this.link({_conn: x}, {'loading-changed': this._onConnLoadChange});
@ -62,6 +60,9 @@ module.exports = new Class({
this.emit('login'); this.emit('login');
} catch (err) { } catch (err) {
this._focusUserInput(); this._focusUserInput();
if (err.statusCode == 401)
Htk.Toast.showError(_('Invalid login'));
else
throw err; throw err;
} finally { } finally {
this.$.pass.value = ''; this.$.pass.value = '';
@ -85,20 +86,15 @@ module.exports = new Class({
this.$.submit.disabled = disabled; this.$.submit.disabled = disabled;
} }
,onPasswordLost() { ,async onPasswordLost() {
var user = this.$.user.value; var recoverUser = this.$.user.value;
if (!user) if (!recoverUser) {
Htk.Toast.showError(_('Please write your user name')); Htk.Toast.showError(_('Please write your user name'));
else return;
this._conn.send('user/recover-password', {recoverUser: user},
this._onPasswordRecovered.bind(this));
} }
,_onPasswordRecovered(json, error) { await this._conn.send('user/recover-password', {recoverUser});
if (error)
throw error;
Htk.Toast.showMessage(_('A mail has been sent wich you can recover your password')); Htk.Toast.showMessage(_('A mail has been sent wich you can recover your password'));
} }
}); });

View File

@ -60,7 +60,8 @@ $login-margin-top: 50px;
$login-margin-between: 55px; $login-margin-between: 55px;
.vn-login > .column { .vn-login > .column {
max-width: 300px; max-width: 250px;
overflow: visible;
& > .header { & > .header {
margin-top: $login-margin-top; margin-top: $login-margin-top;

View File

@ -1,77 +1,62 @@
module.exports = new Class({ module.exports = new Class({
basePath: null basePath: null,
,path: null path: null,
,moduleName: null moduleName: null,
,callbacks: [] resolvers: null,
,localeReady: false status: null,
,jsReady: false
,uiReady: false
,error: false
,ready: false
,initialize(basePath, path) { initialize(basePath, path) {
var absPath = basePath +'/'+ path; const aux = path.split('/');
const moduleName = aux[aux.length - 1];
var aux = path.split('/');
var moduleName = aux[aux.length - 1];
Vn.Locale.load(absPath,
this.onLocaleReady.bind(this));
Vn.includeJs(absPath +'/'+ moduleName +'.js',
this.onJsReady.bind(this));
Vn.loadXml(absPath +'/ui.xml',
this.onUiReady.bind(this));
this.basePath = basePath; this.basePath = basePath;
this.path = path; this.path = path;
this.moduleName = moduleName; this.moduleName = moduleName;
} },
,addCallback(callback) { async load() {
if (!this.ready) switch(this.status) {
this.callbacks.push(callback); case 'ready':
else
callback(this);
}
,onLocaleReady() {
this.localeReady = true;
this.onReady();
}
,onJsReady(success) {
this.jsReady = true;
this.error = !success;
this.onReady();
}
,onUiReady(success) {
this.uiReady = true;
this.error = !success;
this.onReady();
}
,onReady() {
if (!(this.localeReady && this.jsReady && this.uiReady))
return; return;
case 'loading':
return new Promise((resolve, reject) => {
this.resolvers.push(status => {
if (status == 'error')
return reject(new Error(`Module could not be loaded`));
resolve();
});
});
}
this.ready = true; this.status = 'loading';
this.resolvers = [];
var klassName = this.toCamelCase(this.moduleName); const absPath = `${this.basePath}/${this.path}`;
const requests = [
Vn.includeJs(`${absPath}/${this.moduleName}.js`),
Vn.loadXml(`${absPath}/ui.xml`)
];
try { try {
this.klass = Hedera[klassName]; await Vn.Locale.load(absPath);
} catch (e) { } catch(err) {
this.error = true; console.err(err);
console.error(e);
} }
var callbacks = this.callbacks; try {
this.callbacks = null; await Promise.all(requests);
const klassName = this.toCamelCase(this.moduleName);
this.klass = Hedera[klassName];
this.status = 'ready';
} catch (err) {
this.status = 'error';
console.error(err);
}
for (var i = 0; i < callbacks.length; i++) for (const resolver of this.resolvers)
callbacks[i](this); resolver(this.status);
this.resolvers = null;
} }
,toCamelCase(dashedName) { ,toCamelCase(dashedName) {

View File

@ -1,34 +1,26 @@
@font-face @font-face {
{
font-family: 'Roboto'; font-family: 'Roboto';
src: url('roboto.ttf') format('truetype'); src: url('roboto.ttf') format('truetype');
} }
@media print @media print {
{ body {
body
{
-webkit-print-color-adjust: exact; -webkit-print-color-adjust: exact;
} }
.sheet .sheet {
{
width: 100%; width: 100%;
page-break-after: always; page-break-after: always;
} }
#topbar #topbar {
{
display: none; display: none;
} }
} }
@media screen @media screen {
{ body {
body
{
background-color: #EEE; background-color: #EEE;
padding-top: 3.9em; padding-top: 3.9em;
} }
.sheet .sheet {
{
width: 210mm; width: 210mm;
height: 297mm; height: 297mm;
background-color: white; background-color: white;
@ -36,8 +28,7 @@
box-shadow: 0 1mm 1mm #CCC; box-shadow: 0 1mm 1mm #CCC;
padding: 20mm; padding: 20mm;
} }
#topbar #topbar {
{
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
@ -47,8 +38,7 @@
z-index: 100; z-index: 100;
box-shadow: 0 .1em .1em #AAA; box-shadow: 0 .1em .1em #AAA;
} }
#topbar > button #topbar > button {
{
float: right; float: right;
background-color: transparent; background-color: transparent;
color: white; color: white;
@ -60,24 +50,20 @@
height: 100%; height: 100%;
padding: 0 1em; padding: 0 1em;
} }
#topbar > button:hover #topbar > button:hover {
{
background-color: rgba(1, 1, 1, 0.2); background-color: rgba(1, 1, 1, 0.2);
} }
} }
* * {
{
font-family: 'Roboto'; font-family: 'Roboto';
} }
body body {
{
position: relative; position: relative;
margin: 0; margin: 0;
width: 100%; width: 100%;
z-index: -2; z-index: -2;
} }
.sheet .sheet {
{
position: relative; position: relative;
overflow: hidden; overflow: hidden;
box-sizing: padding-box; box-sizing: padding-box;
@ -86,35 +72,27 @@ body
/* Widgets */ /* Widgets */
.htk-grid .htk-grid {
{
border-collapse: collapse; border-collapse: collapse;
width: 100%; width: 100%;
margin: 0 auto; margin: 0 auto;
padding: 0; padding: 0;
} }
.htk-grid > thead > tr .htk-grid > thead > tr {
{
border-bottom: 1px solid #333; border-bottom: 1px solid #333;
height: 10mm; height: 10mm;
} }
.htk-grid > thead th .htk-grid > thead th {
{
text-align: left; text-align: left;
font-weight: normal; font-weight: normal;
} }
.htk-grid tr .htk-grid tr {
{
height: 2em; height: 2em;
} }
.htk-grid > thead th, .htk-grid > thead th,
.htk-grid td .htk-grid td {
{
padding-left: 3mm; padding-left: 3mm;
} }
.htk-grid .cell-spin .htk-grid .cell-spin {
{
text-align: right; text-align: right;
} }

View File

@ -33,28 +33,26 @@ module.exports = new Class({
node.className = 'htk-social-bar'; node.className = 'htk-social-bar';
} }
,_refresh() { ,async _refresh() {
if (!this._conn || this._priority === null) if (!this._conn || this._priority === null)
return; return;
const params = {priority: this._priority}; const params = {priority: this._priority};
var query = 'SELECT title, link, icon FROM social ' const query = 'SELECT title, link, icon FROM social '
+'WHERE priority >= #priority ORDER BY priority'; +'WHERE priority >= #priority ORDER BY priority';
this._conn.execQuery(query, this._onQueryDone.bind(this), params); const resultSet = await this._conn.execQuery(query, params);
}
,_onQueryDone(resultSet) {
Vn.Node.removeChilds(this._node); Vn.Node.removeChilds(this._node);
var res = resultSet.fetchResult(); const res = resultSet.fetchResult();
while (res.next()) { while (res.next()) {
var a = this.createElement('a'); const a = this.createElement('a');
a.href = res.get('link'); a.href = res.get('link');
a.target = '_blank'; a.target = '_blank';
this._node.appendChild(a); this._node.appendChild(a);
var img = this.createElement('img'); const img = this.createElement('img');
img.src = 'image/social/'+ res.get('icon'); img.src = 'image/social/'+ res.get('icon');
img.alt = res.get('title'); img.alt = res.get('title');
img.title = res.get('title'); img.title = res.get('title');

View File

@ -1,48 +1,45 @@
module.exports = new Class({ module.exports = new Class({
Extends: Vn.Object Extends: Vn.Object
,tpvOrder: null ,tpvOrder: null
,tpvStatus: null ,tpvStatus: null
,check(callback) { ,check() {
this.tpvOrder = this.hash.$.tpvOrder; this.tpvOrder = this.hash.$.tpvOrder;
this.tpvStatus = this.hash.$.tpvStatus; this.tpvStatus = this.hash.$.tpvStatus;
if (this.tpvStatus) { if (this.tpvStatus) {
const params = { const query = 'CALL myTpvTransaction_end(#transaction, #status)';
this.conn.execQuery(query, {
transaction: this.tpvOrder, transaction: this.tpvOrder,
status: this.tpvStatus status: this.tpvStatus
}; });
const query = 'CALL myTpvTransaction_end(#transaction, #status)';
this.conn.execQuery(query, null, params);
} }
if (callback) return this.tpvStatus;
callback(this, this.tpvOrder, this.tpvStatus);
} }
,pay(amount, company) { ,async pay(amount, company) {
this._realPay(amount * 100, company); await this._realPay(amount * 100, company);
} }
,_realPay(amount, company) { ,async _realPay(amount, company) {
if (isNumeric(amount) && amount > 0) { if (!isNumeric(amount) || amount <= 0)
const params = { throw new UserError(_('AmountError'));
let json;
try {
json = await this.conn.send('tpv/transaction', {
amount: parseInt(amount) amount: parseInt(amount)
,urlOk: this._makeUrl('ok') ,urlOk: this._makeUrl('ok')
,urlKo: this._makeUrl('ko') ,urlKo: this._makeUrl('ko')
,company: company ,company: company
}; });
} catch(err) {
this.conn.send('tpv/transaction', params, throw new UserError(_('PayError'));
this._onTransactionStart.bind(this));
} else
Htk.Toast.showError(_('AmountError'));
} }
,_onTransactionStart(json) {
if (json) {
const postValues = json.postValues; const postValues = json.postValues;
const form = document.createElement('form'); const form = document.createElement('form');
@ -61,28 +58,18 @@ module.exports = new Class({
} }
form.submit(); form.submit();
} else
Htk.Toast.showWarning(_('PayError'));
} }
,retryPay() { ,async retryPay() {
const params = {transaction: parseInt(this.tpvOrder)};
const query = 'SELECT t.amount, m.companyFk ' const query = 'SELECT t.amount, m.companyFk '
+'FROM myTpvTransaction t ' +'FROM myTpvTransaction t '
+'JOIN tpvMerchant m ON m.id = t.merchantFk ' +'JOIN tpvMerchant m ON m.id = t.merchantFk '
+'WHERE t.id = #transaction'; +'WHERE t.id = #transaction';
this.conn.execQuery(query,
this._onRetryPayDone.bind(this), params);
}
,_onRetryPayDone(resultSet) { const res = await this.conn.execQuery(query,
const res = resultSet.fetchObject(); {transaction: parseInt(this.tpvOrder)});
const payment = res.fetchObject();
if (res) await this._realPay(payment.amount, payment.companyFk);
this._realPay(res.amount, res.companyFk);
else
Htk.Toast.showError(_('AmountError'));
} }
,_makeUrl(status) { ,_makeUrl(status) {

View File

@ -21,9 +21,8 @@ module.exports = new Class({
initialize(props) { initialize(props) {
this.loadTemplateFromString(Tpl); this.loadTemplateFromString(Tpl);
var self = this; this.$.form.onsubmit = () => {
this.$.form.onsubmit = function() { this._onSubmit(); return false;
self._onSubmit(); return false;
}; };
Component.prototype.initialize.call(this, props); Component.prototype.initialize.call(this, props);
@ -38,24 +37,19 @@ module.exports = new Class({
this.emit('name-changed', newValue); this.emit('name-changed', newValue);
}, },
_onSubmit() { async _onSubmit() {
this.$.hiddenName.value = this.$.name.value; this.$.hiddenName.value = this.$.name.value;
this.$.submit.disabled = true; this.$.submit.disabled = true;
this.$.spinner.start(); this.$.spinner.start();
this.conn.sendFormMultipart(this.$.form, try {
this._onResponse.bind(this)); await this.conn.sendFormMultipart(this.$.form);
},
_onResponse(json, error) {
this.$.submit.disabled = false;
this.$.spinner.stop();
if (error)
throw error;
Toast.showMessage(_('ImageAdded')); Toast.showMessage(_('ImageAdded'));
this.emit('file-uploaded', this.$.name.value); this.emit('file-uploaded', this.$.name.value);
} finally {
this.$.submit.disabled = false;
this.$.spinner.stop();
}
}, },
setData(image, directory) { setData(image, directory) {

View File

@ -83,6 +83,7 @@ module.exports =
Vn.Node.remove(this._container); Vn.Node.remove(this._container);
this._container = null; this._container = null;
this.nodes = []; this.nodes = [];
this.lastMessage = null;
} }
,_createContainer() { ,_createContainer() {
@ -102,6 +103,15 @@ module.exports =
} }
,_showText(message, className) { ,_showText(message, className) {
if (!message) return;
const last = this.lastMessage;
if (last
&& last.message == message
&& last.className == className)
return;
this.lastMessage = {message, className};
this._createContainer(); this._createContainer();
if (this._timeouts.length >= this.maxMessages) if (this._timeouts.length >= this.maxMessages)

View File

@ -1,27 +1,27 @@
var VnObject = require('./object'); const VnObject = require('./object');
var JsonException = require('./json-exception'); const JsonException = require('./json-exception');
/** /**
* Handler for JSON rest connections. * Handler for JSON rest connections.
*/ */
module.exports = new Class({ module.exports = new Class({
Extends: VnObject Extends: VnObject,
,_connected: false _connected: false,
,_requestsCount: 0 _requestsCount: 0,
,token: null token: null,
/** /**
* Initilizes the connection object. * Initilizes the connection object.
*/ */
,initialize() { initialize() {
VnObject.prototype.initialize.call(this); VnObject.prototype.initialize.call(this);
this.fetchToken(); this.fetchToken();
} },
,fetchToken() { fetchToken() {
var token = null; let token = null;
if (sessionStorage.getItem('vnToken')) if (sessionStorage.getItem('vnToken'))
token = sessionStorage.getItem('vnToken'); token = sessionStorage.getItem('vnToken');
@ -29,13 +29,13 @@ module.exports = new Class({
token = localStorage.getItem('vnToken'); token = localStorage.getItem('vnToken');
this.token = token; this.token = token;
} },
,clearToken() { clearToken() {
this.token = null; this.token = null;
localStorage.removeItem('vnToken'); localStorage.removeItem('vnToken');
sessionStorage.removeItem('vnToken'); sessionStorage.removeItem('vnToken');
} },
/** /**
* Opens the connection to the REST service. * Opens the connection to the REST service.
@ -45,22 +45,22 @@ module.exports = new Class({
* @param {Boolean} remember Specifies if the user should be remembered * @param {Boolean} remember Specifies if the user should be remembered
* @return {Promise} Resolved when operation is done * @return {Promise} Resolved when operation is done
*/ */
,async open(user, pass, remember) { async open(user, pass, remember) {
let params; let params;
if (user !== null && user !== undefined) { if (user !== null && user !== undefined) {
params = { params = {
user: user user: user,
,password: pass password: pass,
,remember: remember remember: remember
}; };
} else } else
params = null; params = null;
try { try {
const json = await this.lbSend('POST', 'Accounts/login', params); const json = await this.post('Accounts/login', params);
var storage = remember ? localStorage : sessionStorage; const storage = remember ? localStorage : sessionStorage;
storage.setItem('vnToken', json.token); storage.setItem('vnToken', json.token);
this.token = json.token; this.token = json.token;
@ -70,153 +70,163 @@ module.exports = new Class({
this._closeClient(); this._closeClient();
throw err; throw err;
} }
} },
/** /**
* Closes the connection to the REST service. * Closes the connection to the REST service.
* *
* @return {Promise} Resolved when operation is done * @return {Promise} Resolved when operation is done
*/ */
,async close() { async close() {
await this.lbSend('POST', 'Accounts/logout'); const token = this.token;
this._closeClient(); this._closeClient();
this.emit('closed'); this.emit('closed');
if (token) {
const config = {
headers: {'Authorization': token}
};
await this.post('Accounts/logout', null, config);
} }
},
,_closeClient() { _closeClient() {
this._connected = false; this._connected = false;
this.clearToken(); this.clearToken();
} },
/** /**
* Supplants another user. * Supplants another user.
* *
* @param {String} user The user name * @param {String} supplantUser The user name
* @param {Function} callback The callback function
*/ */
,supplantUser(user, callback) { async supplantUser(supplantUser) {
var params = {supplantUser: user}; const json = await this.send('client/supplant', {supplantUser});
this.send('client/supplant', params,
this._onUserSupplant.bind(this, callback));
}
,_onUserSupplant(callback, json, err) {
if (json)
this.token = json; this.token = json;
},
if (callback)
callback(err == null, err);
}
/** /**
* Ends the user supplanting and restores the last login. * Ends the user supplanting and restores the last login.
*/ */
,supplantEnd() { async supplantEnd() {
this.lbSend('POST', 'Accounts/logout'); await this.post('Accounts/logout');
this.fetchToken(); this.fetchToken();
} },
/** /**
* Executes the specified REST service with the given params and calls * Executes the specified REST service with the given params and calls
* the callback when response is received. * the callback when response is received.
* *
* @param {String} restService The service path * @param {String} url The service path
* @param {Map} params The params to pass to the service * @param {Object} params The params to pass to the service
* @param {Function} callback The response callback * @return {Object} The parsed JSON response
*/ */
,send(restService, params, callback) { async send(url, params) {
if (!params) if (!params) params = {};
params = {}; params.srv = `json:${url}`;
return await this.sendWithUrl('POST', '.', params);
},
params.srv = 'json:'+ restService; async sendForm(form) {
const params = {};
this.sendWithUrl(params, callback, 'POST', '.'); const elements = form.elements;
}
,sendForm(form, callback) {
var params = {};
var elements = form.elements;
for (var i = 0; i < elements.length; i++) for (var i = 0; i < elements.length; i++)
if (elements[i].name) if (elements[i].name)
params[elements[i].name] = elements[i].value; params[elements[i].name] = elements[i].value;
this.sendWithUrl(params, callback, 'POST', form.action); return await this.sendWithUrl('POST', form.action, params);
} },
,sendFormMultipart(form, callback) { async sendFormMultipart(form) {
var formData = new FormData(form); return await this.request({
method: 'POST',
url: form.action,
data: new FormData(form)
});
},
var request = new XMLHttpRequest(); async sendFormData(formData) {
request.open('POST', form.action, true); return await this.request({
if (this.token) method: 'POST',
request.setRequestHeader('Authorization', this.token); url: '',
request.onreadystatechange = data: formData
this._onStateChange.bind(this, request, callback); });
request.send(formData); },
this._addRequest();
}
,sendFormData(formData, callback) {
var request = new XMLHttpRequest();
request.open('POST', '', true);
if (this.token)
request.setRequestHeader('Authorization', this.token);
request.onreadystatechange =
this._onStateChange.bind(this, request, callback);
request.send(formData);
this._addRequest();
}
/* /*
* Called when REST response is received. * Called when REST response is received.
*/ */
,sendWithUrl(params, callback, method, url) { async sendWithUrl(method, url, params) {
var request = new XMLHttpRequest(); return await this.request({
request.open(method, url, true); method,
request.setRequestHeader('Content-Type', url,
'application/x-www-form-urlencoded'); data: Vn.Url.makeUri(params),
if (this.token) headers: {
request.setRequestHeader('Authorization', this.token); 'Content-Type': 'application/x-www-form-urlencoded'
request.onreadystatechange =
this._onStateChange.bind(this, request, callback);
request.send(Vn.Url.makeUri(params));
this._addRequest();
} }
,async lbSend(method, url, params) {
var request = new XMLHttpRequest();
request.open(method, `api/${url}`, true);
request.setRequestHeader('Content-Type',
'application/json;charset=utf-8');
if (this.token)
request.setRequestHeader('Authorization', this.token);
this._addRequest();
return await new Promise((resolve, reject) => {
function callback(data, err) {
if (err) return reject(err);
resolve(data);
}
request.onreadystatechange =
this._onStateChange.bind(this, request, callback);
request.send(params && JSON.stringify(params));
}); });
} },
,_addRequest() { async get(url, config) {
config = Object.assign({}, config, {
method: 'GET',
url: `api/${url}`
});
return await this.request(config);
},
async post(url, data, config) {
return await this.requestData('POST', url, data, config);
},
async patch(url, data, config) {
return await this.requestData('PATCH', url, data, config);
},
async requestData(method, url, data, config) {
config = Object.assign({}, config, {
method,
url: `api/${url}`,
data: data && JSON.stringify(data),
});
config.headers = Object.assign({}, config.headers, {
'Content-Type': 'application/json;charset=utf-8'
});
return await this.request(config);
},
async request(config) {
const request = new XMLHttpRequest();
request.open(config.method, config.url, true);
if (this.token)
request.setRequestHeader('Authorization', this.token);
const headers = config.headers;
if (headers)
for (const header in headers)
request.setRequestHeader(header, headers[header]);
const promise = new Promise((resolve, reject) => {
request.onreadystatechange =
() => this._onStateChange(request, resolve, reject);
});
request.send(config.data);
this._addRequest();
return await promise;
},
_addRequest() {
this._requestsCount++; this._requestsCount++;
if (this._requestsCount === 1) if (this._requestsCount === 1)
this.emit('loading-changed', true); this.emit('loading-changed', true);
} },
,_onStateChange(request, callback) { _onStateChange(request, resolve, reject) {
if (request.readyState !== 4) if (request.readyState !== 4)
return; return;
@ -225,17 +235,17 @@ module.exports = new Class({
if (this._requestsCount === 0) if (this._requestsCount === 0)
this.emit('loading-changed', false); this.emit('loading-changed', false);
var data = null; let data = null;
var error = null; let error = null;
try { try {
if (request.status == 0) { if (request.status == 0) {
var ex = new JsonException(); const err = new JsonException();
ex.message = _('The server does not respond, please check your Internet connection'); err.message = _('The server does not respond, please check your Internet connection');
throw ex; err.statusCode = request.status;
throw err;
} }
var contentType = null; let contentType = null;
try { try {
contentType = request contentType = request
@ -247,14 +257,14 @@ module.exports = new Class({
} }
if (contentType != 'application/json') { if (contentType != 'application/json') {
var ex = new JsonException(); const err = new JsonException();
ex.message = request.statusText; err.message = request.statusText;
ex.code = request.status; err.statusCode = request.status;
throw ex; throw err;
} }
var json; let json;
var jsData; let jsData;
if (request.responseText) if (request.responseText)
json = JSON.parse(request.responseText); json = JSON.parse(request.responseText);
@ -264,8 +274,9 @@ module.exports = new Class({
if (request.status >= 200 && request.status < 300) { if (request.status >= 200 && request.status < 300) {
data = jsData; data = jsData;
} else { } else {
var exception = jsData.exception; let exception = jsData.exception;
var error = jsData.error; let error = jsData.error;
let err = new JsonException();
if (exception) { if (exception) {
exception = exception exception = exception
@ -273,41 +284,37 @@ module.exports = new Class({
.replace(/Exception$/, '') .replace(/Exception$/, '')
.replace(/^Vn\.Web\./, ''); .replace(/^Vn\.Web\./, '');
var ex = new JsonException(); err.exception = exception;
ex.exception = exception; err.message = jsData.message;
ex.message = jsData.message; err.code = jsData.code;
ex.code = jsData.code; err.file = jsData.file;
ex.file = jsData.file; err.line = jsData.line;
ex.line = jsData.line; err.trace = jsData.trace;
ex.trace = jsData.trace; err.statusCode = request.status;
} else if (error) { } else if (error) {
var ex = new Error(); err.message = error.message;
ex.name = error.name; err.code = error.code;
ex.message = error.message; err.statusCode = request.status;
ex.code = error.code; } else {
ex.statusCode = request.status; err.message = request.statusText;
err.statusCode = request.status;
} }
throw ex; throw err;
} }
} catch (e) { } catch (e) {
data = null; data = null;
error = e; error = e;
} }
if (callback)
try {
callback(data, error);
error = null;
} catch (e) {
error = e;
}
if (error) { if (error) {
reject(error);
if (error.exception == 'SessionExpired') if (error.exception == 'SessionExpired')
this.clearToken(); this.clearToken();
this.emit('error', error); this.emit('error', error);
} } else
resolve(data);
} }
}); });

View File

@ -1,22 +1,15 @@
/** /**
* This class stores the database errors. * This class stores the database errors.
*/ */
module.exports = new Class module.exports = class JsonException {
({ constructor(exception, message, code, file, line, trace, statucCode) {
exception: null this.name = 'JsonException';
,message: null
,code: null
,file: null
,line: null
,trace: null
,initialize(exception, message, code, file, line, trace) {
this.exception = exception; this.exception = exception;
this.message = message; this.message = message;
this.code = code; this.code = code;
this.file = file; this.file = file;
this.line = line; this.line = line;
this.trace = trace; this.trace = trace;
this.statusCode = statucCode;
} }
}); }

View File

@ -245,6 +245,7 @@ module.exports = class VnObject {
} }
_unlink(object) { _unlink(object) {
if (!object) return;
object.disconnectByInstance(this); object.disconnectByInstance(this);
object.unref(); object.unref();
} }

View File

@ -99,27 +99,18 @@ Object.assign(Vn, {
,_createIncludeData(path) { ,_createIncludeData(path) {
var includeData = { var includeData = {
depCount: 0 path,
,success: false depCount: 0,
,loaded: false success: false,
,callbacks: [] loaded: false,
,dependants: [] callbacks: [],
dependants: [],
}; };
this.includes[path] = includeData; this.includes[path] = includeData;
return includeData; return includeData;
} }
,_handleCallback(includeData, callback) {
if (!callback)
return;
if (includeData.success)
callback(includeData.loaded);
else
includeData.callbacks.push(callback);
}
,_resolveDeps(includeData) { ,_resolveDeps(includeData) {
includeData.success = true; includeData.success = true;
@ -240,17 +231,29 @@ Object.assign(Vn, {
this.currentCallback = callback; this.currentCallback = callback;
} }
,async _handleCallback(includeData) {
if (includeData.success) return;
return new Promise((resolve, reject) => {
function callback(loaded) {
if (!loaded)
return reject(new Error(`Could not load resource: ${includeData.path}`));
resolve();
}
includeData.callbacks.push(callback);
});
}
/** /**
* Includes a new Javascript in the current document, if the script * Includes a new Javascript in the current document, if the script
* is already included, does nothing and calls the callback. * is already included, does nothing and calls the callback.
* *
* @param {string} fileName The script file name * @param {string} fileName The script file name
* @param {Function} callback The function to call when script is
* downloaded and included
*/ */
,includeJs(fileName, callback, skipVersion) { ,async includeJs(fileName, skipVersion) {
var includeData = this._realIncludeJs(fileName, skipVersion); var includeData = this._realIncludeJs(fileName, skipVersion);
this._handleCallback(includeData, callback); return this._handleCallback(includeData);
} }
,_realIncludeJs(fileName, skipVersion) { ,_realIncludeJs(fileName, skipVersion) {
@ -270,11 +273,11 @@ Object.assign(Vn, {
script.src = src; script.src = src;
script.onload = script.onload =
this._onScriptLoad.bind(this, includeData, true); () => this._onScriptLoad(includeData, true);
script.onerror = script.onerror =
this._onScriptLoad.bind(this, includeData, false); () => this._onScriptLoad(includeData, false);
script.onreadystatechange = script.onreadystatechange =
this._onScriptStateChange.bind(this, includeData, script); () => this._onScriptStateChange(includeData, script);
this.head.appendChild(script); this.head.appendChild(script);
} }
@ -314,11 +317,10 @@ Object.assign(Vn, {
* Request an XML file. * Request an XML file.
* *
* @param {string} path The file path * @param {string} path The file path
* @param {Function} callback The function to call when file is downloaded
*/ */
,loadXml(path, callback) { ,async loadXml(path) {
var includeData = this._realLoadXml(path); var includeData = this._realLoadXml(path);
this._handleCallback(includeData, callback); return this._handleCallback(includeData);
} }
,_realLoadXml(path) { ,_realLoadXml(path) {
@ -329,7 +331,7 @@ Object.assign(Vn, {
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
request.onreadystatechange = request.onreadystatechange =
this._onXmlReady.bind(this, includeData, request); () => this._onXmlReady(includeData, request);
request.open('get', path + this.getVersion(), true); request.open('get', path + this.getVersion(), true);
request.send(); request.send();
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "hedera-web", "name": "hedera-web",
"version": "22.46.18", "version": "22.48.20",
"description": "Verdnatura web page", "description": "Verdnatura web page",
"license": "GPL-3.0", "license": "GPL-3.0",
"repository": { "repository": {

View File

@ -7,18 +7,16 @@ Hedera.ShelvesReport = new Class({
,trayThickness: 2 ,trayThickness: 2
,trayMargin: 5 ,trayMargin: 5
,open(lot) { ,async open(lot) {
this.lot = lot; this.lot = lot;
var query = const query =
'SELECT id, name, nTrays, topTrayHeight, trayHeight, width, depth '+ 'SELECT id, name, nTrays, topTrayHeight, trayHeight, width, depth '+
'FROM shelf WHERE id = #shelf; '+ 'FROM shelf WHERE id = #shelf; '+
'CALL item_listAllocation(#warehouse, #date, #family, #namePrefix, #useIds)'; 'CALL item_listAllocation(#warehouse, #date, #family, #namePrefix, #useIds)';
this.conn.execQuery(query, this.onQueryExec.bind(this), lot.$); const resultSet = await this.conn.execQuery(query, lot.$);
}
,onQueryExec(resultSet) {
// Fetch query data // Fetch query data
const row = resultSet.fetchObject(); const row = resultSet.fetchObject();