0
1
Fork 0

Merge pull request '0000-lot' (#9) from 0000-lot into test

Reviewed-on: verdnatura/hedera-web#9
This commit is contained in:
Juan Ferrer 2022-06-06 16:23:49 +00:00
commit e635807cb9
202 changed files with 4758 additions and 3717 deletions

2
debian/changelog vendored
View File

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

View File

@ -9,7 +9,7 @@ Hedera.AddressList = new Class
}
,onAddAddressClick: function() {
this.hash.set({
this.hash.setAll({
form: 'account/address',
address: 0
});
@ -33,7 +33,7 @@ Hedera.AddressList = new Class
}
,onEditAddressClick: function(id) {
this.hash.set({
this.hash.setAll({
form: 'account/address',
address: id
});

View File

@ -1,4 +1,4 @@
Addresses: Direccions
Addresses: Adreces
Return: Tornar
AddAddress: Afegir adreça
SetAsDefault: Establir com per defecte

View File

@ -9,20 +9,12 @@ Hedera.Address = new Class({
},
onStatusChange: function() {
if (this.$.iter.ready && this.$.address.value == 0)
if (this.$.iter.ready && this.hash.$.address == 0)
this.$.iter.insertRow();
},
onOperationsDone: function() {
Htk.Toast.showMessage(_('AddressChangedSuccessfully'));
this.onReturnClick();
},
onAcceptClick: function() {
this.$.iter.performOperations();
},
onReturnClick: function() {
window.history.back();
window.history.back()
}
});

View File

@ -1,24 +1,21 @@
<vn>
<vn-group>
<vn-param id="address"/>
<vn-hash-param key="address" param="address"/>
<vn-lot-query id="params">
<vn-spec name="address" type="Number"/>
</vn-lot-query>
<db-form id="iter" on-status-changed="this.onStatusChange()">
<db-model
id="model"
property="model"
updatable="true"
mode="ON_DEMAND"
lot="params"
on-operations-done="this.onOperationsDone()">
SELECT a.id, a.street, a.nickname, a.city,
a.postalCode, a.provinceFk, p.countryFk
FROM myAddress a
LEFT JOIN vn.province p ON p.id = a.provinceFk
WHERE a.id = #address
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
</custom>
</sql-batch>
</db-model>
</db-form>
</vn-group>
@ -29,11 +26,11 @@
<htk-bar-button
icon="close"
tip="_Return"
on-click="this.onReturnClick()"/>
on-click="window.history.back()"/>
<htk-bar-button
icon="check"
tip="_Accept"
on-click="this.onAcceptClick()"/>
on-click="$.iter.performOperations()"/>
</div>
<div id="form" class="address">
<div class="form box vn-w-sm vn-pa-lg">
@ -62,13 +59,9 @@
</div>
<div class="form-group">
<htk-combo
placeholder="_Country">
<db-param
id="country"
property="param"
form="iter"
column="countryFk"
one-way="true"/>
placeholder="_Country"
id="country"
one-way="true">
<db-model property="model">
SELECT id, country FROM vn.country
ORDER BY country
@ -80,15 +73,10 @@
placeholder="_Province"
column="provinceFk"
form="iter">
<db-model property="model">
<db-model property="model" lot="country">
SELECT id, name FROM vn.province
WHERE countryFk = #country
WHERE countryFk = #id
ORDER BY name
<sql-batch property="batch">
<custom>
<item name="country" param="country"/>
</custom>
</sql-batch>
</db-model>
</htk-combo>
</div>

View File

@ -9,7 +9,7 @@ Hedera.Conf = new Class({
if (this.hash.$.verificationToken)
this.onPassChangeClick();
}
,onPassChangeClick: function() {
this.$.oldPassword.value = '';
this.$.newPassword.value = '';
@ -75,9 +75,5 @@ Hedera.Conf = new Class({
,onPassInfoClick: function() {
this.$.passwordInfo.show();
}
,onAddressesClick: function() {
this.hash.set({form: 'account/address-list'});
}
});

View File

@ -27,7 +27,7 @@
<htk-bar-button
icon="place"
tip="_Addresses"
on-click="this.onAddressesClick()"/>
on-click="$.hash.setAll({form: 'account/address-list'})"/>
<htk-bar-button
icon="lock_reset"
tip="_Change password"

View File

@ -1,21 +1,12 @@
<vn>
<vn-group>
<vn-param id="user"/>
<vn-hash-param key="user" param="user"/>
<db-form id="userForm">
<db-model property="model">
<custom>
SELECT u.id, u.name user, u.nickname, u.email, c.phone, r.name role
FROM account.user u
JOIN account.role r ON r.id = u.role
LEFT JOIN vn.client c ON c.id = u.id
WHERE u.id = #user
</custom>
<sql-batch property="batch">
<custom>
<item name="user" param="user"/>
</custom>
</sql-batch>
<db-form id="user">
<db-model property="model" lot="hash">
SELECT u.id, u.name user, u.nickname, u.email, c.phone, r.name role
FROM account.user u
JOIN account.role r ON r.id = u.role
LEFT JOIN vn.client c ON c.id = u.id
WHERE u.id = #user
</db-model>
</db-form>
</vn-group>
@ -25,29 +16,22 @@
<div id="form" class="access-log">
<div class="box vn-w-xs vn-pa-lg">
<div class="form">
<h4><htk-text form="user-form" column="nickname"/></h4>
<p>#<htk-text form="user-form" column="id"/> - <htk-text form="user-form" column="user"/></p>
<p><htk-text form="user-form" column="role"/></p>
<p><htk-text form="user-form" column="email"/></p>
<p><htk-text form="user-form" column="phone"/></p>
<h4><htk-text form="user" column="nickname"/></h4>
<p>#<htk-text form="user" column="id"/> - <htk-text form="user" column="user"/></p>
<p><htk-text form="user" column="role"/></p>
<p><htk-text form="user" column="email"/></p>
<p><htk-text form="user" column="phone"/></p>
</div>
</div>
<htk-repeater form-id="iter" class="box vn-w-xs htk-list vn-mt-md">
<db-model property="model">
<custom>
SELECT u.stamp, a.platform, a.browser, a.version, a.javascript, a.cookies
FROM visitUser u
JOIN visitAccess c ON c.id = u.accessFk
JOIN visitAgent a ON a.id = c.agentFk
WHERE u.userFk = #user
ORDER BY u.stamp DESC
LIMIT 8
</custom>
<sql-batch property="batch">
<custom>
<item name="user" param="user"/>
</custom>
</sql-batch>
<db-model property="model" lot="hash">
SELECT u.stamp, a.platform, a.browser, a.version, a.javascript, a.cookies
FROM visitUser u
JOIN visitAccess c ON c.id = u.accessFk
JOIN visitAgent a ON a.id = c.agentFk
WHERE u.userFk = #user
ORDER BY u.stamp DESC
LIMIT 8
</db-model>
<custom>
<div class="item">

View File

@ -25,7 +25,7 @@ Hedera.Connections = new Class({
}
,_onUserSupplant: function() {
this.hash.set({form: 'ecomerce/orders'});
this.hash.setAll({form: 'ecomerce/orders'});
}
,sessionsFunc: function() {

View File

@ -23,17 +23,15 @@
property="model"
id="sessions"
on-status-changed="this.onModelStatusChange()">
<custom>
SELECT vu.userFk userId, vu.stamp, u.nickname, s.lastUpdate,
a.platform, a.browser, a.version, u.name user
FROM userSession s
JOIN visitUser vu ON vu.id = s.userVisitFk
JOIN visitAccess ac ON ac.id = vu.accessFk
JOIN visitAgent a ON a.id = ac.agentFk
JOIN visit v ON v.id = a.visitFk
JOIN account.user u ON u.id = vu.userFk
ORDER BY lastUpdate DESC
</custom>
SELECT vu.userFk userId, vu.stamp, u.nickname, s.lastUpdate,
a.platform, a.browser, a.version, u.name user
FROM userSession s
JOIN visitUser vu ON vu.id = s.userVisitFk
JOIN visitAccess ac ON ac.id = vu.accessFk
JOIN visitAgent a ON a.id = ac.agentFk
JOIN visit v ON v.id = a.visitFk
JOIN account.user u ON u.id = vu.userFk
ORDER BY lastUpdate DESC
</db-model>
<custom>
<a class="item"

View File

@ -1,20 +1,16 @@
<vn>
<vn-group>
<vn-param id="filter"/>
<vn-hash-param key="filter" param="filter"/>
</vn-group>
<div id="title">
<h1><t>Items</t></h1>
</div>
<div id="actions">
<htk-search-entry param="filter"/>
<htk-search-entry form="hash" column="search"/>
</div>
<div id="form" class="items">
<htk-repeater
class="htk-list rows box vn-w-xs"
form-id="iter"
empty-message="_Enter a search term">
<db-model property="model" id="items">
<db-model property="model" id="items" lot="hash">
SELECT i.id, i.longName, i.size, i.category,
i.value5, i.value6, i.value7,
i.image, im.updated
@ -22,14 +18,9 @@
LEFT JOIN image im
ON im.collectionFk = 'catalog'
AND im.name = i.image
WHERE i.longName LIKE CONCAT('%', #filter, '%')
OR i.id = #filter
WHERE i.longName LIKE CONCAT('%', #search, '%')
OR i.id = #search
ORDER BY i.longName LIMIT 50
<sql-batch property="batch">
<custom>
<item name="filter" param="filter"/>
</custom>
</sql-batch>
</db-model>
<custom>
<div class="item">

View File

@ -1,34 +1,22 @@
<vn>
<vn-group>
<vn-param id="user-name"/>
<vn-hash-param key="user" param="user-name"/>
</vn-group>
<div id="title">
<h1><t>User management</t></h1>
</div>
<div id="actions">
<htk-search-entry
param="user-name"/>
<htk-search-entry form="hash" column="user"/>
</div>
<div id="form" class="users">
<htk-repeater
form-id="iter"
renderer="rendererFunc"
class="htk-list box vn-w-xs">
<db-model property="model">
<custom>
SELECT u.id, u.name, u.nickname, u.active
FROM account.user u
WHERE u.name LIKE CONCAT('%', #user, '%')
OR u.nickname LIKE CONCAT('%', #user, '%')
OR u.id = #user
ORDER BY u.name LIMIT 200
</custom>
<sql-batch property="batch">
<custom>
<item name="user" param="user-name"/>
</custom>
</sql-batch>
<db-model property="model" lot="hash">
SELECT u.id, u.name, u.nickname, u.active
FROM account.user u
WHERE u.name LIKE CONCAT('%', #user, '%')
OR u.nickname LIKE CONCAT('%', #user, '%')
OR u.id = #user
ORDER BY u.name LIMIT 200
</db-model>
<custom>
<a class="users-box item"

View File

@ -16,7 +16,7 @@ Hedera.Users = new Class({
}
,onUserSupplant: function() {
this.hash.set({form: 'ecomerce/orders'});
this.hash.setAll({form: 'ecomerce/orders'});
}
});

View File

@ -1,4 +1,8 @@
<vn>
<vn-lot-query id="params">
<vn-spec name="from" type="Date"/>
<vn-spec name="to" type="Date"/>
</vn-lot-query>
<div id="title">
<h1><t>Visits</t></h1>
</div>
@ -6,26 +10,26 @@
<htk-bar-button
icon="refresh"
tip="_Refresh"
on-click="this.onRefreshClick()"/>
on-click="$.visits.refresh()"/>
<htk-bar-button
icon="visibility"
tip="_Connections"
on-click="this.onSessionsClick()"/>
on-click="this.hash.setAll({form: 'admin/connections'})"/>
</div>
<div id="form" class="visits">
<div class="vn-w-xs">
<div class="form vn-pa-lg box">
<div class="form-group">
<label><t>From</t></label>
<htk-date-chooser>
<vn-param property="param" id="from"/>
</htk-date-chooser>
<htk-date-chooser
form="params"
column="from"/>
</div>
<div class="form-group">
<label><t>To</t></label>
<htk-date-chooser>
<vn-param property="param" id="to"/>
</htk-date-chooser>
<htk-date-chooser
form="params"
column="to"/>
</div>
</div>
<div class="summary vn-pa-lg box">
@ -50,27 +54,19 @@
class="box htk-list"
form-id="iter"
empty-message="_Select date interval">
<db-model property="model" id="visits">
<custom>
SELECT browser,
MIN(CAST(version AS DECIMAL(4,1))) minVersion,
MAX(CAST(version AS DECIMAL(4,1))) maxVersion,
MAX(c.stamp) lastVisit,
COUNT(DISTINCT c.id) visits,
SUM(a.firstAccessFk = c.id AND v.firstAgentFk = a.id) newVisits
FROM visitUser e
JOIN visitAccess c ON c.id = e.accessFk
JOIN visitAgent a ON a.id = c.agentFk
JOIN visit v ON v.id = a.visitFk
WHERE c.stamp BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
GROUP BY browser ORDER BY visits DESC
</custom>
<sql-batch property="batch">
<custom>
<item name="from" param="from"/>
<item name="to" param="to"/>
</custom>
</sql-batch>
<db-model property="model" id="visits" lot="params">
SELECT browser,
MIN(CAST(version AS DECIMAL(4,1))) minVersion,
MAX(CAST(version AS DECIMAL(4,1))) maxVersion,
MAX(c.stamp) lastVisit,
COUNT(DISTINCT c.id) visits,
SUM(a.firstAccessFk = c.id AND v.firstAgentFk = a.id) newVisits
FROM visitUser e
JOIN visitAccess c ON c.id = e.accessFk
JOIN visitAgent a ON a.id = c.agentFk
JOIN visit v ON v.id = a.visitFk
WHERE c.stamp BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
GROUP BY browser ORDER BY visits DESC
</db-model>
<custom>
<div class="item">

View File

@ -3,16 +3,11 @@ Hedera.Visits = new Class({
Extends: Hedera.Form
,activate: function() {
this.$.from.value = new Date();
this.$.to.value = new Date();
}
,onRefreshClick: function() {
this.$.visits.refresh();
}
,onSessionsClick: function() {
this.hash.set({form: 'admin/connections'});
if (!this.hash.$.to)
this.hash.assign({
from: new Date(),
to: new Date()
});
}
});

View File

@ -3,7 +3,7 @@ Hedera.Packages = new Class({
Extends: Hedera.Form
,onShowClick: function(column, agencyId) {
this.hash.set({
this.hash.setAll({
form: 'agencies/provinces',
agency: agencyId
});

View File

@ -1,6 +1,5 @@
Hedera.Provinces = new Class
({
Hedera.Provinces = new Class({
Extends: Hedera.Form
});

View File

@ -1,23 +1,12 @@
<vn>
<vn-group>
<vn-param id="agency"/>
<vn-hash-param key="agency" param="agency"/>
</vn-group>
<div id="title">
<h1><t>ByProvince</t></h1>
</div>
<div id="form" class="provinces vn-w-sm">
<div class="box">
<htk-grid>
<db-model property="model">
<custom>
CALL vn2008.desglose_volume(#agency)
</custom>
<sql-batch property="batch">
<custom>
<item name="agency" param="agency"/>
</custom>
</sql-batch>
<db-model property="model" lot="hash">
CALL vn2008.desglose_volume(#agency)
</db-model>
<htk-column-text title="_Province" column="Provincia"/>
<htk-column-spin title="_Expeditions" column="expediciones"/>

View File

@ -7,7 +7,7 @@
class="start-order"
icon="add_shopping_cart"
tip="_Start order"
on-click="this.hash.set({form: 'ecomerce/catalog'})"/>
on-click="$.hash.setAll({form: 'ecomerce/catalog'})"/>
</div>
<div id="form" class="home">
<div class="column mansonry" id="news-column">

View File

@ -6,7 +6,7 @@ Hedera.Basket = new Class({
this.close();
this.isOpen = true;
Hedera.BasketChecker.check(this.conn,
Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this));
}
@ -21,7 +21,7 @@ Hedera.Basket = new Class({
,onConfigureClick: function() {
Htk.Toast.showWarning(_('RememberReconfiguringImpact'));
this.hash.set({form: 'ecomerce/checkout'});
this.hash.setAll({form: 'ecomerce/checkout'});
}
,onDeleteClick: function(form) {

View File

@ -10,11 +10,11 @@
<htk-bar-button
icon="local_florist"
tip="_Catalog"
on-click="this.hash.set({form: 'ecomerce/catalog'})"/>
on-click="this.hash.setAll({form: 'ecomerce/catalog'})"/>
<htk-bar-button
icon="shopping_cart_checkout"
tip="_Checkout"
on-click="this.hash.set({form: 'ecomerce/confirm'})"/>
on-click="this.hash.setAll({form: 'ecomerce/confirm'})"/>
</div>
<div id="form" class="basket">
<div class="box vn-w-sm vn-pa-lg">

View File

@ -8,8 +8,8 @@ Hedera.Catalog = new Class({
this.close();
this.isOpen = true;
if (!localStorage.getItem('hederaGuest')) {
Hedera.BasketChecker.check(this.conn,
if (!localStorage.getItem('hederaGuest')) {
Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this));
} else {
var query = 'CALL mybasket_configureForGuest';
@ -31,7 +31,7 @@ Hedera.Catalog = new Class({
else
this.setView(Hedera.Catalog.View.GRID);
this.onRealmChange();
this.onFilterChange();
}
,deactivate: function() {
@ -40,77 +40,80 @@ Hedera.Catalog = new Class({
Vn.Node.remove(this.$.rightPanel);
}
,getFilter(params, tags, currentTag) {
if (params.search == null && params.type == null)
return null;
const $ = this.$;
params = Object.assign({}, params);
const filter = new Sql.Operation({
type: Sql.Operation.Type.AND
});
let idSearch = false;
if (params.search != null) {
idSearch = /^\d+$/.test(params.search);
if (!idSearch) {
filter.push($.searchOp);
params.search = `%${params.search}%`;
} else
filter.push($.idOp);
}
if (!idSearch) {
if (params.realm != null)
filter.push($.realmOp);
if (params.type != null)
filter.push($.typeOp);
for (const tag of tags)
if (tag != currentTag && params[tag] != null)
filter.push($[`${tag}Op`]);
}
params.filter = filter;
const lot = new Vn.Lot();
lot.setAll(params);
return lot;
}
,onFilterChange: function() {
const $ = this.$;
const params = [
'search',
'realm',
'type',
const params = $.params.$;
this.refreshTitle();
const hasRealm = params.realm != null;
$.filters.style.display = hasRealm ? 'block' : 'none';
$.realmMsg.style.display = hasRealm ? 'none' : 'block';
const tags = [
'color',
'origin',
'category',
'producer'
];
const lot = {};
for (const param of params)
lot[param] = this.$[param].value;
if (lot.search != null || lot.type != null) {
const filter = new Sql.Operation({
type: Sql.Operation.Type.AND
});
const exprs = filter.exprs;
let idSearch = false;
if (lot.search != null) {
idSearch = /^\d+$/.test(lot.search);
exprs.add(idSearch ? $.idOp : $.nameOp);
}
if (!idSearch) {
if (lot.realm != null)
exprs.add($.realmOp);
if (lot.type != null)
exprs.add($.typeOp);
const tags = [
'color',
'origin',
'category',
'producer'
];
for (const tag of tags)
if (lot[tag] != null)
exprs.add($[`${tag}Op`]);
}
const batch = new Sql.Batch();
batch.addObject('filter', filter);
batch.block();
$.items.batch = batch;
const lot = this.getFilter(params, tags);
if (lot) {
$.items.lot = lot;
$.items.refresh();
} else
$.items.batch = null;
}
,onRealmChange: function() {
const hasRealm = this.$.realm.value != null;
this.$.filters.style.display = hasRealm ? 'block' : 'none';
this.$.realmMsg.style.display = hasRealm ? 'none' : 'block';
this.onFilterChange();
this.refreshTitle();
}
$.items.clean();
,onTypeChange: function() {
this.onFilterChange();
this.refreshTitle();
for (const tag of tags)
$[`${tag}s`].lot = this.getFilter(params, tags, tag);
}
,refreshTitle: function() {
const hash = this.hash.$;
const types = this.$.types;
const realms = this.$.realms;
const type = this.$.type.value;
const realm = this.$.realm.value;
const type = hash.type;
const realm = hash.realm;
let typeName;
let realmName;
@ -234,14 +237,14 @@ Hedera.Catalog = new Class({
if (this.isGuest())
return;
this.hash.set({form: 'ecomerce/basket'});
this.hash.setAll({form: 'ecomerce/basket'});
}
,onConfigureClick: function() {
if (this.isGuest())
return;
this.hash.set({form: 'ecomerce/checkout'});
this.hash.setAll({form: 'ecomerce/checkout'});
}
,onAddItemClick: function(event, form) {
@ -251,7 +254,7 @@ Hedera.Catalog = new Class({
this.onEraseClick();
this.$.card.row = form.row;
this.$.cardItem.value = form.$.id;
this.$.cardLot.assign({item: form.$.id});
this.$.cardPopup.show(event.currentTarget);
}
@ -280,7 +283,6 @@ Hedera.Catalog = new Class({
,onConfirmClick: function() {
var sql = '';
var batch = new Sql.Batch();
var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'});
var amountSum = 0;
@ -288,10 +290,12 @@ Hedera.Catalog = new Class({
var amount = this.items[warehouse];
amountSum += amount;
batch.addValue('warehouse', warehouse);
batch.addValue('item', this.$.cardItem.value);
batch.addValue('amount', amount);
sql += query.render(batch);
const params = {
warehouse: warehouse,
item: this.$.cardLot.$.item,
amount: amount
}
sql += query.render(params);
}
if (amountSum > 0) {
@ -299,7 +303,7 @@ Hedera.Catalog = new Class({
var itemName = this.$.card.get('item');
Htk.Toast.showMessage(
sprintf(_('Added%dOf%s'), amountSum, itemName));
Vn.Value.sprintf(_('Added%dOf%s'), amountSum, itemName));
}
this.$.cardPopup.hide();
@ -313,7 +317,7 @@ Hedera.Catalog = new Class({
,onPopupClose: function() {
this.onEraseClick();
this.$.card.row = -1;
this.$.cardItem.value = undefined;
this.$.cardLot.value = undefined;
}
,onCardLoad: function() {
@ -327,163 +331,3 @@ Hedera.Catalog.extend({
GRID: 1
}
});
Vn.Filter = new Class({
Extends: Htk.Field
,Tag: 'vn-filter'
,Child: 'model'
,Properties: {
model: {
type: Db.Model
,set: function(x) {
x.batch = this._batch;
this._model = x;
this._select.model = x;
}
,get: function() {
return this._model;
}
},
placeholder: {
type: String
,set: function(x) {
this._select.placeholder = x;
this._placeholder = x;
}
,get: function() {
return this._placeholder;
}
},
filter: {
type: Sql.Filter
,set: function(x) {
this._filter = x;
this._batch.addObject('filter', x);
}
,get: function() {
return this._filter;
}
}
}
,_valueColumnIndex: 0
,_showColumnIndex: 1
,initialize: function(props) {
var node = this.createRoot('div');
node.className = 'vn-filter';
this._select = new Htk.Select();
this._select.on('mousedown', this._onMouseDown, this);
this._select.on('changed', this._onChange, this);
this._select.on('ready', this._onReady, this);
this.node.appendChild(this._select.node);
this._ul = this.createElement('ul');
this.node.appendChild(this._ul);
this._batch = new Sql.Batch();
this.parent(props);
}
,_onMouseDown: function() {
if (this._model && this._model.status === Db.Model.Status.CLEAN)
this._model.refresh();
}
,_onCloseClick: function() {
this._removeSelectionNode();
this._changeValue(undefined);
}
,_removeSelectionNode: function() {
if (this._lastLi) {
Vn.Node.remove(this._lastLi);
this._lastLi = null;
this._label = null;
}
}
,_onChange: function() {
if (this._select.value === null
|| this._select.value === undefined)
return;
this._realSetValue(this._select.value);
}
,_onReady: function() {
if (this._emptyLabel)
this._refreshLabel();
}
,_changeValue: function(newValue) {
this._batch.block();
this.value = newValue;
this._batch.unblock();
}
,_onTimeout: function() {
this._select.value = null;
}
,putValue: function(value) {
this._onMouseDown();
this._realSetValue(value);
}
,_realSetValue: function(value) {
this._removeSelectionNode();
if (value === null || value === undefined)
return;
var li = this._lastLi = this.createElement('li');
this._ul.appendChild(li);
var button = this.createElement('button');
button.addEventListener('click',
this._onCloseClick.bind(this, li));
li.appendChild(button);
var icon = new Htk.Icon({
name: 'close',
alt: _('Close')
});
button.appendChild(icon.node);
var text = this._label = this.createTextNode('');
li.appendChild(text);
setTimeout(this._onTimeout.bind(this));
this._changeValue(value);
this._refreshLabel();
}
,_refreshLabel: function() {
if (!this._label)
return;
let row = -1;
const model = this._model;
let showValue = '';
this._emptyLabel = true;
if (model) {
if (model.ready) {
row = model.searchByIndex(this._valueColumnIndex, this._value);
if (row != -1) {
var label = model.getByIndex(row, this._showColumnIndex);
showValue = label;
this._emptyLabel = false;
}
} else
showValue = _('Loading...');
}
this._label.nodeValue = showValue;
}
});

View File

@ -88,41 +88,7 @@
padding: 0;
width: 100%;
}
.right-panel .vn-filter,
.right-panel select {
margin: 0 auto;
margin-bottom: .7em;
display: block;
}
.vn-filter > ul {
margin: 0;
list-style-type: none;
text-align: left;
color: #666;
padding-left: .8em;
}
.vn-filter li {
margin: 0;
margin-top: .3em;
line-height: 2em;
max-width: 90%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.vn-filter li > button {
vertical-align: middle;
text-align: center;
padding: .2em;
margin: 0;
margin-right: .2em;
}
.vn-filter li > button > span {
display: block;
}
.right-panel .filters > button {
display: block;
margin: 0 auto;
margin-top: 1em;
}
@ -157,7 +123,7 @@
font-size: 1em;
text-overflow: ellipsis;
overflow: hidden;
max-height: 2.8em;
max-height: 3em;
}
.item-info > p {
margin: 0;
@ -247,7 +213,7 @@
flex-direction: column;
width: 240px;
height: 405px;
height: 410px;
overflow: hidden;
}
.grid-view .item-box:hover {

View File

@ -4,8 +4,7 @@
<div id="subtitle"></div>
</div>
<div id="actions" class="catalog-actions">
<htk-search-entry
param="search"/>
<htk-search-entry form="params" column="search"/>
<htk-bar-button
id="view-button"
tip="_Switch view"
@ -22,68 +21,70 @@
</button>
</div>
<vn-group>
<vn-hash-param key="realm" param="realm"/>
<vn-hash-param key="type" param="type"/>
<vn-lot-query id="params" on-change="this.onFilterChange()">
<vn-spec name="search" type="String"/>
<vn-spec name="realm" type="Number"/>
<vn-spec name="type" type="Number"/>
</vn-lot-query>
<vn-lot id="filter-lot"/>
</vn-group>
<vn-group>
<vn-param id="card-item"/>
<vn-param id="search" on-changed="this.onFilterChange()"/>
<vn-param id="realm" on-changed="this.onRealmChange()"/>
<vn-param id="type" on-changed="this.onTypeChange()"/>
<vn-param id="color" on-changed="this.onFilterChange()"/>
<vn-param id="origin" on-changed="this.onFilterChange()"/>
<vn-param id="category" on-changed="this.onFilterChange()"/>
<vn-param id="producer" on-changed="this.onFilterChange()"/>
</vn-group>
<vn-group>
<sql-operation
<sql-filter-item
id="id-op"
type="EQUAL">
<sql-field target="i" name="id"/>
<sql-value param="search"/>
</sql-operation>
type="EQUAL"
target="i"
field="id"
param="search"/>
<sql-operation
id="name-op"
type="LIKE">
<sql-field target="i" name="longName"/>
<sql-search-tags param="search"/>
id="search-op"
type="OR">
<sql-filter-item
type="LIKE"
target="i"
field="longName"
param="search"/>
<sql-filter-item
type="LIKE"
target="i"
field="subname"
param="search"/>
</sql-operation>
<sql-operation
<sql-filter-item
id="realm-op"
type="EQUAL">
<sql-field target="t" name="categoryFk"/>
<sql-value param="realm"/>
</sql-operation>
<sql-operation
type="EQUAL"
target="t"
field="categoryFk"
param="realm"/>
<sql-filter-item
id="type-op"
type="EQUAL">
<sql-field target="i" name="typeFk"/>
<sql-value param="type"/>
</sql-operation>
<sql-operation
type="EQUAL"
target="i"
field="typeFk"
param="type"/>
<sql-filter-item
id="color-op"
type="EQUAL">
<sql-field target="i" name="inkFk"/>
<sql-value param="color"/>
</sql-operation>
<sql-operation
type="EQUAL"
id="origin-op">
<sql-field target="i" name="originFk"/>
<sql-value param="origin"/>
</sql-operation>
<sql-operation
target="i"
field="inkFk"
param="color"/>
<sql-filter-item
type="EQUAL"
id="category-op">
<sql-field target="i" name="category"/>
<sql-value param="category"/>
</sql-operation>
<sql-operation
id="origin-op"
target="i"
field="originFk"
param="origin"/>
<sql-filter-item
type="EQUAL"
id="category-op"
target="i"
field="category"
param="category"/>
<sql-filter-item
id="producer-op"
type="EQUAL">
<sql-field target="i" name="producerFk"/>
<sql-value param="producer"/>
</sql-operation>
type="EQUAL"
target="i"
field="producerFk"
param="producer"/>
</vn-group>
<vn-group>
<db-form id="basket" on-ready="onBasketReady">
@ -96,6 +97,7 @@
</db-form>
<db-model
id="items"
auto-load="false"
result-index="2"
on-status-changed="onItemsChange">
CREATE TEMPORARY TABLE tmp.item
@ -125,11 +127,7 @@
LIMIT 5000;
</db-model>
<db-form id="card" model="items"/>
<sql-batch id="card-batch">
<custom>
<item name="item" param="card-item"/>
</custom>
</sql-batch>
<vn-lot id="card-lot"/>
</vn-group>
<div id="form" class="catalog">
<div id="main" class="main">
@ -241,14 +239,16 @@
</div>
<div id="filters" class="filters">
<h2><t>Filter by</t></h2>
<vn-filter
<htk-combo
placeholder="_Family"
param="type"
form="params"
column="type"
id="type-filter">
<db-model
id="types"
property="model"
conn="conn"
lot="params"
result-index="1"
on-status-changed="refreshTitle">
CALL myBasket_getAvailable;
@ -257,21 +257,21 @@
JOIN vn.itemType t ON t.id = i.typeFk
JOIN tmp.itemAvailable a ON a.id = i.id
JOIN vn.itemTypeL10n l ON l.id = t.id
WHERE t.`order` >= 0 AND #filter
WHERE t.`order` >= 0
AND t.categoryFk = #realm
ORDER BY t.`order`, l.name
</db-model>
<sql-filter property="filter" type="AND">
<sql-filter-item type="EQUAL">
<sql-field name="categoryFk" target="t"/>
<sql-value param="realm"/>
</sql-filter-item>
</sql-filter>
</vn-filter>
<vn-filter
</htk-combo>
<htk-combo
placeholder="_Color"
param="color"
id="color-filter">
<db-model property="model" auto-load="false" result-index="1">
form="params"
column="color"
on-mousedown="$.colors.lazyRefresh()">
<db-model
id="colors"
property="model"
auto-load="false"
result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT l.id, l.name
FROM vn.item i
@ -281,12 +281,17 @@
WHERE #filter
ORDER BY name
</db-model>
</vn-filter>
<vn-filter
</htk-combo>
<htk-combo
placeholder="_Producer"
param="producer"
id="producer-filter">
<db-model property="model" auto-load="false" result-index="1">
form="params"
column="producer"
on-mousedown="$.producers.lazyRefresh()">
<db-model
id="producers"
property="model"
auto-load="false"
result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT p.id, p.name
FROM vn.item i
@ -296,12 +301,17 @@
WHERE #filter
ORDER BY name
</db-model>
</vn-filter>
<vn-filter
</htk-combo>
<htk-combo
placeholder="_Origin"
param="origin"
id="origin-filter">
<db-model property="model" auto-load="false" result-index="1">
form="params"
column="origin"
on-mousedown="$.origins.lazyRefresh()">
<db-model
id="origins"
property="model"
auto-load="false"
result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT o.id, l.name, o.code
FROM vn.item i
@ -312,12 +322,17 @@
WHERE #filter
ORDER BY name
</db-model>
</vn-filter>
<vn-filter
</htk-combo>
<htk-combo
placeholder="_Category"
param="category"
id="category-filter">
<db-model property="model" auto-load="false" result-index="1">
form="params"
column="category"
on-mousedown="$.categorys.lazyRefresh()">
<db-model
id="categorys"
property="model"
auto-load="false"
result-index="1">
CALL myBasket_getAvailable;
SELECT DISTINCT i.category, i.category
FROM vn.item i
@ -326,7 +341,7 @@
WHERE #filter
ORDER BY category
</db-model>
</vn-filter>
</htk-combo>
</div>
<div id="order" class="order">
<h2><t>Order by</t></h2>
@ -383,7 +398,7 @@
<db-form id="card-extend">
<db-model
property="model"
batch="card-batch"
lot="card-lot"
on-status-changed-after="onCardLoad">
SELECT i.description, o.name origin
FROM vn.item i
@ -421,7 +436,7 @@
<htk-repeater show-status="false" form-id="tag" class="tags">
<db-model
property="model"
batch="card-batch"
lot="card-lot"
on-status-changed-after="onCardLoad">
SELECT l.name, it.value
FROM vn.itemTag it
@ -445,7 +460,7 @@
property="model"
result-index="1"
on-status-changed-after="onCardLoad"
batch="card-batch">
lot="card-lot">
CALL myBasket_calcCatalogFromItem(#item);
SELECT l.warehouseFk, w.name warehouse, p.`grouping`,
p.price, p.priceKg, p.rate, l.available

View File

@ -40,12 +40,13 @@ Hedera.Checkout = new Class({
date.setDate(date.getDate() + addDays);
}
this.$.date.value = date;
this.$.method.value = row.deliveryMethod;
this.$.agency.value = row.agencyModeFk;
this.$.address.value = row.addressFk;
this.$.lot.assign({
date: date,
method: row.deliveryMethod,
agency: row.agencyModeFk,
address: row.addressFk
});
this.autoStepLocked = false;
},
@ -57,15 +58,8 @@ Hedera.Checkout = new Class({
this.disableButtons(true);
var query = 'CALL myBasket_configure(#date, #method, #agency, #address)';
var batch = new Sql.Batch();
batch.addParam('method', this.$.method);
batch.addParam('date', this.$.date);
batch.addParam('agency', this.$.agency);
batch.addParam('address', this.$.address);
this.conn.execQuery(query,
this.onBasketConfigured.bind(this), batch);
this.onBasketConfigured.bind(this), this.$.lot.$);
},
onBasketConfigured: function(resultSet) {
@ -79,14 +73,14 @@ Hedera.Checkout = new Class({
else
Htk.Toast.showMessage(_('OrderStarted'));
this.hash.set({form: 'ecomerce/catalog'});
this.hash.setAll({form: 'ecomerce/catalog'});
},
onCancelClick: function() {
if (this.$.orderForm.numRows > 0)
window.history.back();
else
this.hash.set({form: 'ecomerce/orders'});
this.hash.setAll({form: 'ecomerce/orders'});
},
agencySteps: ['method', 'date', 'address', 'agency', 'confirm-delivery'],
@ -157,13 +151,8 @@ Hedera.Checkout = new Class({
this.$.assistant.moveNext();
},
addressRenderer: function(builder, form) {
builder.$.address.addEventListener('click',
this.onAddressClick.bind(this, form.$.id));
},
onAddressClick: function(addressId) {
this.$.address.value = addressId;
this.$.lot.set('address', addressId);
this.goNextStep();
},
@ -171,7 +160,7 @@ Hedera.Checkout = new Class({
if (this.selectedNode)
Vn.Node.removeClass(this.selectedNode, 'selected');
var row = this.$.addresses.search('id', this.$.address.value);
var row = this.$.addresses.search('id', this.$.lot.$.address);
if (row != -1) {
var builder = this.$.repeater.getBuilder(row);
@ -201,7 +190,7 @@ Hedera.Checkout = new Class({
}
this.autoStepLocked = true;
this.$.agency.value = agency;
this.$.lot.assign({agency});
this.autoStepLocked = false;
} else
Htk.Toast.showError(_('NoAgeciesAvailableForDate'));

View File

@ -1,9 +1,6 @@
<vn>
<vn-group>
<vn-param id="method"/>
<vn-param id="date"/>
<vn-param id="agency"/>
<vn-param id="address" on-changed="onAddressChange"/>
<vn-lot id="lot" on-change="this.onAddressChange()"/>
<db-form id="defaults" on-ready="onValuesReady">
<db-model property="model">
SELECT deliveryMethod, agencyModeFk, addressFk, defaultAgencyFk
@ -19,6 +16,7 @@
</db-form>
<db-model id="agencies"
auto-load="false"
lot="lot"
result-index="1"
on-status-changed="onAgenciesReady">
CALL vn.zone_getAgency(#address, #date);
@ -30,15 +28,10 @@
AND a.isVisible
ORDER BY a.description;
DROP TEMPORARY TABLE tmp.zoneGetAgency;
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model>
<db-model id="warehouses"
auto-load="false"
lot="lot"
result-index="1"
on-status-changed="onWarehousesReady">
CALL vn.zone_getAgency(#address, #date);
@ -50,12 +43,6 @@
AND a.isVisible
ORDER BY a.description;
DROP TEMPORARY TABLE tmp.zoneGetAgency;
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model>
</vn-group>
<div id="title">
@ -85,7 +72,8 @@
<div class="answers radio">
<htk-radio-group
id="rg-method"
param="method"
form="lot"
column="method"
on-changed="onMethodChange"/>
<div>
<label>
@ -110,7 +98,8 @@
<htk-calendar
id="calendar"
class="thin-calendar"
param="date"
form="lot"
column="date"
restrict-func="calendarRestrict"
on-changed="onFieldChange"/>
</div>
@ -125,8 +114,7 @@
<htk-repeater
id="repeater"
form-id="iter"
on-change="onAddressChange"
renderer="addressRenderer">
on-change="onAddressChange">
<db-model property="model" id="addresses">
SELECT a.id, a.nickname, p.name province, a.city, a.street, a.isActive, c.country
FROM myAddress a
@ -135,13 +123,12 @@
WHERE a.isActive
</db-model>
<custom>
<div class="address" id="address">
<p class="consignee">
<htk-text form="iter" column="nickname"/>
</p>
<p>
<htk-text form="iter" column="street"/>
</p>
<div
class="address"
on-click="this.onAddressClick(iter.id)"
id="address">
<p class="consignee">{{iter.nickname}}</p>
<p>{{iter.street}}</p>
</div>
</custom>
</htk-repeater>
@ -155,7 +142,8 @@
<div class="answers target">
<htk-combo
id="agency-combo"
param="agency"
form="lot"
column="agency"
on-changed="onFieldChange"
model="agencies"/>
</div>
@ -168,7 +156,8 @@
<div class="answers target">
<htk-combo
id="warehouse-combo"
param="agency"
form="lot"
column="agency"
on-changed="onFieldChange"
model="warehouses"/>
</div>
@ -179,7 +168,7 @@
<div class="answers target">
<p>
<t>Arrival</t>
<htk-text format="%D" param="date"/>
<htk-text format="%D" form="lot" column="date"/>
</p>
<p>
<htk-text form="address-form" column="street"/>
@ -197,7 +186,7 @@
<div class="answers target">
<p>
<t>Pickup</t>
<htk-text format="%D" param="date"/>
<htk-text format="%D" form="lot" column="date"/>
</p>
<p>
<t>Warehouse</t>

View File

@ -6,7 +6,7 @@ Hedera.Confirm = new Class({
this.close();
this.isOpen = true;
Hedera.BasketChecker.check(this.conn,
Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this));
},
@ -139,10 +139,13 @@ Hedera.Confirm = new Class({
else
var payAmount = this.$.totalAmount.value;
var tpv = new Hedera.Tpv({conn: this.conn});
var tpv = new Hedera.Tpv({
conn: this.conn,
hash: this.hash
});
tpv.pay(payAmount, this.$.orderForm.$.companyFk);
} else
this.hash.set({'form': 'ecomerce/orders'});
this.hash.setAll({'form': 'ecomerce/orders'});
}
});

View File

@ -3,7 +3,10 @@ Hedera.Orders = new Class({
Extends: Hedera.Form,
activate: function() {
this.tpv = new Hedera.Tpv({conn: this.conn});
this.tpv = new Hedera.Tpv({
conn: this.conn,
hash: this.hash
});
this.tpv.check(this._onTpvCheck.bind(this));
},
@ -13,7 +16,7 @@ Hedera.Orders = new Class({
},
onBasketClick: function() {
this.hash.set({form: 'ecomerce/basket'});
this.hash.setAll({form: 'ecomerce/basket'});
},
repeaterFunc: function(res, form) {

View File

@ -6,9 +6,8 @@ Hedera.Ticket = new Class({
if (!ticket.value)
return;
var batch = new Sql.Batch();
batch.addValue('ticket', ticket.value);
this.conn.execQuery('CALL myTicket_logAccess(#ticket)', null, batch);
var params = {ticket: ticket.value};
this.conn.execQuery('CALL myTicket_logAccess(#ticket)', null, params);
},
onTicketReady: function(form) {

View File

@ -1,18 +1,10 @@
<vn>
<vn-group>
<vn-param id="ticket-id" on-changed="onTicketChange"/>
<vn-hash-param key="ticket" param="ticket-id"/>
<sql-batch id="batch">
<custom>
<item name="ticket" param="ticket-id"/>
</custom>
</sql-batch>
<db-form id="ticket" on-ready="onTicketReady">
<db-model id="ticket-data" property="model" batch="batch">
CALL myTicket_get(#ticket)
</db-model>
</db-form>
</vn-group>
<vn-lot-query id="params">
<vn-spec name="ticket" type="Number"/>
</vn-lot-query>
<db-lot id="ticket" lot="params" on-ready="onTicketReady">
CALL myTicket_get(#ticket)
</db-lot>
<div id="title">
<h1><t>OrderDetail</t></h1>
</div>
@ -20,7 +12,7 @@
<htk-bar-button
icon="print"
tip="_Print delivery note"
on-click="onPrintClick"/>
on-click="this.onPrintClick()"/>
</div>
<div id="form" class="ticket">
<div class="box vn-w-sm vn-pa-lg">
@ -67,7 +59,7 @@
<db-model
property="model"
id="movements"
batch="batch">
lot="params">
CALL myTicket_getRows(#ticket)
</db-model>
<custom>
@ -108,7 +100,7 @@
<db-model
property="model"
on-status-changed="onServicesChanged"
batch="batch">
lot="params">
CALL myTicket_getServices(#ticket)
</db-model>
<custom>
@ -133,7 +125,7 @@
<db-model
property="model"
on-status-changed="onPackagesChanged"
batch="batch">
lot="params">
CALL myTicket_getPackages(#ticket)
</db-model>
<custom>

View File

@ -55,7 +55,7 @@ Hedera.New = new Class({
},
onStatusChange: function() {
if (this.$.newId.value == 0)
if (this.hash.$.new == 0)
this.$.iter.insertRow();
},
@ -71,10 +71,6 @@ Hedera.New = new Class({
onAcceptClick: function() {
this.$.iter.set('text', this.editor.getContent());
this.$.iter.performOperations();
},
onReturnClick: function() {
this.hash.set({form: 'news/news'});
}
});
});

View File

@ -1,22 +1,14 @@
<vn>
<vn-group>
<vn-param id="new-id"/>
<vn-hash-param key="new" param="new-id"/>
<db-form id="iter" on-status-changed="this.onStatusChange()">
<db-model
id="model"
property="model"
updatable="true"
lot="hash"
on-operations-done="this.onOperationsDone()">
<custom>
SELECT id, title, text, tag, priority, image
FROM news WHERE id = #new
</custom>
<sql-batch property="batch">
<custom>
<item name="new" param="new-id"/>
</custom>
</sql-batch>
SELECT id, title, text, tag, priority, image
FROM news WHERE id = #new
</db-model>
</db-form>
<db-param form="iter" column="text" on-changed="this.onBodyChange()"/>
@ -28,7 +20,7 @@
<htk-bar-button
icon="close"
tip="_Return"
on-click="this.onReturnClick()"/>
on-click="this.hash.setAll({form: 'news/news'});"/>
<htk-bar-button
icon="check"
tip="_Accept"
@ -55,10 +47,8 @@
<label><t>Tag</t></label>
<htk-combo form="iter" column="tag">
<db-model property="model">
<custom>
SELECT name, description FROM newsTag
ORDER BY description
</custom>
SELECT name, description FROM newsTag
ORDER BY description
</db-model>
</htk-combo>
</div>

View File

@ -3,7 +3,7 @@ Hedera.News = new Class({
Extends: Hedera.Form
,editNew: function(newId) {
this.hash.set({
this.hash.setAll({
form: 'news/new',
new: newId
});

View File

@ -3,18 +3,15 @@ Hedera.ItemsForm = new Class({
Extends: Hedera.Form
,activate: function() {
this.$.warehouse.value = 7;
this.$.realm.value = null;
this.$.lot.assign({
warehouse: 7,
realm: null
});
}
,onPreviewClick: function() {
var batch = new Sql.Batch();
batch.addValues({
warehouse: this.$.warehouse.value
,realm: this.$.realm.value
,rate: this.$.rate.value
});
this.gui.openReport('items-report', batch);
this.$.lot.set('rate', this.$.rate.value);
this.gui.openReport('items-report', this.$.lot);
}
});

View File

@ -1,4 +1,5 @@
<vn>
<vn-lot id="lot"/>
<div id="title">
<h1><t>Item list</t></h1>
</div>
@ -12,25 +13,19 @@
<div class="form box vn-w-sm vn-pa-lg">
<div class="form-group">
<label><t>Store</t></label>
<htk-combo>
<vn-param property="param" id="warehouse"/>
<htk-combo form="lot" column="warehouse">
<db-model property="model">
<custom>
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</custom>
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Realm</t></label>
<htk-combo not-null="false">
<vn-param property="param" id="realm"/>
<htk-combo form="lot" column="realm" not-null="false">
<db-model property="model">
<custom>
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</custom>
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</db-model>
</htk-combo>
</div>

View File

@ -3,49 +3,18 @@ Hedera.Shelves = new Class({
Extends: Hedera.Form
,activate: function() {
this.$.date.value = new Date();
this.$.useIds.value = false;
this.$.lot.assign({
date: new Date(),
useIds: false
});
}
,onConfigChange: function() {
const fields = [
'realm'
,'family'
,'warehouse'
,'shelf'
,'namePrefix'
,'maxAmount'
,'reportTitle'
,'showPacking'
,'stack'
];
const config = this.$.config.$;
if (config)
for (const field of fields)
this.$[field].value = config[field];
this.$.lot.assignLot(this.$.config);
}
,onPreviewClick: function() {
var fields = [
'family'
,'warehouse'
,'shelf'
,'namePrefix'
,'maxAmount'
,'reportTitle'
,'showPacking'
,'stack'
,'useIds'
,'date'
];
var batch = new Sql.Batch();
for (const field of fields)
batch.addValue(field, this.$[field].value);
this.gui.openReport('shelves-report', batch);
this.gui.openReport('shelves-report', this.$.lot);
}
});

View File

@ -1,14 +1,8 @@
<vn>
<vn-group>
<db-model property="model" id="configs-model">
<custom>
SELECT c.id, c.name reportTitle, c.namePrefix, c.warehouse, c.family,
c.shelf, c.maxAmount, c.showPacking, c.stack, t.reino_id realm
FROM shelfConfig c
JOIN vn2008.Tipos t ON t.tipo_id = c.family
</custom>
</db-model>
</vn-group>
<vn-lot-query id="params">
<vn-spec name="config" type="Number"/>
</vn-lot-query>
<vn-lot id="lot"/>
<div id="title">
<h1><t>Shelves</t></h1>
</div>
@ -25,89 +19,84 @@
<htk-combo
id="config"
placeholder="_Select config"
model="configs-model"
form="params"
column="config"
on-changed="this.onConfigChange()"
on-ready="this.onConfigChange()"/>
on-ready="this.onConfigChange()">
<db-model property="model">
SELECT c.id, c.name reportTitle, c.namePrefix, c.warehouse, c.family,
c.shelf, c.maxAmount, c.showPacking, c.stack, t.reino_id realm
FROM shelfConfig c
JOIN vn2008.Tipos t ON t.tipo_id = c.family
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Date</t></label>
<htk-date-chooser id="date"/>
<htk-date-chooser form="lot" name="date"/>
</div>
<div class="form-group">
<label><t>Reign</t></label>
<htk-combo id="realm">
<db-model property="model" id="realms">
<custom>
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</custom>
<htk-combo form="lot" name="realm">
<db-model property="model">
SELECT id, reino FROM vn2008.reinos
WHERE display != FALSE ORDER BY reino
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Family</t></label>
<htk-combo id="family">
<db-model property="model">
<custom>
SELECT tipo_id, Tipo FROM vn2008.Tipos
WHERE reino_id = #realm ORDER BY Tipo
</custom>
<sql-batch property="batch">
<custom>
<item name="realm" param="realm"/>
</custom>
</sql-batch>
<htk-combo form="lot" name="family">
<db-model property="model" lot="lot">
SELECT tipo_id, Tipo FROM vn2008.Tipos
WHERE reino_id = #realm ORDER BY Tipo
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Store</t></label>
<htk-combo id="warehouse">
<db-model property="model" id="warehouses">
<custom>
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</custom>
<htk-combo form="lot">
<db-model property="model">
SELECT id, name FROM vn2008.warehouse
WHERE reserve ORDER BY name
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Shelf</t></label>
<htk-combo id="shelf">
<db-model property="model" id="shelves">
<custom>
SELECT id, name FROM shelf
</custom>
<htk-combo form="lot" name="shelf">
<db-model property="model">
SELECT id, name FROM shelf
</db-model>
</htk-combo>
</div>
<div class="form-group">
<label><t>Name prefix</t></label>
<htk-entry id="namePrefix"/>
<htk-entry form="lot" name="namePrefix"/>
</div>
<div class="form-group">
<label><t>Limit amount per item</t></label>
<htk-entry id="maxAmount"/>
<htk-entry form="lot" name="maxAmount"/>
</div>
<div class="form-group">
<label><t>Title</t></label>
<htk-entry id="reportTitle"/>
<htk-entry form="lot" name="reportTitle"/>
</div>
<div class="form-group">
<label>
<htk-check id="showPacking"/>
<htk-check form="lot" name="showPacking"/>
<t>Show packing</t>
</label>
</div>
<div class="form-group">
<label>
<htk-check id="stack"/>
<htk-check form="lot" name="stack"/>
<t>Stack different items</t>
</label>
</div>
<div class="form-group">
<label>
<htk-check id="useIds"/>
<htk-check form="lot" name="useIds"/>
<t>Use ids instead of names</t>
</label>
</div>

View File

@ -12,15 +12,13 @@
var Connection = new Class();
module.exports = Connection;
var Flag =
{
var Flag = {
NOT_NULL : 1
,PRI_KEY : 2
,AI : 512 | 2 | 1
};
var Type =
{
var Type = {
BOOLEAN : 1
,INTEGER : 3
,DOUBLE : 4
@ -53,10 +51,10 @@ Connection.implement({
*
* @param {Sql.Stmt} stmt The statement
* @param {Function} callback The function to call when operation is done
* @param {Sql.Batch} batch The batch used to set the parameters
* @param {Object} params The query params
*/
,execStmt: function(stmt, callback, batch) {
this.execSql(stmt.render(batch), callback);
,execStmt: function(stmt, callback, params) {
this.execSql(stmt.render(params), callback);
}
/**
@ -64,10 +62,10 @@ Connection.implement({
*
* @param {String} query The SQL statement
* @param {Function} callback The function to call when operation is done
* @param {Sql.Batch} batch The batch used to set the parameters
* @param {Object} params The query params
*/
,execQuery: function(query, callback, batch) {
this.execStmt(new Sql.String({query: query}), callback, batch);
,execQuery: function(query, callback, params) {
this.execStmt(new Sql.String({query: query}), callback, params);
}
/*

109
js/db/db-lot.js Normal file
View File

@ -0,0 +1,109 @@
var Connection = require('./connection');
var Model = require('./model');
module.exports = new Class({
Extends: Vn.Form
,Tag: 'db-lot'
,Properties: {
/**
* The connection used to execute the statement.
*/
conn: {
type: Connection
,set: function(x) {
this.model.conn = x;
}
,get: function() {
return this.model.conn;
}
},
/**
* The model query.
*/
query: {
type: String
,set: function(x) {
this.model.query = x;
}
,get: function() {
return this.model.query;
}
},
/**
* The model select statement.
*/
stmt: {
type: Sql.Stmt
,set: function(x) {
this.model.stmt = x;
}
,get: function() {
return this.model.stmt;
}
},
/**
* The lot used to execute the statement.
*/
lot: {
type: Vn.Lot
,set: function(x) {
this.model.lot = x;
}
,get: function() {
return this.model.lot;
}
}
}
,initialize: function(props) {
this.model = new Model();
Vn.Form.prototype.initialize.call(this, props);
}
,appendChild: function(child) {
if (child.nodeType === Node.TEXT_NODE)
this.query = child.textContent;
}
,refresh: function() {
if (this._model)
this._model.refresh();
}
,performOperations: function() {
if (this._model)
this._model.performOperations();
}
/**
* Get the index of the column from its name.
*
* @param {string} columnName The column name
* @return {integer} The column index or -1 if column not exists
*/
,getColumnIndex: function(columnName) {
return this._model ?
this._model.getColumnIndex(columnName) : -1;
}
/**
* Gets a value from the form using the column index.
*
* @param {string} columnName The column index
* @return {Object} The value
*/
,getByIndex: function(column) {
return this._model.getByIndex(this._row, column);
}
/**
* Sets a value on the form using the column index.
*
* @param {string} columnName The column index
* @param {Object} value The new value
*/
,setByIndex: function(column, value) {
return this._model.setByIndex(this._row, column, value);
}
});

View File

@ -1,17 +1,17 @@
require ('sql/sql');
require('sql/sql');
Db = module.exports = {
Connection : require ('./connection')
,Result : require ('./result')
,ResultSet : require ('./result-set')
,Model : require ('./model')
,Iterator : require ('./iterator')
,SimpleIterator : require ('./simple-iterator')
,Form : require ('./form')
,Param : require ('./param')
,Query : require ('./query')
,Calc : require ('./calc')
,CalcSum : require ('./calc-sum')
Connection : require('./connection')
,Result : require('./result')
,ResultSet : require('./result-set')
,Model : require('./model')
,Iterator : require('./iterator')
,SimpleIterator : require('./simple-iterator')
,Form : require('./form')
,Query : require('./query')
,Calc : require('./calc')
,CalcSum : require('./calc-sum')
,Lot : require('./db-lot')
};

View File

@ -67,7 +67,7 @@ module.exports = new Class({
$: {
type: Object
,get: function() {
return this._model.getObject(this._row);
return this._model && this._model.getObject(this._row);
}
}
}
@ -85,13 +85,13 @@ module.exports = new Class({
this.lastRow = this._row;
this._ready = ready;
this.signalEmit('status-changed');
this.emit('status-changed');
if (this._row == -1)
this.row = this.lastRow;
if (ready)
this.signalEmit('ready');
this.emit('ready');
this.iterChanged();
}

View File

@ -44,10 +44,10 @@ module.exports = new Class({
}
/**
* Emits the 'iter-changed' signal on the form.
* Emits the 'change' signal on the form.
*/
,iterChanged: function() {
this.signalEmit('iter-changed');
this.emit('change');
}
/**
@ -90,6 +90,16 @@ module.exports = new Class({
return this._model.getObject(this._row);
}
/**
* Sets a value on the form.
*
* @param {String} columnName The column name
*/
,get: function(columnName) {
if (!this._model) return undefined;
return this._model.get(this._row, columnName);
}
/**
* Sets a value on the form.
*

View File

@ -73,16 +73,16 @@ Model.implement({
}
},
/**
* The batch used to execute the statement.
* The lot used to execute the statement.
*/
batch: {
type: Sql.Batch
lot: {
type: Vn.LotIface
,set: function(x) {
this.link({_batch: x}, {'changed': this._autoLoad});
this._autoLoad();
this.link({_lot: x}, {'change': this._onLotChange});
this._onLotChange();
}
,get: function() {
return this._batch;
return this._lot;
}
},
/**
@ -189,7 +189,7 @@ Model.implement({
,_conn: null
,_resultIndex: 0
,_batch: null
,_lot: null
,_stmt: null
,_status: Status.CLEAN
,data: null
@ -197,6 +197,7 @@ Model.implement({
,columns: null
,columnMap: null
,_updatable: false
,_paramsChanged: true
,_requestedSortIndex: -1
,_requestedSortName: null
@ -213,7 +214,7 @@ Model.implement({
,_requestedMainTable: null
,initialize: function(props) {
this.parent(props);
Vn.Object.prototype.initialize.call(this, props);
this._cleanData();
this._setStatus(Status.CLEAN);
}
@ -224,14 +225,66 @@ Model.implement({
}
,loadXml: function(builder, node) {
this.parent(builder, node);
Vn.Object.prototype.loadXml.call(this, builder, node);
var query = node.firstChild.nodeValue;
if (query)
this.query = query;
}
,_getHolders(stmt) {
if (!stmt) return null;
let holders = this._stmt.findHolders();
if (!holders) return null;
if (this._lot) {
const params = this._lot.params;
for (const holder of holders)
if (params[holder] instanceof Sql.Object) {
const paramHolders = params[holder].findHolders();
if (paramHolders)
holders = holders.concat(paramHolders);
}
}
return holders;
}
,_getHolderValues: function() {
let holders = this._getHolders(this._stmt);
if (!holders) return null;
const lotParams = this._lot ? this._lot.params : {};
const params = {};
for (const holder of holders)
if (!(lotParams[holder] instanceof Sql.Object))
params[holder] = lotParams[holder];
return params;
}
,_getHolderParams: function() {
let holders = this._getHolders(this._stmt);
if (!holders) return null;
const lotParams = this._lot ? this._lot.params : {};
const params = {};
for (const holder of holders)
params[holder] = lotParams[holder];
return params;
}
,_onLotChange: function() {
const params = this._getHolderValues();
this._paramsChanged = !Vn.Value.equals(params, this._lastParams);
this._lastParams = params;
if (this.autoLoad)
this.lazyRefresh();
}
,_autoLoad: function() {
if (this.autoLoad)
this.refresh();
@ -239,36 +292,37 @@ Model.implement({
this.clean();
}
,_isReady: function(params) {
if (!this._stmt || !this._conn)
return false;
for (const param in params)
if (params[param] === undefined)
return false;
return true;
}
,lazyRefresh: function() {
if (this._paramsChanged)
this.refresh();
}
/**
* Refresh the model data reexecuting the query on the database.
*/
,refresh: function() {
var ready = false;
if (this._stmt && this._conn) {
var ids = this._stmt.findHolders();
if (ids) {
if (this._batch && this._batch.isReady()) {
ready = true;
const params = this._getHolderParams();
for (var i = 0; i < ids.length; i++)
if (!this._batch.get(ids[i])) {
ready = false;
break;
}
}
} else
ready = true;
}
if (ready) {
if (this._isReady(params)) {
this._setStatus(Status.LOADING);
this._conn.execStmt(this._stmt, this._selectDone.bind(this), this._batch);
this._paramsChanged = false;
this._conn.execStmt(this._stmt,
this._selectDone.bind(this), params);
} else
this.clean();
}
,clean: function() {
this._cleanData();
this._setStatus(Status.CLEAN);
@ -344,7 +398,7 @@ Model.implement({
this._updatable = this._mainTable !== null && this._requestedUpdatable;
if (oldValue != this._updatable)
this.signalEmit('updatable-changed');
this.emit('updatable-changed');
}
,_refreshMainTable: function() {
@ -492,7 +546,7 @@ Model.implement({
*/
,get: function(rowIndex, columnName) {
if (this.checkRowExists(rowIndex))
return this.data[rowIndex][columnName];
return this.data[rowIndex][columnName];
}
/**
@ -541,9 +595,9 @@ Model.implement({
&& op.oldValues[columnName] === undefined)
op.oldValues[columnName] = row[columnName];
this.signalEmit('row-updated-before', rowIndex);
this.emit('row-updated-before', rowIndex);
row[columnName] = value;
this.signalEmit('row-updated', rowIndex, [columnName]);
this.emit('row-updated', rowIndex, [columnName]);
if (this.mode == Mode.ON_CHANGE
&& !(op.type & Operation.INSERT))
@ -596,12 +650,12 @@ Model.implement({
op.type |= Operation.DELETE;
if (!this._requestedMainTable) {
this.signalEmit('row-deleted-before', rowIndex);
this.emit('row-deleted-before', rowIndex);
this.data.splice(rowIndex, 1);
this.signalEmit('row-deleted', rowIndex);
this.emit('row-deleted', rowIndex);
this._refreshRowIndexes(rowIndex);
} else {
this.signalEmit('row-updated-before', rowIndex);
this.emit('row-updated-before', rowIndex);
if (!op.oldValues)
op.oldValues = [];
@ -619,7 +673,7 @@ Model.implement({
updatedCols.push(i);
}
this.signalEmit('row-updated', rowIndex, updatedCols);
this.emit('row-updated', rowIndex, updatedCols);
}
if (this.mode === Mode.ON_CHANGE)
@ -650,7 +704,7 @@ Model.implement({
var op = this._createOperation(rowIndex);
op.type |= Operation.INSERT;
this.signalEmit('row-inserted', rowIndex);
this.emit('row-inserted', rowIndex);
return rowIndex;
}
@ -662,14 +716,14 @@ Model.implement({
var ops = this._operations;
if (ops.length === 0) {
this.signalEmit('operations-done');
this.emit('operations-done');
return;
}
var stmts = new Sql.MultiStmt();
var query = new Sql.String({query: 'START TRANSACTION'});
stmts.addStmt(query);
stmts.push(query);
for (var i = 0; i < ops.length; i++) {
query = null;
@ -690,12 +744,12 @@ Model.implement({
for (var tableIndex in op.tables) {
var stmt = this._createDmlQuery(op, parseInt(tableIndex));
query.addStmt(stmt);
query.push(stmt);
}
}
if (query) {
stmts.addStmt(query);
stmts.push(query);
} else {
console.warn('Db.Model: %s', _('ErrorSavingChanges'));
return;
@ -703,7 +757,7 @@ Model.implement({
}
var query = new Sql.String({query: 'COMMIT'});
stmts.addStmt(query);
stmts.push(query);
this._conn.execStmt(stmts,
this._onOperationsDone.bind(this, ops));
@ -764,8 +818,8 @@ Model.implement({
dmlQuery.addTarget(target);
multiStmt.addStmt(dmlQuery);
multiStmt.addStmt(select);
multiStmt.push(dmlQuery);
multiStmt.push(select);
return multiStmt;
}
@ -795,7 +849,7 @@ Model.implement({
if (op.type & Operation.DELETE) {
resultSet.fetchResult();
} else if (op.type & (Operation.INSERT | Operation.UPDATE)) {
this.signalEmit('row-updated-before', row.index);
this.emit('row-updated-before', row.index);
var updatedCols = [];
var cols = this.columns;
@ -823,14 +877,14 @@ Model.implement({
}
}
this.signalEmit('row-updated', row.index, updatedCols);
this.emit('row-updated', row.index, updatedCols);
}
}
resultSet.fetchResult();
// if (isOperation)
this.signalEmit('operations-done');
this.emit('operations-done');
}
/**
@ -844,9 +898,9 @@ Model.implement({
if (op.type & Operation.DELETE
&& !(op.type & Operation.INSERT)) {
this.data.splice(row.index, 0, row);
this.signalEmit('row-inserted', row.index);
this.emit('row-inserted', row.index);
} else if (op.type & Operation.UPDATE) {
this.signalEmit('row-updated-before', row.index);
this.emit('row-updated-before', row.index);
var updatedCols = [];
var cols = this.columns;
@ -858,7 +912,7 @@ Model.implement({
updatedCols.push(i);
}
this.signalEmit('row-updated', row.index, updatedCols);
this.emit('row-updated', row.index, updatedCols);
}
}
@ -1064,8 +1118,8 @@ Model.implement({
,_setStatus: function(status) {
this._status = status;
this.signalEmit('status-changed', status);
this.signalEmit('status-changed-after', status);
this.emit('status-changed', status);
this.emit('status-changed-after', status);
}
,_createTarget: function(tableIndex) {
@ -1088,8 +1142,8 @@ Model.implement({
const column = this.columnMap[pk];
const equalOp = new Sql.Operation({type: Sql.Operation.Type.EQUAL});
equalOp.exprs.add(new Sql.Field({name: column.orgname}));
where.exprs.add(equalOp);
equalOp.push(new Sql.Field({name: column.orgname}));
where.push(equalOp);
let pkValue = null;
@ -1100,9 +1154,9 @@ Model.implement({
pkValue = op.row[pk];
if (pkValue)
equalOp.exprs.add(new Sql.Value({value: pkValue}));
equalOp.push(new Sql.Value({value: pkValue}));
else if (column.flags & Connection.Flag.AI && !useOldValues)
equalOp.exprs.add(new Sql.Function({name: 'LAST_INSERT_ID'}));
equalOp.push(new Sql.Function({name: 'LAST_INSERT_ID'}));
else
return null;
}

View File

@ -1,105 +0,0 @@
var Form = require('./form');
module.exports = new Class({
Extends: Vn.Param
,Tag: 'db-param'
,Parent: 'form'
,Properties:
{
/**
* The form field referenced by this param.
*/
column:
{
type: String
,set: function(x) {
this._columnName = x;
this.refresh();
}
,get: function() {
this._columnName;
}
},
/**
* The form referenced by this param.
*/
form:
{
type: Form
,set: function(x) {
this.link({_form: x},
{
'status-changed': this.onFormChange
,'iter-changed': this.onIterChange
});
this.refresh();
}
,get: function() {
return this._form;
}
},
/**
* Determines whether the link to the form is unidirectional, ie, a
* change in the form updates the parameter but not vice versa.
*/
oneWay:
{
type: Boolean
,set: function(x) {
this._oneWay = x;
}
,get: function() {
return this._oneWay;
}
}
}
,_columnName: null
,_form: null
,_formLock: false
,_columnIndex: -1
,_oneWay: false
,_formValue: null
,initialize: function(props) {
this.parent(props);
this.on('changed', this.onChange, this);
}
,refresh: function() {
if (this._form) {
this.onFormChange();
this.onIterChange();
}
}
,onFormChange: function() {
if (this._columnName != null)
this._columnIndex = this._form.getColumnIndex(this._columnName);
}
,onIterChange: function() {
if (this._oneWay && this.value != null)
return;
this._formLock = true;
var formValue;
if (this._columnIndex !== -1)
formValue = this._form.getByIndex(this._columnIndex);
else
formValue = undefined;
this.value = formValue;
this._formLock = false;
}
,onChange: function() {
if (!this._formLock && this._columnIndex != -1 && !this.oneWay)
this._form.setByIndex(this._columnIndex, this._value);
}
});

View File

@ -1,100 +1,78 @@
var Connection = require ('./connection');
var Connection = require('./connection');
module.exports = new Class
({
module.exports = new Class({
Extends: Vn.Object
,Tag: 'db-query'
,Properties:
{
,Properties: {
/**
* The connection used to execute the statement.
*/
conn:
{
conn: {
type: Connection
,set: function (x)
{
,set: function(x) {
this._conn = x;
this.onChange ();
this.onChange();
}
,get: function ()
{
,get: function() {
return this._conn;
}
},
/**
* The model query.
*/
query:
{
query: {
type: String
,set: function (x)
{
this._stmt = new Sql.String ({query: x});
this.onChange ();
,set: function(x) {
this._stmt = new Sql.String({query: x});
this.onChange();
}
,get: function ()
{
return this._stmt.render (null);
,get: function() {
return this._stmt.render(null);
}
},
/**
* The model select statement.
*/
stmt:
{
stmt: {
type: Sql.Stmt
,set: function (x)
{
,set: function(x) {
this._stmt = x;
this.onChange ();
this.onChange();
}
,get: function ()
{
,get: function() {
return this._stmt;
}
},
/**
* The batch used to execute the statement.
* The lot used to execute the statement.
*/
batch:
{
type: Sql.Batch
,set: function (x)
{
this.link ({_batch: x}, {'changed': this.onChange});
this.onChange ();
lot: {
type: Vn.LotIface
,set: function(x) {
this.link({_lot: x}, {'change': this.onChange});
this.onChange();
}
,get: function ()
{
return this._batch;
,get: function() {
return this._lot;
}
},
/**
* Wether to execute automatically de query que it's ready.
*/
autoLoad:
{
autoLoad: {
type: Boolean,
value: false
}
}
,initialize: function (props)
{
this.parent (props);
}
,appendChild: function (child)
{
,appendChild: function(child) {
if (child.nodeType === Node.TEXT_NODE)
this.query = child.textContent;
}
,loadXml: function (builder, node)
{
this.parent (builder, node);
,loadXml: function(builder, node) {
Vn.Object.prototype.loadXml.call(this, builder, node);
var query = node.firstChild.nodeValue;
@ -102,21 +80,18 @@ module.exports = new Class
this.query = query;
}
,execute: function ()
{
this._conn.execStmt (this._stmt,
this.onQueryDone.bind (this), this._batch);
,execute: function() {
this._conn.execStmt(this._stmt,
this.onQueryDone.bind(this), this._lot);
}
,onQueryDone: function (resultSet)
{
this.signalEmit ('ready', resultSet);
,onQueryDone: function(resultSet) {
this.emit('ready', resultSet);
}
,onChange: function ()
{
if (this.autoLoad && this._conn && this._stmt && this._batch)
this.execute ();
,onChange: function() {
if (this.autoLoad && this._conn && this._stmt && this._lot)
this.execute();
}
});

View File

@ -16,7 +16,7 @@ module.exports = new Class({
,initialize: function() {
window.onerror = this._onWindowError.bind(this);
window.onunload = this._onWindowUnload.bind(this);
Vn.Hash.initialize();
this._hash = new Vn.Hash({window: window});
var conn = new Db.Connection();
this.link({_conn: conn}, {'error': this._onConnError});
@ -28,7 +28,10 @@ module.exports = new Class({
if (this.tryAutoLogin())
return;
var login = this._login = new Login({conn: this._conn});
var login = this._login = new Login({
conn: this._conn,
hash: this._hash
});
login.on('login', this._onLogin, this);
login.show();
}
@ -39,7 +42,10 @@ module.exports = new Class({
if (this._gui)
return;
var gui = this._gui = new Gui({conn: this._conn});
var gui = this._gui = new Gui({
conn: this._conn,
hash: this._hash
});
gui.on('logout', this._onLogout, this);
gui.show();
}
@ -164,6 +170,7 @@ module.exports = new Class({
this._freeGui();
this.deinitAutoLogin();
this._conn.unref();
this._hash.unref();
}
// Auto login functionality
@ -171,15 +178,17 @@ module.exports = new Class({
,_firstLogin: true
,initAutoLogin: function() {
var isGuest = new Vn.HashParam({
var isGuest = new Vn.Param({
lot: this._hash,
type: Boolean,
key: 'guest'
name: 'guest'
});
this.link({_isGuest: isGuest}, {'changed': this._onGuestChange});
var token = new Vn.HashParam({
var token = new Vn.Param({
lot: this._hash,
type: String,
key: 'token'
name: 'token'
});
this.link({_token: token}, {'changed': this._onTokenChange});
}

View File

@ -1,6 +1,7 @@
module.exports = {
check: function(conn, callback) {
check: function(conn, hash, callback) {
this.hash = hash;
conn.execQuery('CALL myBasket_check',
this._onBasketCheck.bind(this, callback));
},
@ -18,7 +19,7 @@ module.exports = {
if (callback)
callback(isOk);
if (!isOk)
Vn.Hash.set({form: 'ecomerce/checkout'});
this.hash.setAll({form: 'ecomerce/checkout'});
}
};

View File

@ -15,25 +15,33 @@ module.exports = new Class({
,loadUi: function() {
if (!this.isOpen)
return;
const conn = this.conn;
const hash = this.hash;
var builder = new Vn.Builder();
const builder = new Vn.Builder();
builder.compileFile('forms/'+ this.formInfo.path +'/ui.xml');
var scope = this.builder = builder.load(null, this);
const scope = this.builder = builder.load(null, this);
this.$ = scope.$;
scope.link(null, {conn: this.conn});
scope.link(null, {conn, hash});
this.node = scope.$.form;
var models = scope.getByTagName('db-model');
const paramsLot = this.$.params;
if (paramsLot) {
paramsLot.source = hash;
this.params = paramsLot;
}
for (var i = 0; i < models.length; i++)
models[i].conn = this.conn;
function setConnection(tagName) {
const objects = scope.getByTagName(tagName);
for (let i = 0; i < objects.length; i++)
objects[i].conn = conn;
}
var queries = scope.getByTagName('db-query');
for (var i = 0; i < queries.length; i++)
queries[i].conn = this.conn;
const tags = ['db-model', 'db-query', 'db-lot'];
for (let i = 0; i < tags.length; i++)
setConnection(tags[i]);
if (this.node) {
this.gui.setForm(this.node);
@ -95,7 +103,7 @@ module.exports = new Class({
,_destroy: function() {
this.close();
this.parent();
Vn.Object.prototype._destroy.call(this);
}
});

View File

@ -5,7 +5,7 @@ var Tpl = require('./gui.xml').default;
require('./gui.scss');
module.exports = new Class({
Extends: Htk.Component,
Extends: Vn.Component,
Properties: {
conn: {
type: Db.Connection
@ -30,7 +30,7 @@ module.exports = new Class({
,_navbarVisible: true
,initialize: function(props) {
this.builderInitString(Tpl);
this.loadTemplateFromString(Tpl);
this.loadingCount = 0;
this.$.background.onclick = function() {};
@ -39,7 +39,7 @@ module.exports = new Class({
event.stopPropagation();
});
this.parent(props);
Vn.Component.prototype.initialize.call(this, props);
var sql = 'SELECT id, name, nickname FROM account.myUser;'
+'SELECT defaultForm FROM config;'
@ -64,8 +64,10 @@ module.exports = new Class({
window.addEventListener('scroll', this._onScrollHandler );
}
this.hash = Vn.Hash;
this.formParam = new Vn.HashParam({key: 'form'});
this.formParam = new Vn.Param({
lot: this.hash,
name: 'form',
});
this.formParam.on('changed', this._onFormChange, this);
if (!localStorage.getItem('hederaCookies')) {
@ -101,7 +103,7 @@ module.exports = new Class({
}
,_onConnClose: function() {
this.signalEmit('logout');
this.emit('logout');
}
,_onConnLoadChange: function(conn, isLoading) {
@ -206,7 +208,7 @@ module.exports = new Class({
var a = this.createElement('a');
if (row.path) {
a.href = Vn.Hash.make({form: row.path});
a.href = this.hash.make({form: row.path});
this.menuOptions[row.path] = a;
}
@ -445,14 +447,14 @@ module.exports = new Class({
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Reports
,openReport: function(reportName, batch) {
,openReport: function(reportName, lot) {
this.loaderPush();
var module = new Module('reports', reportName);
module.addCallback(this._onReportLoad.bind(this, batch));
module.addCallback(this._onReportLoad.bind(this, lot));
}
,_onReportLoad: function(batch, module) {
,_onReportLoad: function(lot, module) {
this.loaderPop();
if (module.error) {
@ -461,7 +463,7 @@ module.exports = new Class({
}
var report = new module.klass(module, this);
report.open(batch);
report.open(lot);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant
@ -510,7 +512,6 @@ module.exports = new Class({
,_destroy: function() {
this.hide();
this.parent();
Vn.Component.prototype.initialize.call(this);
}
});

View File

@ -1,7 +1,5 @@
require('htk/htk');
require('./responsive.scss');
require('./style.scss');
Hedera = module.exports = {
Login : require('./login')

View File

@ -61,4 +61,4 @@ Training: Formació
Agencies: Agències
Configuration: Configuració
Account: Compte
Addresses: Direccions
Addresses: Adreces

View File

@ -3,7 +3,7 @@ require('./login.scss');
var Tpl = require('./login.xml').default;
module.exports = new Class({
Extends: Htk.Component,
Extends: Vn.Component,
Properties:
{
conn:
@ -19,8 +19,8 @@ module.exports = new Class({
}
,initialize: function(props) {
this.parent(props);
this.builderInitString(Tpl);
Vn.Component.prototype.initialize.call(this, props);
this.loadTemplateFromString(Tpl);
//this.$.socialBar.conn = this._conn;
@ -69,7 +69,7 @@ module.exports = new Class({
if (user)
localStorage.setItem('hederaLastUser', user);
this.signalEmit('login');
this.emit('login');
} else {
this._focusUserInput();
throw error;

View File

@ -1,6 +1,5 @@
module.exports = new Class
({
module.exports = new Class({
basePath: null
,path: null
,moduleName: null
@ -11,84 +10,74 @@ module.exports = new Class
,error: false
,ready: false
,initialize: function (basePath, path)
{
,initialize: function(basePath, path) {
var absPath = basePath +'/'+ path;
var aux = path.split ('/');
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));
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.path = path;
this.moduleName = moduleName;
}
,addCallback: function (callback)
{
,addCallback: function(callback) {
if (!this.ready)
this.callbacks.push (callback);
this.callbacks.push(callback);
else
callback (this);
callback(this);
}
,onLocaleReady: function (success)
{
,onLocaleReady: function() {
this.localeReady = true;
this.onReady ();
this.onReady();
}
,onJsReady: function (success)
{
,onJsReady: function(success) {
this.jsReady = true;
this.error = !success;
this.onReady ();
this.onReady();
}
,onUiReady: function (success)
{
,onUiReady: function(success) {
this.uiReady = true;
this.error = !success;
this.onReady ();
this.onReady();
}
,onReady: function ()
{
,onReady: function() {
if (!(this.localeReady && this.jsReady && this.uiReady))
return;
this.ready = true;
var klassName = this.toCamelCase (this.moduleName);
var klassName = this.toCamelCase(this.moduleName);
try {
this.klass = Hedera[klassName];
}
catch (e)
{
} catch (e) {
this.error = true;
console.error (e);
console.error(e);
}
var callbacks = this.callbacks;
this.callbacks = null;
for (var i = 0; i < callbacks.length; i++)
callbacks[i] (this);
callbacks[i](this);
}
,toCamelCase: function (dashedName)
{
var camelCase = dashedName.charAt (0).toUpperCase ();
camelCase += dashedName.substr (1).replace (/\w\-\w/g, function (token)
{
return token.charAt (0) + token.charAt (2).toUpperCase ();
,toCamelCase: function(dashedName) {
var camelCase = dashedName.charAt(0).toUpperCase();
camelCase += dashedName.substr(1).replace(/\w-\w/g, function(token) {
return token.charAt(0) + token.charAt(2).toUpperCase();
});
return camelCase;
}

View File

@ -6,11 +6,11 @@ module.exports = new Class({
this.info = moduleInfo;
this.gui = gui;
this.conn = gui.conn;
this.parent(null);
Vn.Object.prototype.initialize.call(this);
}
,open: function(batch) {
this.batch = batch;
,open: function(lot) {
this.lot = lot;
this.createWindow();
}
@ -70,7 +70,7 @@ module.exports = new Class({
var scope = this.scope = builder.load(this.doc, this);
scope.link(null, {
batch: this.batch,
lot: this.lot,
conn: this.conn
});
this.$ = scope.$;

View File

@ -1,33 +1,26 @@
require('./social-bar.scss');
module.exports = new Class
({
Extends: Htk.Widget
module.exports = new Class({
Extends: Vn.Component
,Tag: 'htk-social-bar'
,Properties:
{
conn:
{
,Properties: {
conn: {
type: Db.Connection
,set: function (x)
{
,set: function(x) {
this._conn = x;
this._refresh ();
this._refresh();
}
,get: function ()
{
,get: function() {
return this._conn;
}
},
priority:
{
priority: {
type: Number
,set: function (x)
{
,set: function(x) {
this._priority = x;
this._refresh ();
this._refresh();
}
,get: function ()
{
,get: function() {
return this._priority;
}
}
@ -35,42 +28,37 @@ module.exports = new Class
,_priority: 0
,initialize: function ()
{
var node = this.createRoot ('div');
,initialize: function() {
var node = this.createRoot('div');
node.className = 'htk-social-bar';
}
,_refresh: function ()
{
,_refresh: function() {
if (!this._conn || this._priority === null)
return;
var batch = new Sql.Batch ();
batch.addValue ('priority', this._priority);
const params = {priority: this._priority};
var query = 'SELECT title, link, icon FROM social '
+'WHERE priority >= #priority ORDER BY priority';
this._conn.execQuery (query, this._onQueryDone.bind (this), batch);
this._conn.execQuery(query, this._onQueryDone.bind(this), params);
}
,_onQueryDone: function (resultSet)
{
Vn.Node.removeChilds (this._node);
var res = resultSet.fetchResult ();
,_onQueryDone: function(resultSet) {
Vn.Node.removeChilds(this._node);
var res = resultSet.fetchResult();
while (res.next ())
{
var a = this.createElement ('a');
a.href = res.get ('link');
while (res.next()) {
var a = this.createElement('a');
a.href = res.get('link');
a.target = '_blank';
this._node.appendChild (a);
this._node.appendChild(a);
var img = this.createElement ('img');
img.src = 'image/social/'+ res.get ('icon');
img.alt = res.get ('title');
img.title = res.get ('title');
a.appendChild (img);
var img = this.createElement('img');
img.src = 'image/social/'+ res.get('icon');
img.alt = res.get('title');
img.title = res.get('title');
a.appendChild(img);
}
}
});

13
js/hedera/social-bar.scss Normal file
View File

@ -0,0 +1,13 @@
.htk-social-bar {
text-align: center;
a {
display: inline-block;
margin: 0 .1em;
}
img {
height: 1.8em;
width: 1.8em;
}
}

View File

@ -6,16 +6,16 @@ module.exports = new Class({
,tpvStatus: null
,check: function(callback) {
this.tpvOrder = Vn.Hash.$.tpvOrder;
this.tpvStatus = Vn.Hash.$.tpvStatus;
this.tpvOrder = this.hash.$.tpvOrder;
this.tpvStatus = this.hash.$.tpvStatus;
if (this.tpvStatus) {
var batch = new Sql.Batch();
batch.addValue('transaction', this.tpvOrder);
batch.addValue('status', this.tpvStatus);
const params = {
transaction: this.tpvOrder,
status: this.tpvStatus
};
var query = 'CALL myTpvTransaction_end(#transaction, #status)';
this.conn.execQuery(query, null, batch);
this.conn.execQuery(query, null, params);
}
if (callback)
@ -66,15 +66,14 @@ module.exports = new Class({
}
,retryPay: function() {
var batch = new Sql.Batch();
batch.addValue('transaction', parseInt(this.tpvOrder));
const params = {transaction: parseInt(this.tpvOrder)};
var query = 'SELECT t.amount, m.companyFk '
+'FROM myTpvTransaction t '
+'JOIN tpvMerchant m ON m.id = t.merchantFk '
+'WHERE t.id = #transaction';
this.conn.execQuery(query,
this._onRetryPayDone.bind(this), batch);
this._onRetryPayDone.bind(this), params);
}
,_onRetryPayDone: function(resultSet) {

View File

@ -1,9 +1,9 @@
var Widget = require('./widget');
var Assistant = require('./assistant');
require('./style.scss');
var Component = require('vn/component');
var Assistant = require('../assistant');
module.exports = new Class({
Extends: Widget,
Extends: Component,
Tag: 'htk-assistant-bar',
Properties: {
assistant: {

View File

@ -0,0 +1,66 @@
.htk-assistant-bar {
position: relative;
padding: .8em;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
width: 100%;
& > button {
border-radius: 50%;
padding: .5em;
margin: 0;
text-align: center;
& > img {
display: block;
width: 1.8em;
padding: .5em;
}
}
& > .end {
display: none;
color: #8cc63f;
& > .icon {
font-size: 1.6rem;
}
}
& > .steps {
display: flex;
align-items: center;
& > div {
background-color: #AAA;
width: .5em;
height: .5em;
cursor: pointer;
border-radius: 50%;
margin: .5em;
transition-property: width, height;
transition-duration: 100ms;
transition-timing-function: ease-in-out;
&.selected {
background-color: #666;
width: 1em;
height: 1em;
}
&:hover {
opacity: .7;
}
}
& > img {
width: 1.3em;
margin: 0 .2em;
cursor: pointer;
&:hover {
opacity: .7;
}
}
}
}

View File

@ -1,13 +1,13 @@
var Widget = require('./widget');
var Step = require('./step');
var Toast = require('./toast');
require('./style.scss');
var Component = require('vn/component');
var Step = require('../step');
var Toast = require('../toast');
/**
* A simple assistant with steps.
*/
module.exports = new Class({
Extends: Widget,
Extends: Component,
Tag: 'htk-assistant',
Properties: {
/**
@ -42,7 +42,7 @@ module.exports = new Class({
set: function(x) {
this._stepsIndex = x;
this.setStep(this._stepIndex);
this.signalEmit('steps-change');
this.emit('steps-change');
},
get: function() {
return this._stepsIndex;
@ -83,7 +83,7 @@ module.exports = new Class({
initialize: function(props) {
var node = this.createRoot('div');
node.className = 'htk-assistant';
this.parent(props);
Component.prototype.initialize.call(this, props);
},
appendChild: function(step) {
@ -132,7 +132,7 @@ module.exports = new Class({
this._stepName = stepName;
this.currentStep = step;
step.show();
this.signalEmit('step-change', stepIndex);
this.emit('step-change', stepIndex);
if (this.stepFunc)
this.stepFunc(step);

View File

@ -0,0 +1,14 @@
.htk-assistant > div {
display: none;
& > h2 {
text-align: center;
font-weight: normal;
font-size: 1.5rem;
margin: 0;
padding: 0;
margin-bottom: 1em;
font-weight: bold;
}
}

View File

@ -1,5 +1,5 @@
var Button = require('./button');
var Button = require('../button');
module.exports = new Class({
Extends: Button

View File

@ -1,3 +1,4 @@
require('./style.scss');
module.exports = new Class({
Extends: Htk.Field

10
js/htk/button/style.scss Normal file
View File

@ -0,0 +1,10 @@
.htk-button {
display: flex;
align-items: center;
gap: 8px;
& > .htk-icon {
display: block;
}
}

View File

@ -1,16 +1,15 @@
require('./style.scss');
module.exports = new Class({
Extends: Htk.Field
,Tag: 'htk-calendar'
,Properties:
{
restrictFunc:
{
,Properties: {
restrictFunc: {
type: Function
,set: function(x) {
this._restrictFunc = x;
}
,get: function(x) {
,get: function() {
return this._restrictFunc;
}
}

View File

@ -0,0 +1,94 @@
@import "../style/variables";
@import "../style/classes";
.htk-calendar {
@extend %box;
width: 20em;
table {
border-collapse: collapse;
}
thead tr,
tfoot tr {
font-weight: normal;
vertical-align: middle;
text-align: center;
height: 3em;
}
thead > tr {
&.weekdays > th {
font-weight: normal;
color: #999;
text-transform: lowercase;
}
& > th {
&.previous, &.next {
font-size: .8rem;
button {
border-radius: 50%;
padding: 10px;
display: block;
margin: 0 auto;
& > .htk-icon {
font-size: 1rem;
}
}
}
&.month-year {
font-size: 1.2rem;
text-transform: lowercase;
}
}
}
tfoot tr {
border-top: none;
}
th.button {
display: table-cell;
}
th.button:hover {
cursor: pointer;
background-color: rgba(1, 1, 1, 0.2);
}
col {
width: 14.2%;
}
tr {
height: 2em;
}
tbody td {
text-align: right;
}
tbody td > div {
height: 2em;
width: 2em;
line-height: 2em;
text-align: center;
border-radius: 2em;
padding: 0.3em;
margin: 0 auto;
color: #555;
}
div {
&.disabled {
color: #bbb;
}
&.today {
font-weight: bold;
color: black;
}
&.selected {
color: white;
background-color: $color-primary;
}
&.enabled {
@extend %clickable;
&:hover {
background-color: rgba(140, 198, 63, 0.8);
}
}
}
}

26
js/htk/check/index.js Normal file
View File

@ -0,0 +1,26 @@
module.exports = new Class({
Extends: Htk.Field
,Tag: 'htk-check'
,render: function() {
var node = this.createRoot('input');
node.type = 'checkbox';
node.addEventListener('change', this.changed.bind(this));
}
,changed: function() {
this.valueChanged(this.node.checked);
}
,putValue: function(value) {
if (value)
this.node.checked = true;
else
this.node.checked = false;
}
,setEditable: function(editable) {
this.node.disabled = !editable;
}
});

View File

@ -1,34 +0,0 @@
module.exports = new Class
({
Extends: Htk.Column
,Tag: 'htk-column-check'
,initialize: function (props)
{
this._cssClass = 'cell-check';
this.parent (props);
}
,render: function (tr)
{
var checkButton = this.createElement ('input');
checkButton.type = 'checkbox';
checkButton.checked = this.value;
if (this.editable)
checkButton.addEventListener ('changed',
this.inputChanged.bind (this, tr, node));
else
checkButton.disabled = true;
var td = this.parent (tr);
td.appendChild (checkButton);
return td;
}
,inputChanged: function (tr, node)
{
this.changed (tr, node.value);
}
});

View File

@ -1,5 +1,5 @@
var NodeBuilder = require('../vn/node-builder');
var NodeBuilder = require('../../vn/node-builder');
/**
* Represents a grid column. This is an abstract class and should not be
@ -8,8 +8,7 @@ var NodeBuilder = require('../vn/node-builder');
module.exports = new Class({
Extends: NodeBuilder
,Tag: 'htk-column'
,Properties:
{
,Properties: {
value: {
type: String
,value: null
@ -57,7 +56,7 @@ module.exports = new Class({
* Initializes the column.
*/
,initialize: function(props) {
this.parent(props);
NodeBuilder.prototype.initialize.call(this, props);
this.td = this.createElement('td');
}
@ -90,7 +89,7 @@ module.exports = new Class({
}
,changed: function(tr, newValue) {
this.signalEmit('changed', tr.rowIndex - 1, newValue);
this.emit('changed', tr.rowIndex - 1, newValue);
}
});

View File

@ -1,39 +0,0 @@
module.exports = new Class
({
Extends: Htk.Column
,Tag: 'htk-column-radio'
,Properties:
{
param:
{
type: Vn.Param
,set: function (x)
{
this.radioGroup.master = x;
}
}
}
,initialize: function (props)
{
this._cssClass = 'cell-radio';
this.radioGroup = new Htk.RadioGroup (this.doc);
this.parent (props);
}
,render: function (tr)
{
var td = this.parent (tr);
var radio = this.radioGroup.createButton (this.value);
td.appendChild (radio);
return td;
}
,clear: function ()
{
this.radioGroup.clear ();
}
});

View File

@ -1,3 +1,4 @@
require('./style.scss');
module.exports = new Class({
Extends: Htk.Column,
@ -36,11 +37,11 @@ module.exports = new Class({
initialize: function(props) {
this._cssClass = 'cell-button';
this.parent(props);
Htk.Column.prototype.initialize.call(this, props);
},
render: function(tr) {
const td = this.parent(tr);
const td = Htk.Column.prototype.render.call(this, tr);
let button;
@ -69,6 +70,6 @@ module.exports = new Class({
},
buttonClicked: function(value, tr, button) {
this.signalEmit('clicked', value, tr.rowIndex - 1, button);
this.emit('clicked', value, tr.rowIndex - 1, button);
}
});

View File

@ -0,0 +1,34 @@
@import "../../style/classes";
td.cell-button {
max-width: 20px;
text-align: center;
& > button,
& > a {
@extend %clickable;
display: block;
height: 44px;
width: 44px;
margin: 0 auto;
border-radius: 50%;
padding: 10px;
border: none;
background-color: transparent;
box-sizing: border-box;
& > .htk-icon {
display: block;
}
&:hover {
background-color: rgba(1, 1, 1, 0.1);
}
}
img {
height: 1.5em;
width: 1.5em;
display: block;
margin: auto;
padding: 0;
}
}

View File

@ -0,0 +1,31 @@
require('./style.scss');
module.exports = new Class({
Extends: Htk.Column
,Tag: 'htk-column-check'
,initialize: function(props) {
this._cssClass = 'cell-check';
Htk.Column.prototype.initialize.call(this, props);
}
,render: function(tr) {
var checkButton = this.createElement('input');
checkButton.type = 'checkbox';
checkButton.checked = this.value;
if (this.editable)
checkButton.addEventListener('changed',
this.inputChanged.bind(this, tr, node));
else
checkButton.disabled = true;
var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(checkButton);
return td;
}
,inputChanged: function(tr, node) {
this.changed(tr, node.value);
}
});

View File

@ -0,0 +1,5 @@
th.cell-check,
th.cell-radio {
text-align: center;
}

View File

@ -24,13 +24,13 @@ module.exports = new Class
,initialize: function(props) {
this._cssClass = 'cell-date';
this.parent(props);
Htk.Column.prototype.initialize.call(this, props);
}
,render: function(tr) {
var text = Vn.Date.strftime(this.value, this._format);
var td = this.parent(tr);
var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(this.createTextNode(text));
return td;

View File

@ -1,46 +1,41 @@
require('./style.scss');
module.exports = new Class
({
module.exports = new Class({
Extends: Htk.Column
,Tag: 'htk-column-image'
,Properties:
{
,Properties: {
/**
* The directory where the images are allocated.
*/
directory:
{
directory:{
type: String
,value: null
},
/**
* The subdirectory where the images are allocated.
*/
subdir:
{
subdir:{
type: String
,value: null
},
/**
* Subdirectory where full images are allocated.
*/
fullDir:
{
fullDir:{
type: String
,value: null
},
/**
* The REST connection used to upload the image.
*/
conn:
{
conn:{
type: Vn.JsonConnection
}
}
,initialize: function(props) {
this._cssClass = 'cell-image';
this.parent(props);
Htk.Column.prototype.initialize.call(this, props);
}
,render: function(tr) {
@ -53,7 +48,7 @@ module.exports = new Class
,doc: this.doc
});
var td = this.parent(tr);
var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(image.node);
return td;
}

View File

@ -0,0 +1,11 @@
td.cell-image {
text-align: center;
.htk-image {
max-width: 2.5em;
max-height: 2.5em;
display: block;
margin: auto;
}
}

View File

@ -1,23 +1,19 @@
module.exports = new Class
({
module.exports = new Class({
Extends: Htk.Column
,Tag: 'htk-column-link'
,Properties:
{
,Properties: {
/**
* The link url.
*/
href:
{
href:{
type: String
,value: null
},
/**
* the target where the link is opened.
*/
target:
{
target:{
type: String
,value: null
}
@ -31,7 +27,7 @@ module.exports = new Class
if (this.target)
link.target = this.target;
var td = this.parent(tr);
var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(link);
return td;
}

View File

@ -0,0 +1,32 @@
module.exports = new Class({
Extends: Htk.Column
,Tag: 'htk-column-radio'
,Properties: {
param:{
type: Vn.Param
,set: function(x) {
this.radioGroup.master = x;
}
}
}
,initialize: function(props) {
this._cssClass = 'cell-radio';
this.radioGroup = new Htk.RadioGroup(this.doc);
Htk.Column.prototype.initialize.call(this, props);
}
,render: function(tr) {
var td = Htk.Column.prototype.render.call(this, tr);
var radio = this.radioGroup.createButton(this.value);
td.appendChild(radio);
return td;
}
,clear: function() {
this.radioGroup.clear();
}
});

View File

@ -1,15 +1,13 @@
require('./style.scss');
module.exports = new Class
({
module.exports = new Class({
Extends: Htk.Column
,Tag: 'htk-column-spin'
,Properties:
{
,Properties: {
/**
* The text to append to the number.
*/
unit:
{
unit:{
type: String
,value: null
},
@ -24,17 +22,17 @@ module.exports = new Class
,initialize: function(props) {
this._cssClass = 'cell-spin';
this.parent(props);
Htk.Column.prototype.initialize.call(this, props);
}
,renderHeader: function() {
var th = this.parent();
var th = Htk.Column.prototype.renderHeader.call(this, );
th.className = 'cell-spin';
return th;
}
,render: function(tr) {
var td = this.parent(tr);
var td = Htk.Column.prototype.render.call(this, tr);
var valueString = null;

View File

@ -0,0 +1,8 @@
th.cell-spin {
text-align: right;
}
td.cell-spin {
width: 2.5em;
text-align: right;
}

View File

@ -1,15 +1,12 @@
module.exports = new Class
({
module.exports = new Class({
Extends: Htk.Column
,Tag: 'htk-column-text'
,Properties:
{
,Properties: {
/**
* Format that applies to the value.
*/
format:
{
format:{
type: String
,set: function(x) {
this._format = _(x);
@ -24,7 +21,7 @@ module.exports = new Class
,initialize: function(props) {
this._cssClass = 'cell-text';
this.parent(props);
Htk.Column.prototype.initialize.call(this, props);
}
,render: function(tr) {
@ -42,7 +39,7 @@ module.exports = new Class
node = this.createTextNode(
Vn.Value.format(this.value, this._format));
var td = this.parent(tr);
var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(node);
return td;
}

View File

@ -1,36 +0,0 @@
const Widget = require('./widget');
module.exports = new Class({
Extends: Widget
,scope: null
,builderInit: function(path) {
const builder = new Vn.Builder();
builder.compileFile(path);
this.builderResultInit(builder);
}
,builderInitString: function(xmlString) {
const builder = new Vn.Builder();
builder.compileString(xmlString);
this.builderResultInit(builder);
}
,builderResultInit: function(builder) {
const scope = this.scope = builder.load(this.doc, this);
scope.link();
this.$ = scope.$;
this._node = scope.$.main;
}
,_destroy: function() {
if (this.scope)
this.scope.unref();
this.parent();
}
});

View File

@ -1,8 +1,7 @@
require('./style.scss');
var Calendar = require('../calendar');
var Calendar = require('./calendar');
module.exports = new Class
({
module.exports = new Class({
Extends: Htk.Field
,Tag: 'htk-date-chooser'

View File

@ -0,0 +1,17 @@
.htk-date-chooser {
display: flex;
align-items: center;
font-weight: normal;
& > span {
flex: 1;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
& > .htk-icon {
flex: none;
color: #666;
}
}

View File

@ -1,5 +1,5 @@
var Popup = require('./popup');
require('./style.scss');
var Popup = require('../popup');
/**
* Class to show message dialogs with buttons.
@ -97,7 +97,7 @@ Dialog.implement({
,_buttons: Button.ACCEPT
,open: function() {
this.parent();
Popup.prototype.open.call(this);
// Dialog body
@ -146,8 +146,8 @@ Dialog.implement({
,hide(response) {
if (!this._isOpen) return;
this.parent();
this.signalEmit('response', response);
Popup.prototype.hide.call(this);
this.emit('response', response);
}
,createButton: function(label, response) {

25
js/htk/dialog/style.scss Normal file
View File

@ -0,0 +1,25 @@
.htk-dialog {
padding: 1.5em;
max-width: 20em;
font-weight: normal;
color: #555;
p {
margin: 0;
}
img {
float: left;
height: 3em;
margin-top: 0;
margin-right: 1em;
}
p {
padding: 0;
}
.button-bar > button {
float: right;
margin-left: 1em;
margin-top: .5em;
}
}

View File

@ -1,10 +1,8 @@
module.exports = new Class
({
module.exports = new Class({
Extends: Htk.Field
,Tag: 'htk-entry'
,Properties:
{
,Properties: {
/**
* Displayed text when there is no content.
*/
@ -52,7 +50,7 @@ module.exports = new Class
node.addEventListener('change', this._onChange.bind(this));
}
,_onChange: function(event) {
,_onChange: function() {
var newValue;
if (this.node.value == '')

View File

@ -1,31 +0,0 @@
module.exports = new Class
({
Extends: Htk.Field
,Tag: 'htk-check'
,render: function ()
{
var node = this.createRoot ('input');
node.type = 'checkbox';
node.addEventListener ('change', this.changed.bind (this));
}
,changed: function ()
{
this.valueChanged (this.node.checked);
}
,putValue: function (value)
{
if (value)
this.node.checked = true;
else
this.node.checked = false;
}
,setEditable: function (editable)
{
this.node.disabled = !editable;
}
});

View File

@ -1,12 +1,12 @@
var Widget = require('./widget');
var Component = require('vn/component');
module.exports = new Class({
Extends: Widget
Extends: Component
,Implements: Vn.ParamIface
,Tag: 'htk-field'
,Child: 'param'
,Properties:
{
,Properties: {
value: {
type: String
,set: function(x) {
@ -18,21 +18,48 @@ module.exports = new Class({
this.valueChanged(x);
this.putValue(x);
this._notifyChanges();
}
,get: function(x) {
,get: function() {
return this._value;
}
},
param: {
type: Vn.Param
type: Vn.ParamIface
,set: function(x) {
this.link({_param: x}, {'changed': this.onParamChange});
this.onParamChange();
this._setParam(x);
}
,get: function() {
return this._param;
}
},
lot: {
type: Vn.LotIface
,set: function(x) {
this._setLot(x);
}
,get: function() {
return this._lot;
}
},
name: {
type: String
,set: function(x) {
this._setName(x);
}
,get: function() {
return this._name;
}
},
oneWay: {
type: Boolean
,set: function(x) {
this._oneWay = x;
}
,get: function() {
return this._oneWay;
}
},
editable: {
type: Boolean
,set: function(x) {
@ -48,21 +75,19 @@ module.exports = new Class({
form: {
type: Db.Iterator
,set: function(x) {
this._form = x;
this.bindToForm();
this.lot = x;
}
,get: function() {
return this._form;
return this._lot;
}
},
column: {
type: String
,set: function(x) {
this._paramName = x;
this.bindToForm();
this.name = x;
}
,get: function() {
return this._paramName;
return this._name;
}
},
conditionalFunc: {
@ -71,27 +96,24 @@ module.exports = new Class({
}
}
,_value: undefined
,_param: null
,_editable: true
,_blockParamChange: false
,_blockValueChange: false
,_lockField: false
,onParamChange: function() {
if (!this._blockValueChange) {
this._blockParamChange = true;
this.value = this._param.value;
this._blockParamChange = false;
}
}
,bindToForm: function() {
if (this._form && this._paramName)
this.param = new Db.Param
({
form: this._form
,column: this._paramName
});
,_setValue: function(newValue) {
if (!this._putValue(newValue))
return;
if (!this._lockField)
this.putValue(newValue);
if (this.conditionalFunc)
this.conditionalFunc(this, newValue);
const node = this.node;
if (node && node.nodeType === Node.ELEMENT_NODE)
node.classList.toggle('filled', newValue !== undefined);
this._notifyChanges();
}
/**
@ -100,7 +122,7 @@ module.exports = new Class({
*
* @param {Boolean} editable Whether the user is allowed to edit the entry
*/
,setEditable: function(editable) {}
,setEditable: function() {}
/**
* Virtual method that must be implemented by class childs to put the value
@ -108,7 +130,7 @@ module.exports = new Class({
*
* @param {Object} value The new value for the entry
*/
,putValue: function(value) {}
,putValue: function() {}
/**
* Protected method that should be called from class childs when the value
@ -117,18 +139,9 @@ module.exports = new Class({
* @param {Object} value The new entry value
*/
,valueChanged: function(value) {
this._value = value;
if (this.conditionalFunc)
this.conditionalFunc(this, value);
if (this._param && !this._blockParamChange) {
this._blockValueChange = true;
this._param.value = value;
this._blockValueChange = false;
}
this.signalEmit('changed');
this._lockField = true;
this._setValue(value);
this._lockField = false;
}
});

View File

@ -1,46 +0,0 @@
module.exports = new Class
({
Extends: Htk.Field
,Tag: 'htk-spin'
,render: function ()
{
var input = this.createRoot ('input');
//setInputTypeNumber (input);
this.node.type = 'number';
input.addEventListener ('change', this._onChange.bind (this));
this.unit = null;
this.digits = 0;
}
,_onChange: function ()
{
var newValue = (this.node.value == '') ? null : parseFloat (this.node.value);
this.node.value = newValue;
this.valueChanged (newValue);
}
,putValue: function (value)
{
var text;
if (value != null)
{
text = (new Number (value)).toFixed (this.digits);
if (this.unit != null)
text += ' ' + this.unit;
}
else
text = '';
this.node.value = text;
}
,setEditable: function (editable)
{
this.node.readOnly = !editable;
}
});

View File

@ -1,58 +0,0 @@
var Entry = require ('./entry');
var ColumnRadio = require ('../column/radio');
module.exports = new Class
({
Extends: Entry
,Tag: 'htk-table'
,render: function ()
{
var tv = new Htk.TreeView ();
this.node.appendChild (tv.node);
var renderer = new ColumnRadio ();
tv.appendColumn (0, renderer, '');
var rbGroup = renderer.rbGroup;
rbGroup.addSignal ('changed', this.changed, this);
this.treeview = tv;
this.rbGroup = rbGroup;
}
,setModel: function (model)
{
this.treeview.setModel (model);
model.addSignal ('status-changed', this.modelRefresh, this);
this.selectValue ();
}
,changed: function (rbGroup)
{
this.realValue = this.rbGroup.getValue ();
this.signalEmit ('changed');
}
,selectValue: function ()
{
this.rbGroup.setValue (this.realValue);
}
,setRealValue: function ()
{
this.selectValue ();
}
,modelRefresh: function (model, status)
{
if (status == Db.Model.Status.READY)
this.selectValue ();
}
,setEditable: function (editable)
{
this.rbGroup.setEditable (editable);
}
});

View File

@ -1,6 +1,6 @@
var Popup = require('./popup');
var Spinner = require('./spinner');
require('./style.scss');
var Popup = require('../popup');
var Spinner = require('../spinner');
module.exports = new Class
({

View File

@ -0,0 +1,12 @@
.htk-full-image {
img {
display: block;
cursor: pointer;
}
.htk-spinner {
background-color: #FFF;
margin: .6em;
display: block;
}
}

View File

@ -1,8 +1,8 @@
var Widget = require('./widget');
require('./style.scss');
var Component = require('vn/component');
module.exports = new Class({
Extends: Widget
Extends: Component
,Tag: 'htk-grid'
,Child: 'model'
,Properties:

63
js/htk/grid/style.scss Normal file
View File

@ -0,0 +1,63 @@
@import "../style/variables";
.htk-grid {
margin: auto;
border-collapse: collapse;
& > thead > tr,
& > tfoot > tr {
background-color: $color-primary;
vertical-align: middle;
height: 3em;
}
th {
color: white;
cursor: pointer;
font-weight: normal;
padding: 0 0.4em;
}
th:hover {
background-color: rgba(1, 1, 1, 0.2);
}
tr {
height: 3.5em;
}
& > tfoot a,
& > thead a {
color: black;
}
tr.pair-row {
background-color: transparent;
}
& > tbody tr {
border-top: 1px solid #DDD;
}
& > tbody tr:first-child {
border-top: none;
}
& > tbody td {
margin: 0;
padding: 0 0.5em;
}
th,
td {
text-align: left;
}
td:first-child,
th:first-child {
padding-left: 1em;
}
td:last-child,
th:last-child {
padding-right: 1em;
}
.message {
padding: 1.5em;
text-align: center;
}
.message > * {
display: inline-block;
vertical-align: middle;
padding-right: .8em;
}
}

View File

@ -3,9 +3,7 @@ require('db/db');
require('./style/index.scss');
Htk = module.exports = {
Widget : require('./widget')
,Component : require('./component')
,Popup : require('./popup')
Popup : require('./popup')
,Dialog : require('./dialog')
,Toast : require('./toast')
,Repeater : require('./repeater')
@ -18,36 +16,37 @@ Htk = module.exports = {
,AssistantBar : require('./assistant-bar')
,Step : require('./step')
,Loader : require('./loader')
,List : require('./list')
,Field : require('./field')
,Column : require('./column')
};
var Fields = {
Text : require('./field/text')
,Html : require('./field/html')
,Entry : require('./field/entry')
,RadioGroup : require('./field/radio-group')
,Radio : require('./field/radio')
,Label : require('./field/label')
,TextArea : require('./field/text-area')
,Spin : require('./field/spin')
,Check : require('./field/check')
,Select : require('./field/select')
,Calendar : require('./field/calendar')
,DateChooser : require('./field/date-chooser')
,Image : require('./field/image')
,Button : require('./field/button')
,BarButton : require('./field/bar-button')
,Table : require('./field/table')
,SearchEntry : require('./field/search-entry')
,ColumnButton : require('./column/button')
,ColumnLink : require('./column/link')
,ColumnDate : require('./column/date')
,ColumnImage : require('./column/image')
,ColumnRadio : require('./column/radio')
,ColumnSpin : require('./column/spin')
,ColumnText : require('./column/text')
,ColumnCheck : require('./column/check')
Text : require('./text')
,Html : require('./html')
,Entry : require('./entry')
,RadioGroup : require('./radio/radio-group')
,Radio : require('./radio')
,Label : require('./label')
,TextArea : require('./text-area')
,Spin : require('./spin')
,Check : require('./check')
,Select : require('./select')
,Calendar : require('./calendar')
,DateChooser : require('./date-chooser')
,Image : require('./image')
,Button : require('./button')
,BarButton : require('./bar-button')
,Table : require('./table')
,SearchEntry : require('./search-entry')
,ColumnButton : require('./columns/button')
,ColumnLink : require('./columns/link')
,ColumnDate : require('./columns/date')
,ColumnImage : require('./columns/image')
,ColumnRadio : require('./columns/radio')
,ColumnSpin : require('./columns/spin')
,ColumnText : require('./columns/text')
,ColumnCheck : require('./columns/check')
};
for (var field in Fields)

View File

@ -1,8 +1,8 @@
var Widget = require('./widget');
var Component = require('vn/component');
module.exports = new Class({
Extends: Widget
Extends: Component
,Tag: 'htk-icon'
,Properties:
{

View File

@ -1,7 +1,7 @@
var Component = require('./component');
var Toast = require('./toast');
var Tpl = require('./image-editor.xml').default;
require('./style.scss');
var Component = require('vn/component');
var Toast = require('../toast');
var Tpl = require('./ui.xml').default;
/**
* A form to handle the image database, it allows to add new images or
@ -19,14 +19,14 @@ module.exports = new Class({
},
initialize: function(props) {
this.builderInitString(Tpl);
this.loadTemplateFromString(Tpl);
var self = this;
this.$.form.onsubmit = function() {
self._onSubmit(); return false;
};
this.parent(props);
Component.prototype.initialize.call(this, props);
},
onNameChange: function() {
@ -35,7 +35,7 @@ module.exports = new Class({
if (!newValue)
newValue = null
this.signalEmit('name-changed', newValue);
this.emit('name-changed', newValue);
},
_onSubmit: function() {
@ -55,7 +55,7 @@ module.exports = new Class({
throw error;
Toast.showMessage(_('ImageAdded'));
this.signalEmit('file-uploaded', this.$.name.value);
this.emit('file-uploaded', this.$.name.value);
},
setData: function(image, directory) {

Some files were not shown because too many files have changed in this diff Show More