Merge pull request '0000-lot' (#9) from 0000-lot into test
gitea/hedera-web/pipeline/head This commit looks good Details

Reviewed-on: #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. * Initial Release.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@ Hedera.Catalog = new Class({
this.isOpen = true; this.isOpen = true;
if (!localStorage.getItem('hederaGuest')) { if (!localStorage.getItem('hederaGuest')) {
Hedera.BasketChecker.check(this.conn, Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this)); this.onBasketCheck.bind(this));
} else { } else {
var query = 'CALL mybasket_configureForGuest'; var query = 'CALL mybasket_configureForGuest';
@ -31,7 +31,7 @@ Hedera.Catalog = new Class({
else else
this.setView(Hedera.Catalog.View.GRID); this.setView(Hedera.Catalog.View.GRID);
this.onRealmChange(); this.onFilterChange();
} }
,deactivate: function() { ,deactivate: function() {
@ -40,77 +40,80 @@ Hedera.Catalog = new Class({
Vn.Node.remove(this.$.rightPanel); 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() { ,onFilterChange: function() {
const $ = this.$; const $ = this.$;
const params = [ const params = $.params.$;
'search',
'realm', this.refreshTitle();
'type', const hasRealm = params.realm != null;
$.filters.style.display = hasRealm ? 'block' : 'none';
$.realmMsg.style.display = hasRealm ? 'none' : 'block';
const tags = [
'color', 'color',
'origin', 'origin',
'category', 'category',
'producer' 'producer'
]; ];
const lot = {};
for (const param of params)
lot[param] = this.$[param].value;
if (lot.search != null || lot.type != null) { const lot = this.getFilter(params, tags);
const filter = new Sql.Operation({ if (lot) {
type: Sql.Operation.Type.AND $.items.lot = lot;
}); $.items.refresh();
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;
} else } else
$.items.batch = null; $.items.clean();
}
,onRealmChange: function() { for (const tag of tags)
const hasRealm = this.$.realm.value != null; $[`${tag}s`].lot = this.getFilter(params, tags, tag);
this.$.filters.style.display = hasRealm ? 'block' : 'none';
this.$.realmMsg.style.display = hasRealm ? 'none' : 'block';
this.onFilterChange();
this.refreshTitle();
}
,onTypeChange: function() {
this.onFilterChange();
this.refreshTitle();
} }
,refreshTitle: function() { ,refreshTitle: function() {
const hash = this.hash.$;
const types = this.$.types; const types = this.$.types;
const realms = this.$.realms; const realms = this.$.realms;
const type = this.$.type.value; const type = hash.type;
const realm = this.$.realm.value; const realm = hash.realm;
let typeName; let typeName;
let realmName; let realmName;
@ -234,14 +237,14 @@ Hedera.Catalog = new Class({
if (this.isGuest()) if (this.isGuest())
return; return;
this.hash.set({form: 'ecomerce/basket'}); this.hash.setAll({form: 'ecomerce/basket'});
} }
,onConfigureClick: function() { ,onConfigureClick: function() {
if (this.isGuest()) if (this.isGuest())
return; return;
this.hash.set({form: 'ecomerce/checkout'}); this.hash.setAll({form: 'ecomerce/checkout'});
} }
,onAddItemClick: function(event, form) { ,onAddItemClick: function(event, form) {
@ -251,7 +254,7 @@ Hedera.Catalog = new Class({
this.onEraseClick(); this.onEraseClick();
this.$.card.row = form.row; this.$.card.row = form.row;
this.$.cardItem.value = form.$.id; this.$.cardLot.assign({item: form.$.id});
this.$.cardPopup.show(event.currentTarget); this.$.cardPopup.show(event.currentTarget);
} }
@ -280,7 +283,6 @@ Hedera.Catalog = new Class({
,onConfirmClick: function() { ,onConfirmClick: function() {
var sql = ''; var sql = '';
var batch = new Sql.Batch();
var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'}); var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'});
var amountSum = 0; var amountSum = 0;
@ -288,10 +290,12 @@ Hedera.Catalog = new Class({
var amount = this.items[warehouse]; var amount = this.items[warehouse];
amountSum += amount; amountSum += amount;
batch.addValue('warehouse', warehouse); const params = {
batch.addValue('item', this.$.cardItem.value); warehouse: warehouse,
batch.addValue('amount', amount); item: this.$.cardLot.$.item,
sql += query.render(batch); amount: amount
}
sql += query.render(params);
} }
if (amountSum > 0) { if (amountSum > 0) {
@ -299,7 +303,7 @@ Hedera.Catalog = new Class({
var itemName = this.$.card.get('item'); var itemName = this.$.card.get('item');
Htk.Toast.showMessage( Htk.Toast.showMessage(
sprintf(_('Added%dOf%s'), amountSum, itemName)); Vn.Value.sprintf(_('Added%dOf%s'), amountSum, itemName));
} }
this.$.cardPopup.hide(); this.$.cardPopup.hide();
@ -313,7 +317,7 @@ Hedera.Catalog = new Class({
,onPopupClose: function() { ,onPopupClose: function() {
this.onEraseClick(); this.onEraseClick();
this.$.card.row = -1; this.$.card.row = -1;
this.$.cardItem.value = undefined; this.$.cardLot.value = undefined;
} }
,onCardLoad: function() { ,onCardLoad: function() {
@ -327,163 +331,3 @@ Hedera.Catalog.extend({
GRID: 1 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; padding: 0;
width: 100%; 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 { .right-panel .filters > button {
display: block;
margin: 0 auto;
margin-top: 1em; margin-top: 1em;
} }
@ -157,7 +123,7 @@
font-size: 1em; font-size: 1em;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
max-height: 2.8em; max-height: 3em;
} }
.item-info > p { .item-info > p {
margin: 0; margin: 0;
@ -247,7 +213,7 @@
flex-direction: column; flex-direction: column;
width: 240px; width: 240px;
height: 405px; height: 410px;
overflow: hidden; overflow: hidden;
} }
.grid-view .item-box:hover { .grid-view .item-box:hover {

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ Hedera.Confirm = new Class({
this.close(); this.close();
this.isOpen = true; this.isOpen = true;
Hedera.BasketChecker.check(this.conn, Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this)); this.onBasketCheck.bind(this));
}, },
@ -139,10 +139,13 @@ Hedera.Confirm = new Class({
else else
var payAmount = this.$.totalAmount.value; 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); tpv.pay(payAmount, this.$.orderForm.$.companyFk);
} else } 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, Extends: Hedera.Form,
activate: function() { 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)); this.tpv.check(this._onTpvCheck.bind(this));
}, },
@ -13,7 +16,7 @@ Hedera.Orders = new Class({
}, },
onBasketClick: function() { onBasketClick: function() {
this.hash.set({form: 'ecomerce/basket'}); this.hash.setAll({form: 'ecomerce/basket'});
}, },
repeaterFunc: function(res, form) { repeaterFunc: function(res, form) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,49 +3,18 @@ Hedera.Shelves = new Class({
Extends: Hedera.Form Extends: Hedera.Form
,activate: function() { ,activate: function() {
this.$.date.value = new Date(); this.$.lot.assign({
this.$.useIds.value = false; date: new Date(),
useIds: false
});
} }
,onConfigChange: function() { ,onConfigChange: function() {
const fields = [ this.$.lot.assignLot(this.$.config);
'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];
} }
,onPreviewClick: function() { ,onPreviewClick: function() {
var fields = [ this.gui.openReport('shelves-report', this.$.lot);
'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);
} }
}); });

View File

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

View File

@ -12,15 +12,13 @@
var Connection = new Class(); var Connection = new Class();
module.exports = Connection; module.exports = Connection;
var Flag = var Flag = {
{
NOT_NULL : 1 NOT_NULL : 1
,PRI_KEY : 2 ,PRI_KEY : 2
,AI : 512 | 2 | 1 ,AI : 512 | 2 | 1
}; };
var Type = var Type = {
{
BOOLEAN : 1 BOOLEAN : 1
,INTEGER : 3 ,INTEGER : 3
,DOUBLE : 4 ,DOUBLE : 4
@ -53,10 +51,10 @@ Connection.implement({
* *
* @param {Sql.Stmt} stmt The statement * @param {Sql.Stmt} stmt The statement
* @param {Function} callback The function to call when operation is done * @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) { ,execStmt: function(stmt, callback, params) {
this.execSql(stmt.render(batch), callback); this.execSql(stmt.render(params), callback);
} }
/** /**
@ -64,10 +62,10 @@ Connection.implement({
* *
* @param {String} query The SQL statement * @param {String} query The SQL statement
* @param {Function} callback The function to call when operation is done * @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) { ,execQuery: function(query, callback, params) {
this.execStmt(new Sql.String({query: query}), callback, batch); 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 = { Db = module.exports = {
Connection : require ('./connection') Connection : require('./connection')
,Result : require ('./result') ,Result : require('./result')
,ResultSet : require ('./result-set') ,ResultSet : require('./result-set')
,Model : require ('./model') ,Model : require('./model')
,Iterator : require ('./iterator') ,Iterator : require('./iterator')
,SimpleIterator : require ('./simple-iterator') ,SimpleIterator : require('./simple-iterator')
,Form : require ('./form') ,Form : require('./form')
,Param : require ('./param') ,Query : require('./query')
,Query : require ('./query') ,Calc : require('./calc')
,Calc : require ('./calc') ,CalcSum : require('./calc-sum')
,CalcSum : require ('./calc-sum') ,Lot : require('./db-lot')
}; };

View File

@ -67,7 +67,7 @@ module.exports = new Class({
$: { $: {
type: Object type: Object
,get: function() { ,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.lastRow = this._row;
this._ready = ready; this._ready = ready;
this.signalEmit('status-changed'); this.emit('status-changed');
if (this._row == -1) if (this._row == -1)
this.row = this.lastRow; this.row = this.lastRow;
if (ready) if (ready)
this.signalEmit('ready'); this.emit('ready');
this.iterChanged(); 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() { ,iterChanged: function() {
this.signalEmit('iter-changed'); this.emit('change');
} }
/** /**
@ -90,6 +90,16 @@ module.exports = new Class({
return this._model.getObject(this._row); 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. * 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: { lot: {
type: Sql.Batch type: Vn.LotIface
,set: function(x) { ,set: function(x) {
this.link({_batch: x}, {'changed': this._autoLoad}); this.link({_lot: x}, {'change': this._onLotChange});
this._autoLoad(); this._onLotChange();
} }
,get: function() { ,get: function() {
return this._batch; return this._lot;
} }
}, },
/** /**
@ -189,7 +189,7 @@ Model.implement({
,_conn: null ,_conn: null
,_resultIndex: 0 ,_resultIndex: 0
,_batch: null ,_lot: null
,_stmt: null ,_stmt: null
,_status: Status.CLEAN ,_status: Status.CLEAN
,data: null ,data: null
@ -197,6 +197,7 @@ Model.implement({
,columns: null ,columns: null
,columnMap: null ,columnMap: null
,_updatable: false ,_updatable: false
,_paramsChanged: true
,_requestedSortIndex: -1 ,_requestedSortIndex: -1
,_requestedSortName: null ,_requestedSortName: null
@ -213,7 +214,7 @@ Model.implement({
,_requestedMainTable: null ,_requestedMainTable: null
,initialize: function(props) { ,initialize: function(props) {
this.parent(props); Vn.Object.prototype.initialize.call(this, props);
this._cleanData(); this._cleanData();
this._setStatus(Status.CLEAN); this._setStatus(Status.CLEAN);
} }
@ -224,7 +225,7 @@ Model.implement({
} }
,loadXml: function(builder, node) { ,loadXml: function(builder, node) {
this.parent(builder, node); Vn.Object.prototype.loadXml.call(this, builder, node);
var query = node.firstChild.nodeValue; var query = node.firstChild.nodeValue;
@ -232,6 +233,58 @@ Model.implement({
this.query = 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() { ,_autoLoad: function() {
if (this.autoLoad) if (this.autoLoad)
this.refresh(); this.refresh();
@ -239,32 +292,33 @@ Model.implement({
this.clean(); 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 the model data reexecuting the query on the database.
*/ */
,refresh: function() { ,refresh: function() {
var ready = false; const params = this._getHolderParams();
if (this._stmt && this._conn) { if (this._isReady(params)) {
var ids = this._stmt.findHolders();
if (ids) {
if (this._batch && this._batch.isReady()) {
ready = true;
for (var i = 0; i < ids.length; i++)
if (!this._batch.get(ids[i])) {
ready = false;
break;
}
}
} else
ready = true;
}
if (ready) {
this._setStatus(Status.LOADING); 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 } else
this.clean(); this.clean();
} }
@ -344,7 +398,7 @@ Model.implement({
this._updatable = this._mainTable !== null && this._requestedUpdatable; this._updatable = this._mainTable !== null && this._requestedUpdatable;
if (oldValue != this._updatable) if (oldValue != this._updatable)
this.signalEmit('updatable-changed'); this.emit('updatable-changed');
} }
,_refreshMainTable: function() { ,_refreshMainTable: function() {
@ -492,7 +546,7 @@ Model.implement({
*/ */
,get: function(rowIndex, columnName) { ,get: function(rowIndex, columnName) {
if (this.checkRowExists(rowIndex)) 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] === undefined)
op.oldValues[columnName] = row[columnName]; op.oldValues[columnName] = row[columnName];
this.signalEmit('row-updated-before', rowIndex); this.emit('row-updated-before', rowIndex);
row[columnName] = value; row[columnName] = value;
this.signalEmit('row-updated', rowIndex, [columnName]); this.emit('row-updated', rowIndex, [columnName]);
if (this.mode == Mode.ON_CHANGE if (this.mode == Mode.ON_CHANGE
&& !(op.type & Operation.INSERT)) && !(op.type & Operation.INSERT))
@ -596,12 +650,12 @@ Model.implement({
op.type |= Operation.DELETE; op.type |= Operation.DELETE;
if (!this._requestedMainTable) { if (!this._requestedMainTable) {
this.signalEmit('row-deleted-before', rowIndex); this.emit('row-deleted-before', rowIndex);
this.data.splice(rowIndex, 1); this.data.splice(rowIndex, 1);
this.signalEmit('row-deleted', rowIndex); this.emit('row-deleted', rowIndex);
this._refreshRowIndexes(rowIndex); this._refreshRowIndexes(rowIndex);
} else { } else {
this.signalEmit('row-updated-before', rowIndex); this.emit('row-updated-before', rowIndex);
if (!op.oldValues) if (!op.oldValues)
op.oldValues = []; op.oldValues = [];
@ -619,7 +673,7 @@ Model.implement({
updatedCols.push(i); updatedCols.push(i);
} }
this.signalEmit('row-updated', rowIndex, updatedCols); this.emit('row-updated', rowIndex, updatedCols);
} }
if (this.mode === Mode.ON_CHANGE) if (this.mode === Mode.ON_CHANGE)
@ -650,7 +704,7 @@ Model.implement({
var op = this._createOperation(rowIndex); var op = this._createOperation(rowIndex);
op.type |= Operation.INSERT; op.type |= Operation.INSERT;
this.signalEmit('row-inserted', rowIndex); this.emit('row-inserted', rowIndex);
return rowIndex; return rowIndex;
} }
@ -662,14 +716,14 @@ Model.implement({
var ops = this._operations; var ops = this._operations;
if (ops.length === 0) { if (ops.length === 0) {
this.signalEmit('operations-done'); this.emit('operations-done');
return; return;
} }
var stmts = new Sql.MultiStmt(); var stmts = new Sql.MultiStmt();
var query = new Sql.String({query: 'START TRANSACTION'}); var query = new Sql.String({query: 'START TRANSACTION'});
stmts.addStmt(query); stmts.push(query);
for (var i = 0; i < ops.length; i++) { for (var i = 0; i < ops.length; i++) {
query = null; query = null;
@ -690,12 +744,12 @@ Model.implement({
for (var tableIndex in op.tables) { for (var tableIndex in op.tables) {
var stmt = this._createDmlQuery(op, parseInt(tableIndex)); var stmt = this._createDmlQuery(op, parseInt(tableIndex));
query.addStmt(stmt); query.push(stmt);
} }
} }
if (query) { if (query) {
stmts.addStmt(query); stmts.push(query);
} else { } else {
console.warn('Db.Model: %s', _('ErrorSavingChanges')); console.warn('Db.Model: %s', _('ErrorSavingChanges'));
return; return;
@ -703,7 +757,7 @@ Model.implement({
} }
var query = new Sql.String({query: 'COMMIT'}); var query = new Sql.String({query: 'COMMIT'});
stmts.addStmt(query); stmts.push(query);
this._conn.execStmt(stmts, this._conn.execStmt(stmts,
this._onOperationsDone.bind(this, ops)); this._onOperationsDone.bind(this, ops));
@ -764,8 +818,8 @@ Model.implement({
dmlQuery.addTarget(target); dmlQuery.addTarget(target);
multiStmt.addStmt(dmlQuery); multiStmt.push(dmlQuery);
multiStmt.addStmt(select); multiStmt.push(select);
return multiStmt; return multiStmt;
} }
@ -795,7 +849,7 @@ Model.implement({
if (op.type & Operation.DELETE) { if (op.type & Operation.DELETE) {
resultSet.fetchResult(); resultSet.fetchResult();
} else if (op.type & (Operation.INSERT | Operation.UPDATE)) { } 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 updatedCols = [];
var cols = this.columns; 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(); resultSet.fetchResult();
// if (isOperation) // if (isOperation)
this.signalEmit('operations-done'); this.emit('operations-done');
} }
/** /**
@ -844,9 +898,9 @@ Model.implement({
if (op.type & Operation.DELETE if (op.type & Operation.DELETE
&& !(op.type & Operation.INSERT)) { && !(op.type & Operation.INSERT)) {
this.data.splice(row.index, 0, row); 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) { } else if (op.type & Operation.UPDATE) {
this.signalEmit('row-updated-before', row.index); this.emit('row-updated-before', row.index);
var updatedCols = []; var updatedCols = [];
var cols = this.columns; var cols = this.columns;
@ -858,7 +912,7 @@ Model.implement({
updatedCols.push(i); 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) { ,_setStatus: function(status) {
this._status = status; this._status = status;
this.signalEmit('status-changed', status); this.emit('status-changed', status);
this.signalEmit('status-changed-after', status); this.emit('status-changed-after', status);
} }
,_createTarget: function(tableIndex) { ,_createTarget: function(tableIndex) {
@ -1088,8 +1142,8 @@ Model.implement({
const column = this.columnMap[pk]; const column = this.columnMap[pk];
const equalOp = new Sql.Operation({type: Sql.Operation.Type.EQUAL}); const equalOp = new Sql.Operation({type: Sql.Operation.Type.EQUAL});
equalOp.exprs.add(new Sql.Field({name: column.orgname})); equalOp.push(new Sql.Field({name: column.orgname}));
where.exprs.add(equalOp); where.push(equalOp);
let pkValue = null; let pkValue = null;
@ -1100,9 +1154,9 @@ Model.implement({
pkValue = op.row[pk]; pkValue = op.row[pk];
if (pkValue) 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) 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 else
return null; 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 Extends: Vn.Object
,Tag: 'db-query' ,Tag: 'db-query'
,Properties: ,Properties: {
{
/** /**
* The connection used to execute the statement. * The connection used to execute the statement.
*/ */
conn: conn: {
{
type: Connection type: Connection
,set: function (x) ,set: function(x) {
{
this._conn = x; this._conn = x;
this.onChange (); this.onChange();
} }
,get: function () ,get: function() {
{
return this._conn; return this._conn;
} }
}, },
/** /**
* The model query. * The model query.
*/ */
query: query: {
{
type: String type: String
,set: function (x) ,set: function(x) {
{ this._stmt = new Sql.String({query: x});
this._stmt = new Sql.String ({query: x}); this.onChange();
this.onChange ();
} }
,get: function () ,get: function() {
{ return this._stmt.render(null);
return this._stmt.render (null);
} }
}, },
/** /**
* The model select statement. * The model select statement.
*/ */
stmt: stmt: {
{
type: Sql.Stmt type: Sql.Stmt
,set: function (x) ,set: function(x) {
{
this._stmt = x; this._stmt = x;
this.onChange (); this.onChange();
} }
,get: function () ,get: function() {
{
return this._stmt; return this._stmt;
} }
}, },
/** /**
* The batch used to execute the statement. * The lot used to execute the statement.
*/ */
batch: lot: {
{ type: Vn.LotIface
type: Sql.Batch ,set: function(x) {
,set: function (x) this.link({_lot: x}, {'change': this.onChange});
{ this.onChange();
this.link ({_batch: x}, {'changed': this.onChange});
this.onChange ();
} }
,get: function () ,get: function() {
{ return this._lot;
return this._batch;
} }
}, },
/** /**
* Wether to execute automatically de query que it's ready. * Wether to execute automatically de query que it's ready.
*/ */
autoLoad: autoLoad: {
{
type: Boolean, type: Boolean,
value: false value: false
} }
} }
,initialize: function (props) ,appendChild: function(child) {
{
this.parent (props);
}
,appendChild: function (child)
{
if (child.nodeType === Node.TEXT_NODE) if (child.nodeType === Node.TEXT_NODE)
this.query = child.textContent; this.query = child.textContent;
} }
,loadXml: function (builder, node) ,loadXml: function(builder, node) {
{ Vn.Object.prototype.loadXml.call(this, builder, node);
this.parent (builder, node);
var query = node.firstChild.nodeValue; var query = node.firstChild.nodeValue;
@ -102,21 +80,18 @@ module.exports = new Class
this.query = query; this.query = query;
} }
,execute: function () ,execute: function() {
{ this._conn.execStmt(this._stmt,
this._conn.execStmt (this._stmt, this.onQueryDone.bind(this), this._lot);
this.onQueryDone.bind (this), this._batch);
} }
,onQueryDone: function (resultSet) ,onQueryDone: function(resultSet) {
{ this.emit('ready', resultSet);
this.signalEmit ('ready', resultSet);
} }
,onChange: function () ,onChange: function() {
{ if (this.autoLoad && this._conn && this._stmt && this._lot)
if (this.autoLoad && this._conn && this._stmt && this._batch) this.execute();
this.execute ();
} }
}); });

View File

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

View File

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

View File

@ -16,24 +16,32 @@ module.exports = new Class({
if (!this.isOpen) if (!this.isOpen)
return; return;
var builder = new Vn.Builder(); const conn = this.conn;
const hash = this.hash;
const builder = new Vn.Builder();
builder.compileFile('forms/'+ this.formInfo.path +'/ui.xml'); 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.$; this.$ = scope.$;
scope.link(null, {conn: this.conn}); scope.link(null, {conn, hash});
this.node = scope.$.form; 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++) function setConnection(tagName) {
models[i].conn = this.conn; const objects = scope.getByTagName(tagName);
for (let i = 0; i < objects.length; i++)
objects[i].conn = conn;
}
var queries = scope.getByTagName('db-query'); const tags = ['db-model', 'db-query', 'db-lot'];
for (let i = 0; i < tags.length; i++)
for (var i = 0; i < queries.length; i++) setConnection(tags[i]);
queries[i].conn = this.conn;
if (this.node) { if (this.node) {
this.gui.setForm(this.node); this.gui.setForm(this.node);
@ -95,7 +103,7 @@ module.exports = new Class({
,_destroy: function() { ,_destroy: function() {
this.close(); 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'); require('./gui.scss');
module.exports = new Class({ module.exports = new Class({
Extends: Htk.Component, Extends: Vn.Component,
Properties: { Properties: {
conn: { conn: {
type: Db.Connection type: Db.Connection
@ -30,7 +30,7 @@ module.exports = new Class({
,_navbarVisible: true ,_navbarVisible: true
,initialize: function(props) { ,initialize: function(props) {
this.builderInitString(Tpl); this.loadTemplateFromString(Tpl);
this.loadingCount = 0; this.loadingCount = 0;
this.$.background.onclick = function() {}; this.$.background.onclick = function() {};
@ -39,7 +39,7 @@ module.exports = new Class({
event.stopPropagation(); event.stopPropagation();
}); });
this.parent(props); Vn.Component.prototype.initialize.call(this, props);
var sql = 'SELECT id, name, nickname FROM account.myUser;' var sql = 'SELECT id, name, nickname FROM account.myUser;'
+'SELECT defaultForm FROM config;' +'SELECT defaultForm FROM config;'
@ -64,8 +64,10 @@ module.exports = new Class({
window.addEventListener('scroll', this._onScrollHandler ); window.addEventListener('scroll', this._onScrollHandler );
} }
this.hash = Vn.Hash; this.formParam = new Vn.Param({
this.formParam = new Vn.HashParam({key: 'form'}); lot: this.hash,
name: 'form',
});
this.formParam.on('changed', this._onFormChange, this); this.formParam.on('changed', this._onFormChange, this);
if (!localStorage.getItem('hederaCookies')) { if (!localStorage.getItem('hederaCookies')) {
@ -101,7 +103,7 @@ module.exports = new Class({
} }
,_onConnClose: function() { ,_onConnClose: function() {
this.signalEmit('logout'); this.emit('logout');
} }
,_onConnLoadChange: function(conn, isLoading) { ,_onConnLoadChange: function(conn, isLoading) {
@ -206,7 +208,7 @@ module.exports = new Class({
var a = this.createElement('a'); var a = this.createElement('a');
if (row.path) { if (row.path) {
a.href = Vn.Hash.make({form: row.path}); a.href = this.hash.make({form: row.path});
this.menuOptions[row.path] = a; this.menuOptions[row.path] = a;
} }
@ -445,14 +447,14 @@ module.exports = new Class({
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Reports //++++++++++++++++++++++++++++++++++++++++++++++++++++++ Reports
,openReport: function(reportName, batch) { ,openReport: function(reportName, lot) {
this.loaderPush(); this.loaderPush();
var module = new Module('reports', reportName); 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(); this.loaderPop();
if (module.error) { if (module.error) {
@ -461,7 +463,7 @@ module.exports = new Class({
} }
var report = new module.klass(module, this); var report = new module.klass(module, this);
report.open(batch); report.open(lot);
} }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant //++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant
@ -510,7 +512,6 @@ module.exports = new Class({
,_destroy: function() { ,_destroy: function() {
this.hide(); this.hide();
this.parent(); Vn.Component.prototype.initialize.call(this);
} }
}); });

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,33 +1,26 @@
require('./social-bar.scss');
module.exports = new Class module.exports = new Class({
({ Extends: Vn.Component
Extends: Htk.Widget
,Tag: 'htk-social-bar' ,Tag: 'htk-social-bar'
,Properties: ,Properties: {
{ conn: {
conn:
{
type: Db.Connection type: Db.Connection
,set: function (x) ,set: function(x) {
{
this._conn = x; this._conn = x;
this._refresh (); this._refresh();
} }
,get: function () ,get: function() {
{
return this._conn; return this._conn;
} }
}, },
priority: priority: {
{
type: Number type: Number
,set: function (x) ,set: function(x) {
{
this._priority = x; this._priority = x;
this._refresh (); this._refresh();
} }
,get: function () ,get: function() {
{
return this._priority; return this._priority;
} }
} }
@ -35,42 +28,37 @@ module.exports = new Class
,_priority: 0 ,_priority: 0
,initialize: function () ,initialize: function() {
{ var node = this.createRoot('div');
var node = this.createRoot ('div');
node.className = 'htk-social-bar'; node.className = 'htk-social-bar';
} }
,_refresh: function () ,_refresh: function() {
{
if (!this._conn || this._priority === null) if (!this._conn || this._priority === null)
return; return;
var batch = new Sql.Batch (); const params = {priority: this._priority};
batch.addValue ('priority', this._priority);
var query = 'SELECT title, link, icon FROM social ' var query = 'SELECT title, link, icon FROM social '
+'WHERE priority >= #priority ORDER BY priority'; +'WHERE priority >= #priority ORDER BY priority';
this._conn.execQuery (query, this._onQueryDone.bind (this), batch); this._conn.execQuery(query, this._onQueryDone.bind(this), params);
} }
,_onQueryDone: function (resultSet) ,_onQueryDone: function(resultSet) {
{ Vn.Node.removeChilds(this._node);
Vn.Node.removeChilds (this._node); var res = resultSet.fetchResult();
var res = resultSet.fetchResult ();
while (res.next ()) while (res.next()) {
{ var a = this.createElement('a');
var a = this.createElement ('a'); a.href = res.get('link');
a.href = res.get ('link');
a.target = '_blank'; a.target = '_blank';
this._node.appendChild (a); this._node.appendChild(a);
var img = this.createElement ('img'); var img = this.createElement('img');
img.src = 'image/social/'+ res.get ('icon'); img.src = 'image/social/'+ res.get('icon');
img.alt = res.get ('title'); img.alt = res.get('title');
img.title = res.get ('title'); img.title = res.get('title');
a.appendChild (img); 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 ,tpvStatus: null
,check: function(callback) { ,check: function(callback) {
this.tpvOrder = Vn.Hash.$.tpvOrder; this.tpvOrder = this.hash.$.tpvOrder;
this.tpvStatus = Vn.Hash.$.tpvStatus; this.tpvStatus = this.hash.$.tpvStatus;
if (this.tpvStatus) { if (this.tpvStatus) {
var batch = new Sql.Batch(); const params = {
batch.addValue('transaction', this.tpvOrder); transaction: this.tpvOrder,
batch.addValue('status', this.tpvStatus); status: this.tpvStatus
};
var query = 'CALL myTpvTransaction_end(#transaction, #status)'; var query = 'CALL myTpvTransaction_end(#transaction, #status)';
this.conn.execQuery(query, null, batch); this.conn.execQuery(query, null, params);
} }
if (callback) if (callback)
@ -66,15 +66,14 @@ module.exports = new Class({
} }
,retryPay: function() { ,retryPay: function() {
var batch = new Sql.Batch(); const params = {transaction: parseInt(this.tpvOrder)};
batch.addValue('transaction', parseInt(this.tpvOrder));
var query = 'SELECT t.amount, m.companyFk ' var query = 'SELECT t.amount, m.companyFk '
+'FROM myTpvTransaction t ' +'FROM myTpvTransaction t '
+'JOIN tpvMerchant m ON m.id = t.merchantFk ' +'JOIN tpvMerchant m ON m.id = t.merchantFk '
+'WHERE t.id = #transaction'; +'WHERE t.id = #transaction';
this.conn.execQuery(query, this.conn.execQuery(query,
this._onRetryPayDone.bind(this), batch); this._onRetryPayDone.bind(this), params);
} }
,_onRetryPayDone: function(resultSet) { ,_onRetryPayDone: function(resultSet) {

View File

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

View File

@ -1,3 +1,4 @@
require('./style.scss');
module.exports = new Class({ module.exports = new Class({
Extends: Htk.Field 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({ module.exports = new Class({
Extends: Htk.Field Extends: Htk.Field
,Tag: 'htk-calendar' ,Tag: 'htk-calendar'
,Properties: ,Properties: {
{ restrictFunc: {
restrictFunc:
{
type: Function type: Function
,set: function(x) { ,set: function(x) {
this._restrictFunc = x; this._restrictFunc = x;
} }
,get: function(x) { ,get: function() {
return this._restrictFunc; 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 * 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({ module.exports = new Class({
Extends: NodeBuilder Extends: NodeBuilder
,Tag: 'htk-column' ,Tag: 'htk-column'
,Properties: ,Properties: {
{
value: { value: {
type: String type: String
,value: null ,value: null
@ -57,7 +56,7 @@ module.exports = new Class({
* Initializes the column. * Initializes the column.
*/ */
,initialize: function(props) { ,initialize: function(props) {
this.parent(props); NodeBuilder.prototype.initialize.call(this, props);
this.td = this.createElement('td'); this.td = this.createElement('td');
} }
@ -90,7 +89,7 @@ module.exports = new Class({
} }
,changed: function(tr, newValue) { ,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({ module.exports = new Class({
Extends: Htk.Column, Extends: Htk.Column,
@ -36,11 +37,11 @@ module.exports = new Class({
initialize: function(props) { initialize: function(props) {
this._cssClass = 'cell-button'; this._cssClass = 'cell-button';
this.parent(props); Htk.Column.prototype.initialize.call(this, props);
}, },
render: function(tr) { render: function(tr) {
const td = this.parent(tr); const td = Htk.Column.prototype.render.call(this, tr);
let button; let button;
@ -69,6 +70,6 @@ module.exports = new Class({
}, },
buttonClicked: function(value, tr, button) { 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) { ,initialize: function(props) {
this._cssClass = 'cell-date'; this._cssClass = 'cell-date';
this.parent(props); Htk.Column.prototype.initialize.call(this, props);
} }
,render: function(tr) { ,render: function(tr) {
var text = Vn.Date.strftime(this.value, this._format); 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)); td.appendChild(this.createTextNode(text));
return td; return td;

View File

@ -1,46 +1,41 @@
require('./style.scss');
module.exports = new Class module.exports = new Class({
({
Extends: Htk.Column Extends: Htk.Column
,Tag: 'htk-column-image' ,Tag: 'htk-column-image'
,Properties: ,Properties: {
{
/** /**
* The directory where the images are allocated. * The directory where the images are allocated.
*/ */
directory: directory:{
{
type: String type: String
,value: null ,value: null
}, },
/** /**
* The subdirectory where the images are allocated. * The subdirectory where the images are allocated.
*/ */
subdir: subdir:{
{
type: String type: String
,value: null ,value: null
}, },
/** /**
* Subdirectory where full images are allocated. * Subdirectory where full images are allocated.
*/ */
fullDir: fullDir:{
{
type: String type: String
,value: null ,value: null
}, },
/** /**
* The REST connection used to upload the image. * The REST connection used to upload the image.
*/ */
conn: conn:{
{
type: Vn.JsonConnection type: Vn.JsonConnection
} }
} }
,initialize: function(props) { ,initialize: function(props) {
this._cssClass = 'cell-image'; this._cssClass = 'cell-image';
this.parent(props); Htk.Column.prototype.initialize.call(this, props);
} }
,render: function(tr) { ,render: function(tr) {
@ -53,7 +48,7 @@ module.exports = new Class
,doc: this.doc ,doc: this.doc
}); });
var td = this.parent(tr); var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(image.node); td.appendChild(image.node);
return td; 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 Extends: Htk.Column
,Tag: 'htk-column-link' ,Tag: 'htk-column-link'
,Properties: ,Properties: {
{
/** /**
* The link url. * The link url.
*/ */
href: href:{
{
type: String type: String
,value: null ,value: null
}, },
/** /**
* the target where the link is opened. * the target where the link is opened.
*/ */
target: target:{
{
type: String type: String
,value: null ,value: null
} }
@ -31,7 +27,7 @@ module.exports = new Class
if (this.target) if (this.target)
link.target = this.target; link.target = this.target;
var td = this.parent(tr); var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(link); td.appendChild(link);
return td; 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 Extends: Htk.Column
,Tag: 'htk-column-spin' ,Tag: 'htk-column-spin'
,Properties: ,Properties: {
{
/** /**
* The text to append to the number. * The text to append to the number.
*/ */
unit: unit:{
{
type: String type: String
,value: null ,value: null
}, },
@ -24,17 +22,17 @@ module.exports = new Class
,initialize: function(props) { ,initialize: function(props) {
this._cssClass = 'cell-spin'; this._cssClass = 'cell-spin';
this.parent(props); Htk.Column.prototype.initialize.call(this, props);
} }
,renderHeader: function() { ,renderHeader: function() {
var th = this.parent(); var th = Htk.Column.prototype.renderHeader.call(this, );
th.className = 'cell-spin'; th.className = 'cell-spin';
return th; return th;
} }
,render: function(tr) { ,render: function(tr) {
var td = this.parent(tr); var td = Htk.Column.prototype.render.call(this, tr);
var valueString = null; 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 Extends: Htk.Column
,Tag: 'htk-column-text' ,Tag: 'htk-column-text'
,Properties: ,Properties: {
{
/** /**
* Format that applies to the value. * Format that applies to the value.
*/ */
format: format:{
{
type: String type: String
,set: function(x) { ,set: function(x) {
this._format = _(x); this._format = _(x);
@ -24,7 +21,7 @@ module.exports = new Class
,initialize: function(props) { ,initialize: function(props) {
this._cssClass = 'cell-text'; this._cssClass = 'cell-text';
this.parent(props); Htk.Column.prototype.initialize.call(this, props);
} }
,render: function(tr) { ,render: function(tr) {
@ -42,7 +39,7 @@ module.exports = new Class
node = this.createTextNode( node = this.createTextNode(
Vn.Value.format(this.value, this._format)); Vn.Value.format(this.value, this._format));
var td = this.parent(tr); var td = Htk.Column.prototype.render.call(this, tr);
td.appendChild(node); td.appendChild(node);
return td; 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 Extends: Htk.Field
,Tag: 'htk-date-chooser' ,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 @@
require('./style.scss');
var Popup = require('./popup'); var Popup = require('../popup');
/** /**
* Class to show message dialogs with buttons. * Class to show message dialogs with buttons.
@ -97,7 +97,7 @@ Dialog.implement({
,_buttons: Button.ACCEPT ,_buttons: Button.ACCEPT
,open: function() { ,open: function() {
this.parent(); Popup.prototype.open.call(this);
// Dialog body // Dialog body
@ -146,8 +146,8 @@ Dialog.implement({
,hide(response) { ,hide(response) {
if (!this._isOpen) return; if (!this._isOpen) return;
this.parent(); Popup.prototype.hide.call(this);
this.signalEmit('response', response); this.emit('response', response);
} }
,createButton: function(label, 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 Extends: Htk.Field
,Tag: 'htk-entry' ,Tag: 'htk-entry'
,Properties: ,Properties: {
{
/** /**
* Displayed text when there is no content. * Displayed text when there is no content.
*/ */
@ -52,7 +50,7 @@ module.exports = new Class
node.addEventListener('change', this._onChange.bind(this)); node.addEventListener('change', this._onChange.bind(this));
} }
,_onChange: function(event) { ,_onChange: function() {
var newValue; var newValue;
if (this.node.value == '') 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({ module.exports = new Class({
Extends: Widget Extends: Component
,Implements: Vn.ParamIface
,Tag: 'htk-field' ,Tag: 'htk-field'
,Child: 'param' ,Child: 'param'
,Properties: ,Properties: {
{
value: { value: {
type: String type: String
,set: function(x) { ,set: function(x) {
@ -18,21 +18,48 @@ module.exports = new Class({
this.valueChanged(x); this.valueChanged(x);
this.putValue(x); this.putValue(x);
this._notifyChanges();
} }
,get: function(x) { ,get: function() {
return this._value; return this._value;
} }
}, },
param: { param: {
type: Vn.Param type: Vn.ParamIface
,set: function(x) { ,set: function(x) {
this.link({_param: x}, {'changed': this.onParamChange}); this._setParam(x);
this.onParamChange();
} }
,get: function() { ,get: function() {
return this._param; 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: { editable: {
type: Boolean type: Boolean
,set: function(x) { ,set: function(x) {
@ -48,21 +75,19 @@ module.exports = new Class({
form: { form: {
type: Db.Iterator type: Db.Iterator
,set: function(x) { ,set: function(x) {
this._form = x; this.lot = x;
this.bindToForm();
} }
,get: function() { ,get: function() {
return this._form; return this._lot;
} }
}, },
column: { column: {
type: String type: String
,set: function(x) { ,set: function(x) {
this._paramName = x; this.name = x;
this.bindToForm();
} }
,get: function() { ,get: function() {
return this._paramName; return this._name;
} }
}, },
conditionalFunc: { conditionalFunc: {
@ -71,27 +96,24 @@ module.exports = new Class({
} }
} }
,_value: undefined
,_param: null
,_editable: true ,_editable: true
,_blockParamChange: false ,_lockField: false
,_blockValueChange: false
,onParamChange: function() { ,_setValue: function(newValue) {
if (!this._blockValueChange) { if (!this._putValue(newValue))
this._blockParamChange = true; return;
this.value = this._param.value;
this._blockParamChange = false;
}
}
,bindToForm: function() { if (!this._lockField)
if (this._form && this._paramName) this.putValue(newValue);
this.param = new Db.Param
({ if (this.conditionalFunc)
form: this._form this.conditionalFunc(this, newValue);
,column: this._paramName
}); 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 * @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 * 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 * @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 * 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 * @param {Object} value The new entry value
*/ */
,valueChanged: function(value) { ,valueChanged: function(value) {
this._value = value; this._lockField = true;
this._setValue(value);
if (this.conditionalFunc) this._lockField = false;
this.conditionalFunc(this, value);
if (this._param && !this._blockParamChange) {
this._blockValueChange = true;
this._param.value = value;
this._blockValueChange = false;
}
this.signalEmit('changed');
} }
}); });

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

View File

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

View File

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

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