0
1
Fork 0

Checkpoint

This commit is contained in:
Juan Ferrer 2022-05-30 03:30:33 +02:00
parent 894ff77877
commit de19063ed9
118 changed files with 3166 additions and 1895 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,8 +8,8 @@ Hedera.Catalog = new Class({
this.close();
this.isOpen = true;
if (!localStorage.getItem('hederaGuest')) {
Hedera.BasketChecker.check(this.conn,
if (!localStorage.getItem('hederaGuest')) {
Hedera.BasketChecker.check(this.conn, this.hash,
this.onBasketCheck.bind(this));
} else {
var query = 'CALL mybasket_configureForGuest';
@ -42,36 +42,24 @@ Hedera.Catalog = new Class({
,onFilterChange: function() {
const $ = this.$;
const params = [
'search',
'realm',
'type',
'color',
'origin',
'category',
'producer'
];
const lot = {};
for (const param of params)
lot[param] = this.$[param].value;
const hash = this.hash;
if (lot.search != null || lot.type != null) {
if (hash.search != null || hash.type != null) {
const filter = new Sql.Operation({
type: Sql.Operation.Type.AND
});
const exprs = filter.exprs;
let idSearch = false;
if (lot.search != null) {
idSearch = /^\d+$/.test(lot.search);
exprs.add(idSearch ? $.idOp : $.nameOp);
if (hash.search != null) {
idSearch = /^\d+$/.test(hash.search);
filter.push(idSearch ? $.idOp : $.nameOp);
}
if (!idSearch) {
if (lot.realm != null)
exprs.add($.realmOp);
if (lot.type != null)
exprs.add($.typeOp);
if (hash.realm != null)
filter.push($.realmOp);
if (hash.type != null)
filter.push($.typeOp);
const tags = [
'color',
@ -80,28 +68,21 @@ Hedera.Catalog = new Class({
'producer'
];
for (const tag of tags)
if (lot[tag] != null)
exprs.add($[`${tag}Op`]);
if (hash[tag] != null)
filter.push($[`${tag}Op`]);
}
const batch = new Sql.Batch();
batch.addObject('filter', filter);
batch.block();
$.items.batch = batch;
const lot = new Vn.Lot();
lot.set('filter', filter);
$.items.lot = lot;
} else
$.items.batch = null;
$.items.lot = null;
}
,onRealmChange: function() {
const hasRealm = this.$.realm.value != null;
this.$.filters.style.display = hasRealm ? 'block' : 'none';
this.$.realmMsg.style.display = hasRealm ? 'none' : 'block';
this.onFilterChange();
this.refreshTitle();
}
,onTypeChange: function() {
this.onFilterChange();
this.refreshTitle();
}
@ -234,14 +215,14 @@ Hedera.Catalog = new Class({
if (this.isGuest())
return;
this.hash.set({form: 'ecomerce/basket'});
this.hash.setAll({form: 'ecomerce/basket'});
}
,onConfigureClick: function() {
if (this.isGuest())
return;
this.hash.set({form: 'ecomerce/checkout'});
this.hash.setAll({form: 'ecomerce/checkout'});
}
,onAddItemClick: function(event, form) {
@ -280,7 +261,6 @@ Hedera.Catalog = new Class({
,onConfirmClick: function() {
var sql = '';
var batch = new Sql.Batch();
var query = new Sql.String({query: 'CALL myBasket_addItem(#warehouse, #item, #amount);'});
var amountSum = 0;
@ -288,10 +268,12 @@ Hedera.Catalog = new Class({
var amount = this.items[warehouse];
amountSum += amount;
batch.addValue('warehouse', warehouse);
batch.addValue('item', this.$.cardItem.value);
batch.addValue('amount', amount);
sql += query.render(batch);
const params = {
warehouse: warehouse,
item: this.$.cardItem.value,
amount: amount
}
sql += query.render(params);
}
if (amountSum > 0) {
@ -336,7 +318,7 @@ Vn.Filter = new Class({
model: {
type: Db.Model
,set: function(x) {
x.batch = this._batch;
x.lot = this._lot;
this._model = x;
this._select.model = x;
}
@ -358,7 +340,7 @@ Vn.Filter = new Class({
type: Sql.Filter
,set: function(x) {
this._filter = x;
this._batch.addObject('filter', x);
this._lot.set('filter', x);
}
,get: function() {
return this._filter;
@ -382,7 +364,7 @@ Vn.Filter = new Class({
this._ul = this.createElement('ul');
this.node.appendChild(this._ul);
this._batch = new Sql.Batch();
this._lot = new Vn.Lot();
this.parent(props);
}
@ -418,9 +400,9 @@ Vn.Filter = new Class({
}
,_changeValue: function(newValue) {
this._batch.block();
this._lot.block();
this.value = newValue;
this._batch.unblock();
this._lot.unblock();
}
,_onTimeout: function() {

View File

@ -157,7 +157,7 @@
font-size: 1em;
text-overflow: ellipsis;
overflow: hidden;
max-height: 2.8em;
max-height: 3em;
}
.item-info > p {
margin: 0;
@ -247,7 +247,7 @@
flex-direction: column;
width: 240px;
height: 405px;
height: 410px;
overflow: hidden;
}
.grid-view .item-box:hover {

View File

@ -22,18 +22,11 @@
</button>
</div>
<vn-group>
<vn-hash-param key="realm" param="realm"/>
<vn-hash-param key="type" param="type"/>
</vn-group>
<vn-group>
<vn-param id="card-item"/>
<vn-param id="search" on-changed="this.onFilterChange()"/>
<vn-param id="realm" on-changed="this.onRealmChange()"/>
<vn-param id="type" on-changed="this.onTypeChange()"/>
<vn-param id="color" on-changed="this.onFilterChange()"/>
<vn-param id="origin" on-changed="this.onFilterChange()"/>
<vn-param id="category" on-changed="this.onFilterChange()"/>
<vn-param id="producer" on-changed="this.onFilterChange()"/>
<vn-lot-query id="params" on-change="this.onFilterChange()">
<vn-spec name="search" type="String"/>
<vn-spec name="realm" type="Number"/>
<vn-spec name="type" type="Number"/>
</vn-lot-query>
</vn-group>
<vn-group>
<sql-operation
@ -125,11 +118,7 @@
LIMIT 5000;
</db-model>
<db-form id="card" model="items"/>
<sql-batch id="card-batch">
<custom>
<item name="item" param="card-item"/>
</custom>
</sql-batch>
<vn-lot id="card-lot"/>
</vn-group>
<div id="form" class="catalog">
<div id="main" class="main">
@ -383,7 +372,7 @@
<db-form id="card-extend">
<db-model
property="model"
batch="card-batch"
lot="card-lot"
on-status-changed-after="onCardLoad">
SELECT i.description, o.name origin
FROM vn.item i
@ -421,7 +410,7 @@
<htk-repeater show-status="false" form-id="tag" class="tags">
<db-model
property="model"
batch="card-batch"
lot="card-lot"
on-status-changed-after="onCardLoad">
SELECT l.name, it.value
FROM vn.itemTag it
@ -445,7 +434,7 @@
property="model"
result-index="1"
on-status-changed-after="onCardLoad"
batch="card-batch">
lot="card-lot">
CALL myBasket_calcCatalogFromItem(#item);
SELECT l.warehouseFk, w.name warehouse, p.`grouping`,
p.price, p.priceKg, p.rate, l.available

View File

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

View File

@ -1,9 +1,6 @@
<vn>
<vn-group>
<vn-param id="method"/>
<vn-param id="date"/>
<vn-param id="agency"/>
<vn-param id="address" on-changed="onAddressChange"/>
<vn-lot id="lot" on-change="this.onAddressChange()"/>
<db-form id="defaults" on-ready="onValuesReady">
<db-model property="model">
SELECT deliveryMethod, agencyModeFk, addressFk, defaultAgencyFk
@ -19,6 +16,7 @@
</db-form>
<db-model id="agencies"
auto-load="false"
lot="lot"
result-index="1"
on-status-changed="onAgenciesReady">
CALL vn.zone_getAgency(#address, #date);
@ -30,15 +28,10 @@
AND a.isVisible
ORDER BY a.description;
DROP TEMPORARY TABLE tmp.zoneGetAgency;
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model>
<db-model id="warehouses"
auto-load="false"
lot="lot"
result-index="1"
on-status-changed="onWarehousesReady">
CALL vn.zone_getAgency(#address, #date);
@ -50,12 +43,6 @@
AND a.isVisible
ORDER BY a.description;
DROP TEMPORARY TABLE tmp.zoneGetAgency;
<sql-batch property="batch">
<custom>
<item name="address" param="address"/>
<item name="date" param="date"/>
</custom>
</sql-batch>
</db-model>
</vn-group>
<div id="title">

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

@ -73,16 +73,16 @@ Model.implement({
}
},
/**
* The batch used to execute the statement.
* The lot used to execute the statement.
*/
batch: {
type: Sql.Batch
lot: {
type: Vn.LotIface
,set: function(x) {
this.link({_batch: x}, {'changed': this._autoLoad});
this._autoLoad();
this.link({_lot: x}, {'change': this._autoLoad});
this._onLotChange();
}
,get: function() {
return this._batch;
return this._lot;
}
},
/**
@ -189,7 +189,7 @@ Model.implement({
,_conn: null
,_resultIndex: 0
,_batch: null
,_lot: null
,_stmt: null
,_status: Status.CLEAN
,data: null
@ -232,39 +232,69 @@ Model.implement({
this.query = query;
}
,_getLotParams: function() {
if (!this._stmt)
return null;
var holders = this._stmt.findHolders();
if (!holders)
return null;
var lotParams = this._lot ? this._lot.params : {};
if (lotParams == null)
lotParams = {};
var params = {};
for (var i = 0; i < holders.length; i++)
params[holders[i]] = lotParams[holders[i]];
return params;
}
,_onLotChange: function() {
var lotParams = this._getLotParams();
if (!Vn.Value.equals(lotParams, this._lastLotParams))
this._autoLoad();
}
,_autoLoad: function() {
if (this.autoLoad)
this.refresh();
else
this.clean();
}
,_isReady: function(params) {
if (!this._stmt || !this._conn)
return false;
var holders = this._stmt.findHolders();
if (!holders)
return true;
for (var i = 0; i < holders.length; i++)
if (params[holders[i]] === undefined)
return false;
return true;
}
/**
* Refresh the model data reexecuting the query on the database.
*/
,refresh: function() {
var ready = false;
if (this._stmt && this._conn) {
var ids = this._stmt.findHolders();
if (ids) {
if (this._batch && this._batch.isReady()) {
ready = true;
,refresh: function(params) {
var lotParams = this._getLotParams();
var myParams = {};
for (var i = 0; i < ids.length; i++)
if (!this._batch.get(ids[i])) {
ready = false;
break;
}
}
} else
ready = true;
}
Object.assign(myParams, lotParams);
Object.assign(myParams, params);
if (ready) {
if (this._filter && (!params || params.filter === undefined))
myParams.filter = this._filter;
this._lastLotParams = lotParams;
if (this._isReady(myParams)) {
this._setStatus(Status.LOADING);
this._conn.execStmt(this._stmt, this._selectDone.bind(this), this._batch);
this._conn.execStmt(this._stmt,
this._selectDone.bind(this), myParams);
} else
this.clean();
}
@ -344,7 +374,7 @@ Model.implement({
this._updatable = this._mainTable !== null && this._requestedUpdatable;
if (oldValue != this._updatable)
this.signalEmit('updatable-changed');
this.emit('updatable-changed');
}
,_refreshMainTable: function() {
@ -492,7 +522,7 @@ Model.implement({
*/
,get: function(rowIndex, columnName) {
if (this.checkRowExists(rowIndex))
return this.data[rowIndex][columnName];
return this.data[rowIndex][columnName];
}
/**
@ -541,9 +571,9 @@ Model.implement({
&& op.oldValues[columnName] === undefined)
op.oldValues[columnName] = row[columnName];
this.signalEmit('row-updated-before', rowIndex);
this.emit('row-updated-before', rowIndex);
row[columnName] = value;
this.signalEmit('row-updated', rowIndex, [columnName]);
this.emit('row-updated', rowIndex, [columnName]);
if (this.mode == Mode.ON_CHANGE
&& !(op.type & Operation.INSERT))
@ -596,12 +626,12 @@ Model.implement({
op.type |= Operation.DELETE;
if (!this._requestedMainTable) {
this.signalEmit('row-deleted-before', rowIndex);
this.emit('row-deleted-before', rowIndex);
this.data.splice(rowIndex, 1);
this.signalEmit('row-deleted', rowIndex);
this.emit('row-deleted', rowIndex);
this._refreshRowIndexes(rowIndex);
} else {
this.signalEmit('row-updated-before', rowIndex);
this.emit('row-updated-before', rowIndex);
if (!op.oldValues)
op.oldValues = [];
@ -619,7 +649,7 @@ Model.implement({
updatedCols.push(i);
}
this.signalEmit('row-updated', rowIndex, updatedCols);
this.emit('row-updated', rowIndex, updatedCols);
}
if (this.mode === Mode.ON_CHANGE)
@ -650,7 +680,7 @@ Model.implement({
var op = this._createOperation(rowIndex);
op.type |= Operation.INSERT;
this.signalEmit('row-inserted', rowIndex);
this.emit('row-inserted', rowIndex);
return rowIndex;
}
@ -662,14 +692,14 @@ Model.implement({
var ops = this._operations;
if (ops.length === 0) {
this.signalEmit('operations-done');
this.emit('operations-done');
return;
}
var stmts = new Sql.MultiStmt();
var query = new Sql.String({query: 'START TRANSACTION'});
stmts.addStmt(query);
stmts.push(query);
for (var i = 0; i < ops.length; i++) {
query = null;
@ -690,12 +720,12 @@ Model.implement({
for (var tableIndex in op.tables) {
var stmt = this._createDmlQuery(op, parseInt(tableIndex));
query.addStmt(stmt);
query.push(stmt);
}
}
if (query) {
stmts.addStmt(query);
stmts.push(query);
} else {
console.warn('Db.Model: %s', _('ErrorSavingChanges'));
return;
@ -703,7 +733,7 @@ Model.implement({
}
var query = new Sql.String({query: 'COMMIT'});
stmts.addStmt(query);
stmts.push(query);
this._conn.execStmt(stmts,
this._onOperationsDone.bind(this, ops));
@ -764,8 +794,8 @@ Model.implement({
dmlQuery.addTarget(target);
multiStmt.addStmt(dmlQuery);
multiStmt.addStmt(select);
multiStmt.push(dmlQuery);
multiStmt.push(select);
return multiStmt;
}
@ -795,7 +825,7 @@ Model.implement({
if (op.type & Operation.DELETE) {
resultSet.fetchResult();
} else if (op.type & (Operation.INSERT | Operation.UPDATE)) {
this.signalEmit('row-updated-before', row.index);
this.emit('row-updated-before', row.index);
var updatedCols = [];
var cols = this.columns;
@ -823,14 +853,14 @@ Model.implement({
}
}
this.signalEmit('row-updated', row.index, updatedCols);
this.emit('row-updated', row.index, updatedCols);
}
}
resultSet.fetchResult();
// if (isOperation)
this.signalEmit('operations-done');
this.emit('operations-done');
}
/**
@ -844,9 +874,9 @@ Model.implement({
if (op.type & Operation.DELETE
&& !(op.type & Operation.INSERT)) {
this.data.splice(row.index, 0, row);
this.signalEmit('row-inserted', row.index);
this.emit('row-inserted', row.index);
} else if (op.type & Operation.UPDATE) {
this.signalEmit('row-updated-before', row.index);
this.emit('row-updated-before', row.index);
var updatedCols = [];
var cols = this.columns;
@ -858,7 +888,7 @@ Model.implement({
updatedCols.push(i);
}
this.signalEmit('row-updated', row.index, updatedCols);
this.emit('row-updated', row.index, updatedCols);
}
}
@ -1064,8 +1094,8 @@ Model.implement({
,_setStatus: function(status) {
this._status = status;
this.signalEmit('status-changed', status);
this.signalEmit('status-changed-after', status);
this.emit('status-changed', status);
this.emit('status-changed-after', status);
}
,_createTarget: function(tableIndex) {
@ -1088,8 +1118,8 @@ Model.implement({
const column = this.columnMap[pk];
const equalOp = new Sql.Operation({type: Sql.Operation.Type.EQUAL});
equalOp.exprs.add(new Sql.Field({name: column.orgname}));
where.exprs.add(equalOp);
equalOp.push(new Sql.Field({name: column.orgname}));
where.push(equalOp);
let pkValue = null;
@ -1100,9 +1130,9 @@ Model.implement({
pkValue = op.row[pk];
if (pkValue)
equalOp.exprs.add(new Sql.Value({value: pkValue}));
equalOp.push(new Sql.Value({value: pkValue}));
else if (column.flags & Connection.Flag.AI && !useOldValues)
equalOp.exprs.add(new Sql.Function({name: 'LAST_INSERT_ID'}));
equalOp.push(new Sql.Function({name: 'LAST_INSERT_ID'}));
else
return null;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -64,8 +64,10 @@ module.exports = new Class({
window.addEventListener('scroll', this._onScrollHandler );
}
this.hash = Vn.Hash;
this.formParam = new Vn.HashParam({key: 'form'});
this.formParam = new Vn.Param({
lot: this.hash,
name: 'form',
});
this.formParam.on('changed', this._onFormChange, this);
if (!localStorage.getItem('hederaCookies')) {
@ -101,7 +103,7 @@ module.exports = new Class({
}
,_onConnClose: function() {
this.signalEmit('logout');
this.emit('logout');
}
,_onConnLoadChange: function(conn, isLoading) {
@ -206,7 +208,7 @@ module.exports = new Class({
var a = this.createElement('a');
if (row.path) {
a.href = Vn.Hash.make({form: row.path});
a.href = this.hash.make({form: row.path});
this.menuOptions[row.path] = a;
}
@ -445,14 +447,14 @@ module.exports = new Class({
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Reports
,openReport: function(reportName, batch) {
,openReport: function(reportName, lot) {
this.loaderPush();
var module = new Module('reports', reportName);
module.addCallback(this._onReportLoad.bind(this, batch));
module.addCallback(this._onReportLoad.bind(this, lot));
}
,_onReportLoad: function(batch, module) {
,_onReportLoad: function(lot, module) {
this.loaderPop();
if (module.error) {
@ -461,7 +463,7 @@ module.exports = new Class({
}
var report = new module.klass(module, this);
report.open(batch);
report.open(lot);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant

View File

@ -69,7 +69,7 @@ module.exports = new Class({
if (user)
localStorage.setItem('hederaLastUser', user);
this.signalEmit('login');
this.emit('login');
} else {
this._focusUserInput();
throw error;

View File

@ -9,8 +9,8 @@ module.exports = new Class({
this.parent(null);
}
,open: function(batch) {
this.batch = batch;
,open: function(lot) {
this.lot = lot;
this.createWindow();
}
@ -70,7 +70,7 @@ module.exports = new Class({
var scope = this.scope = builder.load(this.doc, this);
scope.link(null, {
batch: this.batch,
lot: this.lot,
conn: this.conn
});
this.$ = scope.$;

View File

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

View File

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

View File

@ -42,7 +42,7 @@ module.exports = new Class({
set: function(x) {
this._stepsIndex = x;
this.setStep(this._stepIndex);
this.signalEmit('steps-change');
this.emit('steps-change');
},
get: function() {
return this._stepsIndex;
@ -132,7 +132,7 @@ module.exports = new Class({
this._stepName = stepName;
this.currentStep = step;
step.show();
this.signalEmit('step-change', stepIndex);
this.emit('step-change', stepIndex);
if (this.stepFunc)
this.stepFunc(step);

View File

@ -90,7 +90,7 @@ module.exports = new Class({
}
,changed: function(tr, newValue) {
this.signalEmit('changed', tr.rowIndex - 1, newValue);
this.emit('changed', tr.rowIndex - 1, newValue);
}
});

View File

@ -69,6 +69,6 @@ module.exports = new Class({
},
buttonClicked: function(value, tr, button) {
this.signalEmit('clicked', value, tr.rowIndex - 1, button);
this.emit('clicked', value, tr.rowIndex - 1, button);
}
});

View File

@ -147,7 +147,7 @@ Dialog.implement({
,hide(response) {
if (!this._isOpen) return;
this.parent();
this.signalEmit('response', response);
this.emit('response', response);
}
,createButton: function(label, response) {

View File

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

View File

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

View File

@ -153,7 +153,7 @@ module.exports = new Class({
popup.on('closed', this._onPopupClose.bind(this));
popup.show(this.node);
this.signalEmit('menu-show');
this.emit('menu-show');
e.stopPropagation();
}
@ -184,7 +184,7 @@ module.exports = new Class({
,_onPopupClose: function() {
this._popup = null;
this.signalEmit('menu-hide');
this.emit('menu-hide');
}
,_refreshShowText: function() {
@ -204,14 +204,14 @@ module.exports = new Class({
,_onModelChange: function() {
var model = this._model;
this.signalEmit('status-changed');
this.emit('status-changed');
if (this._popup)
this._popup.reset();
if (model && model.ready) {
this._selectOption();
this.signalEmit('ready');
this.emit('ready');
} else
this._setRow(-1);
}

View File

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

View File

@ -35,7 +35,7 @@ module.exports = new Class({
if (!newValue)
newValue = null
this.signalEmit('name-changed', newValue);
this.emit('name-changed', newValue);
},
_onSubmit: function() {
@ -55,7 +55,7 @@ module.exports = new Class({
throw error;
Toast.showMessage(_('ImageAdded'));
this.signalEmit('file-uploaded', this.$.name.value);
this.emit('file-uploaded', this.$.name.value);
},
setData: function(image, directory) {

View File

@ -185,7 +185,7 @@ module.exports = new Class
Vn.Node.remove(this._node);
this._parent = null;
this._isOpen = false;
this.signalEmit('closed');
this.emit('closed');
}
,_bgMouseDown: function(e) {

View File

@ -169,7 +169,7 @@ module.exports = new Class({
}
this.node.appendChild(this._container);
this.signalEmit('change');
this.emit('change');
}
,_showNoRecordsFound: function() {

View File

@ -68,7 +68,8 @@ const Widget = new Class({
type: String
,set: function(x) {
this._htmlId = x;
this._node.id = x;
if (this._node)
this._node.id = x;
}
,get: function() {
return this._htmlId;
@ -85,7 +86,9 @@ const Widget = new Class({
}
,createRoot: function(tagName) {
return this._node = this.createElement(tagName);
const node = this._node = this.createElement(tagName);
if (this._htmlId) node.id = this._htmlId;
return node;
}
,renderBase: function() {

View File

@ -1,142 +0,0 @@
var Object = require('./object');
var Value = require('./value');
/**
* A map container for many Sql.Object
*/
module.exports = new Class({
Extends: Object
,Tag: 'sql-batch'
,Properties: {
blocked: {
type: Boolean
,set: function(x) {
this._blocked = x;
}
,get: function() {
return this._blocked;
}
}
}
,objects: {}
,_blocked: false
,loadXml: function(scope, node) {
this.parent(scope, node);
var childs = node.childNodes;
for (var i = 0; i < childs.length; i++)
if (childs[i].tagName && childs[i].tagName.toLowerCase() == 'item') {
var object;
var id = childs[i].getAttribute('name');
if (id) {
if (object = scope.getById(childs[i].getAttribute('param')))
this.addParam(id, object);
else if (object = scope.getById(childs[i].getAttribute('object')))
this.addObject(id, object);
}
}
}
,get: function(id) {
if (this.objects[id])
return this.objects[id];
return null;
}
,add: function(id) {
if (!this.objects[id])
this.objects[id] = null;
}
,_addObject: function(id, object) {
this.remove(id);
this.objects[id] = object;
object.on('changed', this.emitChanged, this);
this.emitChanged();
}
,addObject: function(id, object) {
this._addObject(id, object.ref());
}
,addValue: function(id, value) {
this._addObject(id,
new Value({value: value}));
}
,addValues: function(values) {
for (var id in values)
this.addValue(id, values[id]);
}
,addParam: function(id, param) {
this._addObject(id,
new Value({param: param}));
}
,getValue: function(id) {
var object = this.objects[id];
if (object instanceof Value)
return object.value;
return null;
}
,addParams: function(params) {
for (var id in params)
this.addParam(id, params[id]);
}
,remove: function(id) {
if (this.objects[id]) {
this._unrefObject(this.objects[id]);
delete this.objects[id];
}
}
,block: function() {
this._blocked = true;
}
,unblock: function() {
this._blocked = false;
}
,emitChanged: function() {
if (!this._blocked)
this.signalEmit('changed');
}
,changed: function() {
this.signalEmit('changed');
}
,isReady: function() {
for (var id in this.objects)
if (!(this.objects[id] && this.objects[id].isReady()))
return false;
return true;
}
,_unrefObject: function(object) {
if (object) {
object.disconnect('changed', this.emitChanged, this);
object.unref();
}
}
,_destroy: function() {
for (var id in this.objects)
this._unrefObject(this.objects[id]);
this.parent();
}
});

View File

@ -4,19 +4,14 @@ var Stmt = require('./stmt');
/**
* The equivalent of a SQL delete.
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Stmt
,Tag: 'sql-delete'
,render: function(batch) {
var sql = 'DELETE FROM ' + this.renderTarget(batch);
if (this.where)
sql += ' WHERE ' + this.where.render(batch);
sql += ' LIMIT 1'; // Only for security.
return sql;
,render: function(params) {
return 'DELETE FROM'
+ this.renderTarget(params)
+ this.renderIfSet(this.where, 'WHERE', params)
+ this.renderLimit(params);
}
});

View File

@ -13,13 +13,13 @@ module.exports = new Class({
,expr: []
,addSet: function(fieldName, value) {
this.expr.push(new Value({value: value}));
this.field.push(new Field({name: fieldName}));
this.expr.push(new Value({value: value}));
}
,addExpr: function(fieldName, expr) {
this.expr.push(expr);
this.field.push(new Field({name: fieldName}));
this.expr.push(expr);
}
,delSet: function() {

View File

@ -1,5 +1,5 @@
var Expr = require('./expr');
var Expr = require ('./expr');
/**
* The equivalent of a SQL field.
@ -12,11 +12,17 @@ module.exports = new Class
,Tag: 'sql-field'
,Properties:
{
/**
* The column name.
*/
name:
{
type: String
,value: null
},
/**
* The source table name or its alias if it has been specified.
*/
target:
{
type: String
@ -24,8 +30,9 @@ module.exports = new Class
}
}
,render: function(batch) {
var sql = (this.target) ? '`' + this.target + '`.' : '';
return sql + '`' + this.name + '`';
,render: function ()
{
return this.renderPreIdent (this.target)
+ this.renderIdent (this.name);
}
});

View File

@ -1,17 +1,68 @@
var Operation = require('./operation');
var Value = require('./value');
var Field = require('./field');
/**
* The equivalent of a SQL operation.
* Objects to be used as an operands of @Sql.Filter. It represents a two
* expressions basic operation composed by a table column, the operator and the
* value extracted from the rendering paramerers.
*/
module.exports = new Class({
Extends: Operation
,Tag: 'sql-filter-item'
,Properties: {
primary: {
type: Boolean
/**
* The column name.
*/
field: {
type: String,
value: null
},
/**
* The source table name or its alias if it has been specified.
*/
target: {
type: String,
value: null
},
/**
* The parameter name.
*/
param: {
type: String,
value: null
}
}
,primary: true
/**
* Checks if parameter name haa been defined and if it has a value.
*/
,isReady: function(params) {
return this.param != null && params != null && params[this.param] != null;
}
,render: function(params) {
var newOp = new Operation({type: this.type});
newOp.push(new Field({
name: this.field,
target: this.target
}));
var value = params[this.param];
if (this.type === Operation.Type.LIKE && typeof value === 'string') {
value = value.replace(/[\%\?]/g, this._escapeChar);
value = value.replace(/^|\s+|$/g, '%');
}
newOp.push(new Value({value: value}));
return newOp.render(params);
}
,_escapeChar: function(char) {
return '\\'+ char;
}
});

View File

@ -1,44 +1,52 @@
var Operation = require('./operation');
var Operation = require ('./operation');
var Value = require ('./value');
/**
* The equivalent of a SQL operation.
* The equivalent of a SQL filter expression. It allows to automatically build
* SQL filters based on lot parameters.
*/
module.exports = new Class({
module.exports = new Class
({
Extends: Operation
,Tag: 'sql-filter'
,Properties: {
alwaysReady: {
type: Boolean
}
}
,isReady: function() {
if (this.alwaysReady)
/**
* Checks if any of filters childs are ready.
*/
,isReady: function (params)
{
var exprs = this.exprs;
for (var i = exprs.length; i--;)
if (exprs[i].isReady (params))
return true;
var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++)
if (e[i].isReady() && e[i].primary)
return true;
return false;
}
,render: function(batch) {
var isReady = false;
var newOp = new Operation({type: this.type});
/**
* Renders the filter as an SQL expression. If any of its childs isn't
* ready is ommitted from the expression. If all of its childs aren't ready
* renders the TRUE expression.
*/
,render: function (params)
{
var newOp;
var newExprs = [];
this.exprs.forEach (function (expr) {
if (expr.isReady (params))
newExprs.push (expr);
})
var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++)
if (e[i].isReady()) {
newOp.exprs.add(e[i]);
isReady = true;
}
if (newExprs.length > 0)
newOp = new Operation ({
type: this.type,
exprs: newExprs
});
else
newOp = new Value ({value: true});
if (!isReady)
return 'TRUE';
return newOp.render(batch);
return newOp.render (params);
}
});

View File

@ -1,38 +1,56 @@
var Expr = require ('./expr');
var List = require ('./list');
var ListHolder = require ('./list-holder');
/**
* The equivalent of a SQL function.
*
* @param {string} funcName The name of the function
* @param {Array#Sql.Expr} param Array with function parameters
*/
module.exports = new Class
({
Extends: Expr
,Tag: 'sql-function'
,Implements: ListHolder
,Properties:
{
/**
* The function name.
*/
name:
{
type: String
,value: null
},
/**
* The function schema.
*/
schema:
{
type: String
,value: null
},
/**
* The function parameters.
*/
params:
{
type: List
,value: null
type: Array
,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
}
}
,render: function (batch)
,render: function (params)
{
var sql = (this.schema) ? '`' + this.schema + '`.' : '';
return sql + '`' + this.name + '`()';
return this.renderPreIdent (this.schema)
+ this.renderIdent (this.name)
+ '('
+ this.renderListWs (this.list, params, ', ')
+ ')';
}
});

View File

@ -1,12 +1,13 @@
var Object = require('./object');
var SqlObject = require ('./object');
var Value = require ('./value');
/**
* A holder for another object.
*/
module.exports = new Class
({
Extends: Object
Extends: SqlObject
,Properties:
{
id:
@ -16,11 +17,24 @@ module.exports = new Class
}
}
,render: function(batch) {
var object;
,render: function (params)
{
if (params)
{
var object = params[this.id];
if (batch && (object = batch.get(this.id)))
return object.render(batch);
if (object !== undefined)
{
if (!(object instanceof SqlObject))
{
var sqlValue = new Value ();
sqlValue.value = object;
return sqlValue.render ();
}
else
return object.render (params);
}
}
return '#'+ this.id;
}

View File

@ -8,31 +8,14 @@ module.exports = new Class
({
Extends: Dml
,render: function (batch)
,render: function (params)
{
var sql;
var n;
sql = 'INSERT INTO ' + this.renderTarget (batch) + ' (';
for (n = 0; n < this.field.length; n++)
{
if (n > 0)
sql += ', ';
sql += this.field[n].render (batch);
}
sql += ') VALUES (';
for (n = 0; n < this.field.length; n++)
{
if (n > 0)
sql += ', ';
sql += this.expr[n].render(batch);
}
sql += ')';
return sql;
return 'INSERT INTO'
+ this.renderTarget (params)
+ ' ('
+ this.renderListWs (this.field, params, ', ')
+ ') VALUES ('
+ this.renderListWs (this.expr, params, ', ')
+ ')';
}
})

54
js/sql/join-item.js Normal file
View File

@ -0,0 +1,54 @@
var Target = require ('./target');
var Expr = require ('./expr');
var SqlObject = require ('./object');
var Type = require ('./join').Type;
var TypeSql = [
'INNER',
'LEFT',
'RIGHT'
];
/**
* The equivalent of a SQL join.
*/
module.exports = new Class
({
Extends: SqlObject
,Tag: 'sql-join-table'
,Properties:
{
/**
* The join type.
*/
type:
{
enumType: Type
,value: 0
},
/**
* The right target.
*/
target:
{
type: Target
,value: null
},
/**
* The join on condition.
*/
condition:
{
type: Expr
,value: null
}
}
,render: function (params)
{
return TypeSql[this.type] +' JOIN '
+ this.target.render (params)
+ this.renderIfSet (this.condition, 'ON', params);
}
});

54
js/sql/join.js Normal file
View File

@ -0,0 +1,54 @@
var Target = require ('./target');
var ListHolder = require ('./list-holder');
/**
* The equivalent of a SQL join.
*/
var Klass = new Class ();
module.exports = Klass;
var Type = {
INNER : 0,
LEFT : 1,
RIGHT : 2
};
Klass.extend
({
Type: Type
});
Klass.implement
({
Extends: Target
,Implements: ListHolder
,Tag: 'sql-join'
,Properties:
{
/**
* The right targets.
*/
targets:
{
type: Array
,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
}
}
,render: function (params)
{
return '('
+ this.target.render (params)
+ ' '
+ this.renderList (this.list, params)
+ ')';
}
});

60
js/sql/list-holder.js Normal file
View File

@ -0,0 +1,60 @@
/**
* Interface for array holders.
*/
module.exports = new Class
({
Properties:
{
/*
list:
{
type: Array
,set: function (x)
{
this._list = x;
}
,get: function ()
{
return this._list;
}
}
*/
}
,list: []
,appendChild: function (child)
{
this.list.push (child);
}
/**
* Adds an element to the list.
*
* @param {SqlObject} element The element to add
*/
,push: function (element)
{
this.list.push (element);
}
/**
* Removes an element from the list.
*
* @param {Number} i The element index
*/
,splice: function (i)
{
this.list.splice (i);
}
/**
* Adds an element to the list.
*
* @param {Number} i The element index
*/
,get: function (i)
{
return this.list[i];
}
});

View File

@ -1,60 +1,69 @@
var Object = require('./object');
var Object = require ('./object');
/**
* List of Sql.Object
*/
module.exports = new Class({
module.exports = new Class
({
Extends: Object
,objects: []
,add: function(object) {
this.objects.push(object.ref());
object.on('changed', this._onObjectChange, this);
this._onObjectChange();
,add: function (object)
{
this.objects.push (object.ref ());
object.on ('changed', this._onObjectChange, this);
this._onObjectChange ();
}
,get: function(i) {
,get: function (i)
{
return objects[i];
}
,getArray: function() {
,getArray: function ()
{
return this.objects;
}
,remove: function(i) {
this._unrefObject(this.objects.splice(i, 1));
this._onObjectChange();
,remove: function (i)
{
this._unrefObject (this.objects.splice (i, 1));
this._onObjectChange ();
}
,_onObjectChange: function() {
this.signalEmit('changed');
,_onObjectChange: function ()
{
this.emit ('changed');
}
,isReady: function() {
,isReady: function ()
{
var o = this.objects;
if (o.length == 0)
return false;
for (var i = 0; i < o.length; i++)
if (!o[i].isReady())
if (!o[i].isReady ())
return false;
return true;
}
,_unrefObject: function(object) {
object.disconnect('changed', this._onObjectChange, this);
object.unref();
,_unrefObject: function (object)
{
object.disconnect ('changed', this._onObjectChange, this);
object.unref ();
}
,_destroy: function() {
,_destroy: function ()
{
for (var i = 0; i < this.objects.length; i++)
this._unrefObject(this.objects[i]);
this._unrefObject (this.objects[i]);
this.parent();
this.parent ();
}
});

View File

@ -1,5 +1,6 @@
var Stmt = require ('./stmt');
var ListHolder = require ('./list-holder');
/**
* The equivalent of a SQL multi statement.
@ -7,43 +8,29 @@ var Stmt = require ('./stmt');
module.exports = new Class
({
Extends: Stmt
,stmts: []
,addStmt: function (stmt)
,Implements: ListHolder
,Tag: 'sql-multi-stmt'
,Properties:
{
return this.stmts.push (stmt);
}
,getStmt: function (stmtIndex)
{
return this.stmts[index];
}
,isReady: function ()
{
if (this.stmts.length == 0)
return false;
for (var i = 0; i < this.stmts.length; i++)
if (!this.stmts[i].isReady ())
return false;
return true;
}
,render: function (batch)
{
var sql = '';
for (var i = 0; i < this.stmts.length; i++)
/**
* The statements list.
*/
stmts:
{
if (i > 0)
sql += ";\n";
sql += this.stmts[i].render (batch);
type: Array
,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
}
}
return sql;
,render: function (params)
{
return this.renderListWs (this.list, params, ";\n");
}
});

View File

@ -3,18 +3,11 @@
*/
module.exports = new Class({
Extends: Vn.Object
/**
* Renders the object as an SQL string.
*
* @param {Sql.Batch} batch The batch used to render the object
* @return {String} The SQL string
*/
,render: function(batch) {}
/**
* Gets if the object is ready to be rendered.
*
* @param {Object} params The query parameters
* @return {boolean} %true if the object is ready, %false otherwise
*/
,isReady: function() {
@ -22,9 +15,90 @@ module.exports = new Class({
}
/**
* Through the query looking for containers and adds it to the batch.
* Through the query looking for containers.
*
* @return {Sql.Batch} batch The batch
* @return {Array} An array with the names of the found parameters
*/
,findHolders: function(batch) {}
,findHolders: function() {}
/**
* Renders the object as an SQL string.
*
* @param {Object} params The params used to render the object
* @return {string} The SQL string
*/
,render: function() {}
/**
* Renders an objects array.
*
* @param {Array} list The objects array
* @param {Object} params The parameters
* @return {string} The rendered SQL string
*/
,renderList: function(list, params) {
var sql = '';
list.forEach(function(item) {
sql += item.render(params);
})
return sql;
}
/**
* Renders an objects array using a separator.
*
* @param {Array} list The objects array
* @param {Object} params The parameters
* @param {String} separator The separator between items
* @return {string} The rendered SQL string
*/
,renderListWs: function(list, params, separator) {
var sql = '';
list.forEach(function(item, i) {
if (i > 0)
sql += separator;
sql += item.render(params);
})
return sql;
}
/**
* Renders a quoted SQL identifier.
*
* @param {String} identifier The identifier
* @return {string} The quoted identifier
*/
,renderIdent: function(identifier) {
return '`'+ identifier +'`';
}
/**
* Renders a quoted SQL identifier.
*
* @param {String} identifier The identifier
* @return {string} The quoted identifier
*/
,renderPreIdent: function(identifier) {
if (identifier)
return this.renderIdent(identifier) +'.';
else
return '';
}
/**
* Renders the object if it's defined.
*
* @param {String} prefix The rendered string prefix
* @return {string} The rendered object with its prefix
*/
,renderIfSet: function(object, prefix, params) {
if (object)
return ' '+ prefix +' '+ object.render(params);
else
return '';
}
});

View File

@ -1,78 +1,96 @@
var Expr = require('./expr');
var Expr = require ('./expr');
var ListHolder = require ('./list-holder');
/**
* The equivalent of a SQL operation between exprs.
*
* @param {Array#Sql.Expr} expr Array with the exprs
* @param {Sql..Operation.Type} type The type of the operation
* @param {Array#Expr} exprs Array with the exprs
* @param {Type} type The type of the operation
*/
var Operation = new Class();
module.exports = Operation;
var Klass = new Class ();
module.exports = Klass;
var Type = {
var Type =
{
EQUAL : 0
,LIKE : 1
,AND : 2
,OR : 3
,REGEXP : 4
,LOWER : 5
,UPPER : 6
,LE : 7
,UE : 8
,PLUS : 9
,MINUS : 10
,MULT : 11
,DIV : 12
,NE : 13
,MOD : 14
};
var Operators = [
var Operators =
[
'='
,'LIKE'
,'AND'
,'OR'
,'REGEXP'
,'<'
,'>'
,'<='
,'>='
,'+'
,'-'
,'*'
,'/'
,'<>'
,'MOD'
];
Operation.extend({
Klass.extend
({
Type: Type
,Operators: Operators
});
Operation.implement({
Klass.implement
({
Extends: Expr
,Implements: ListHolder
,Tag: 'sql-operation'
,Properties: {
type: {
,Properties:
{
type:
{
enumType: Type
,value: -1
},
target:
{
type: String
,value: null
},
exprs:
{
type: Array
,set: function (x)
{
this.list = x;
}
,get: function ()
{
return this.list;
}
}
}
,initialize: function(props) {
this.parent(props);
this.link({exprs: new Sql.List()}, {'changed': this.onListChange});
}
,appendChild: function(child) {
this.exprs.add(child);
}
,onListChange: function() {
this.signalEmit('changed');
}
,isReady: function() {
return this.exprs.isReady();
}
,render: function(batch) {
var sql = '(';
,render: function (params)
{
var operator = ' '+ Operators[this.type] +' ';
var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++) {
if (i > 0)
sql += operator;
sql += e[i].render(batch);
}
sql += ')';
return sql;
return '('
+ this.renderListWs (this.list, params, operator)
+ ')';
}
});

View File

@ -1,19 +0,0 @@
var Value = require('./value');
/**
* The equivalent of a SQL value.
*/
module.exports = new Class
({
Extends: Value
,Tag: 'sql-search-tags'
,render: function(batch) {
if (typeof this._value == 'string') {
var value = this._value.replace(/^|\s+|$/g, '%');
return "'" + value.replace(this.regexp, this.replaceFunc) + "'";
} else
return this.parent();
}
});

View File

@ -16,22 +16,13 @@ module.exports = new Class
this.expr.push (new Field ({name: fieldName}));
}
,render: function (batch)
,render: function (params)
{
var sql = 'SELECT '
for (var i = 0; i < this.expr.length; i++)
{
if (i > 0)
sql += ', ';
sql += this.expr[i].render(batch);
}
sql += ' FROM ' + this.renderTarget (batch);
if (this.where)
sql += ' WHERE ' + this.where.render (batch);
return sql;
return 'SELECT '
+ this.renderListWs (this.expr, params, ', ')
+ ' FROM'
+ this.renderTarget (params)
+ this.renderIfSet (this.where, 'WHERE', params)
+ this.renderLimit (params);
}
});

View File

@ -1,28 +1,29 @@
require ('vn/vn');
require('vn/vn');
Sql = module.exports = {
Object : require ('./object')
,Holder : require ('./holder')
,Batch : require ('./batch')
,List : require ('./list')
,Expr : require ('./expr')
,Value : require ('./value')
,Field : require ('./field')
,Function : require ('./function')
,Operation : require ('./operation')
,Target : require ('./target')
,Table : require ('./table')
,Stmt : require ('./stmt')
,Dml : require ('./dml')
,String : require ('./string')
,Delete : require ('./delete')
,Insert : require ('./insert')
,Select : require ('./select')
,Update : require ('./update')
,MultiStmt : require ('./multi-stmt')
,Filter : require ('./filter')
,FilterItem : require ('./filter-item')
,SearchTags : require ('./search-tags')
Object : require('./object')
,Holder : require('./holder')
,List : require('./list')
,ListHolder : require('./list-holder')
,Expr : require('./expr')
,Value : require('./value')
,Field : require('./field')
,Function : require('./function')
,Operation : require('./operation')
,Target : require('./target')
,Table : require('./table')
,Join : require('./join')
,JoinItem : require('./join-item')
,Stmt : require('./stmt')
,Dml : require('./dml')
,String : require('./string')
,Delete : require('./delete')
,Insert : require('./insert')
,Select : require('./select')
,Update : require('./update')
,MultiStmt : require('./multi-stmt')
,Filter : require('./filter')
,FilterItem : require('./filter-item')
};

View File

@ -1,47 +1,40 @@
var Object = require ('./object');
var Expr = require ('./expr');
var Object = require('./object');
var Expr = require('./expr');
/**
* The equivalent of a SQL statement.
*/
module.exports = new Class
({
module.exports = new Class({
Extends: Object
,Properties:
{
where:
{
,Properties: {
where: {
type: Expr
,value: null
},
limit: {
type: Number
,value: null
}
}
,target: []
,addTarget: function (target)
{
this.target.push (target);
,addTarget: function(target) {
this.target.push(target);
}
,renderTarget: function (batch)
{
var sql;
var len = this.target.length;
if (len > 0)
{
sql = ' ';
for (var n = 0; n < len; n++)
{
if (n > 0) sql += ', ';
sql += this.target[n].render (batch);
}
}
,renderTarget: function(params) {
if (this.target.length > 0)
return ' '+ this.renderListWs(this.target, params, ', ');
else
sql += 'DUAL';
return sql;
}
return ' DUAL';
}
,renderLimit: function() {
if (this.limit != null)
return ' LIMIT '+ parseInt(this.limit);
else
return '';
}
});

View File

@ -8,6 +8,7 @@ var Holder = require ('./holder');
module.exports = new Class
({
Extends: Stmt
,Tag: 'sql-string'
,Properties:
{
query:
@ -18,19 +19,25 @@ module.exports = new Class
}
,regexp: /#\w+/g
,replaceFunc: function (batch, token)
,appendChild: function (child)
{
var holder = new Holder ({id: token.substr (1)});
return holder.render (batch);
if (child.nodeType === Node.TEXT_NODE)
this.query = child.textContent;
}
,render: function (batch)
,render: function (params)
{
if (!this.query)
return null;
function replaceFunc (token)
{
var holder = new Holder ({id: token.substr (1)});
return holder.render (params);
}
return this.query.replace (this.regexp, this.replaceFunc.bind (this, batch));
return this.query.replace (this.regexp, replaceFunc);
}
,findHolders: function ()

View File

@ -1,5 +1,5 @@
var Target = require('./target');
var Target = require ('./target');
/**
* Represents a database table.
@ -14,6 +14,11 @@ module.exports = new Class
type: String
,value: null
},
alias:
{
type: String
,value: null
},
schema:
{
type: String
@ -21,9 +26,14 @@ module.exports = new Class
}
}
,render: function(batch) {
var sql = this.schema ? '`' + this.schema + '`.' : '';
sql += '`' + this.name + '`';
,render: function ()
{
var sql = this.renderPreIdent (this.schema)
+ this.renderIdent (this.name);
if (this.alias)
sql += ' AS '+ this.renderIdent (this.alias);
return sql;
}
});

View File

@ -1,5 +1,5 @@
var Object = require('./object');
var Object = require ('./object');
/**
* The equivalent of a SQL target.

View File

@ -8,25 +8,23 @@ module.exports = new Class
({
Extends: Dml
,render: function (batch)
,render: function (params)
{
var sql;
var n;
var sql = 'UPDATE'
+ this.renderTarget (params)
+ ' SET ';
sql = 'UPDATE ' + this.renderTarget (batch) + ' SET ';
for (n = 0; n < this.field.length; n++)
{
if (n > 0)
this.field.forEach (function (field, i) {
if (i > 0)
sql += ', ';
sql += this.field[n].render () + ' = ' + this.expr[n].render(batch);
}
sql += field.render (params)
+ ' = '
+ this.expr[i].render(params);
}, this);
if (this.where)
sql += ' WHERE ' + this.where.render (batch);
sql += ' LIMIT 1'; // Only for security.
sql += this.renderIfSet (this.where, 'WHERE', params)
+ this.renderLimit(params);
return sql;
}
});

View File

@ -5,64 +5,69 @@ var Expr = require('./expr');
* The equivalent of a SQL value.
*/
module.exports = new Class({
Extends: Expr
,Tag: 'sql-value'
Extends: Expr
,Implements: Vn.ParamIface
,Tag: 'sql-value'
,Properties: {
/**
* The master param.
*/
param: {
type: Vn.Param
value: {
type: null
,set: function(x) {
this.link({_param: x}, {'changed': this.onParamChange});
this.onParamChange();
this._setValue(x);
}
,get: function() {
return this._value;
}
},
type: {
type: Type
,set: function(x) {
this._setType(x);
}
,get: function() {
return this._type;
}
},
param: {
type: Vn.ParamIface
,set: function(x) {
this._setParam(x);
}
,get: function() {
return this._param;
}
},
/**
* The value.
*/
value: {
type: String
lot: {
type: Vn.LotIface
,set: function(x) {
if (Vn.Value.compare(x, this._value))
return;
if (x instanceof Date)
x = x.clone();
this._value = x;
if (this._param && !this.paramLock) {
this.paramLock = true;
this._param.value = x;
this.paramLock = false;
}
this.signalEmit('changed');
this._setLot(x);
}
,get: function() {
return this._value;
return this._lot;
}
},
name: {
type: String
,set: function(x) {
this._name = x;
this._onLotChange();
}
,get: function() {
return this._name;
}
},
oneWay: {
type: Boolean
,set: function(x) {
this._oneWay = x;
}
,get: function() {
return this._oneWay;
}
}
}
,_value: undefined
,_param: null
,regexp: new RegExp('(\\\\)|\'', 'g')
,paramLock: false
,onParamChange: function() {
if (this.paramLock || !this._param)
return;
this.paramLock = true;
this.value = this._param.value;
this.paramLock = false;
}
,isReady: function() {
return this._value !== undefined;

View File

@ -1,36 +1,29 @@
module.exports =
{
getPageYOffset: function ()
{
module.exports = {
getPageYOffset: function() {
return window.pageYOffset;
},
getPageXOffset: function ()
{
getPageXOffset: function() {
return window.pageXOffset;
},
getInnerHeight: function ()
{
getInnerHeight: function() {
return window.innerHeight;
},
getInnerWidth: function ()
{
getInnerWidth: function() {
return window.innerWidth;
},
createRadio: function (uid, doc)
{
var radio = doc.createElement ('input');
createRadio: function(uid, doc) {
var radio = doc.createElement('input');
radio.type = 'radio';
radio.name = uid;
return radio;
},
setInputTypeNumber: function (input)
{
setInputTypeNumber: function(input) {
input.type = 'number';
}
};

View File

@ -2,6 +2,7 @@ const VnObject = require('./object');
const Widget = require('../htk/widget');
const VnNode = require('./node');
const Scope = require('./scope');
const Type = require('./type');
const kebabToCamel = require('./string-util').kebabToCamel;
/**
@ -488,6 +489,9 @@ module.exports = new Class({
case Function:
context.funcProps[propName] = this._getMethod(value);
break;
case Type:
newValue = window[value];
break;
default:
if (propInfo.enumType)
newValue = propInfo.enumType[value];

View File

@ -8,8 +8,7 @@ Date.prototype.clone = function() {
module.exports =
{
WDays:
[
WDays: [
'Sunday'
,'Monday'
,'Tuesday'
@ -18,8 +17,7 @@ module.exports =
,'Friday'
,'Saturday'
]
,AbrWDays:
[
,AbrWDays: [
'Su'
,'Mo'
,'Tu'
@ -28,8 +26,7 @@ module.exports =
,'Fr'
,'Sa'
]
,Months:
[
,Months: [
'January'
,'February'
,'March'
@ -43,8 +40,7 @@ module.exports =
,'November'
,'December'
]
,AbrMonths:
[
,AbrMonths: [
'Jan'
,'Feb'
,'Mar'

4
js/vn/enum.js Normal file
View File

@ -0,0 +1,4 @@
/**
* Base type for ennumerations.
*/
module.exports = function() {};

72
js/vn/form.js Normal file
View File

@ -0,0 +1,72 @@
var Iterator = require('./iterator');
var ModelIface = require('./model-iface');
module.exports = new Class({
Extends: Iterator
,Tag: 'db-form'
,Properties: {
model: {
type: ModelIface
,set: function(x) {
this.link({_model: x},
{
'status-changed': this.onModelChange
,'row-updated': this.onModelRowUpdate
});
}
,get: function() {
return this._model;
}
},
/**
* The row where the form positioned, has -1 if the row is unselected.
*/
row: {
type: Number
,set: function(x) {
if (!this._model || this._model.numRows <= x || x < -1)
x = -1;
if (x == this._row)
return;
this._row = x;
this.rowChanged();
}
,get: function() {
return this._row;
}
}
}
,initialize: function(props) {
Object.assign(this, {
_lastRow: 0
,_lastReady: false
});
this.parent(props);
}
,onModelChange: function() {
var ready = this._model && this._model.ready;
if (ready != this._lastReady) {
if (this._row != -1)
this._lastRow = this._row;
this._lastReady = ready;
this.emit('status-changed');
if (this._row == -1)
this.row = this._lastRow;
if (ready)
this.emit('ready');
}
}
,onModelRowUpdate: function(model, row) {
if (row == this._row)
this.rowChanged();
}
});

View File

@ -1,14 +0,0 @@
var Object = require('./object');
/**
* Class to handle the URL.
*/
module.exports = new Class
({
Extends: Object
,changed: function() {
this.signalEmit('changed');
}
});

View File

@ -1,127 +0,0 @@
var Object = require('./object');
var Param = require('./param');
var Hash = require('./hash');
module.exports = new Class({
Extends: Object
,Tag: 'vn-hash-param'
,Child: 'param'
,Properties: {
param: {
type: Param
,set: function(x) {
this.link({_param: x}, {'changed': this._onParamChange});
this._refreshParam();
}
,get: function() {
return this._param;
}
},
key: {
type: String
,set: function(x) {
this._key = x;
this._onHashChange();
}
,get: function() {
return this._key;
}
},
value: {
type: Object
,set: function(x) {
this._setValue(x, true);
}
,get: function() {
return this._value;
}
},
type: {
type: Object
,set: function(x) {
this._type = x;
this._onHashChange();
}
,get: function() {
return this._type;
}
}
}
,_hashLock: false
,_paramLock: false
,_value: undefined
,_key: null
,_type: null
,initialize: function(props) {
this.parent(props);
var listener = Hash.getListener();
this.link({_listener: listener}, {'changed': this._onHashChange});
this._onHashChange();
}
,_onHashChange: function() {
if (this._hashLock || !this._key || !this._listener)
return;
var newValue = Hash.get(this._key);
if (newValue === '')
newValue = null;
if (this._type && newValue !== undefined && newValue !== null)
switch (this._type) {
case Boolean:
newValue = (/^(true|1)$/i).test(newValue);
break;
case Number:
newValue = 0 + new Number(newValue);
break;
}
this._hashLock = true;
this._setValue(newValue, true);
this._hashLock = false;
}
,_setValue: function(newValue, signal) {
if (newValue == this._value)
return;
this._value = newValue;
if (this._key && !this._hashLock) {
this._hashLock = true;
var map = {};
map[this._key] = newValue;
Hash.add(map);
this._hashLock = false;
}
this._refreshParam();
if (signal)
this.signalEmit('changed', newValue);
}
,_refreshParam: function() {
if (this._param && !this._paramLock) {
this._paramLock = true;
this._param.value = this._value;
this._paramLock = false;
}
}
,_onParamChange: function() {
if (this._paramLock)
return;
this._paramLock = true;
this._setValue(this._param.value);
this._paramLock = false;
}
});

View File

@ -1,137 +1,164 @@
var HashListener = require('./hash-listener');
var VnDate = require('./date');
var Lot = require('./lot');
/**
* Class to handle the URL.
* Class to handle the hash part of the URL as a key-value javascript object.
* It also handles dates and objects as a value.
*/
module.exports = {
path: null
,_hash: null
,_hashMap: {}
,_listener: null
,initialize: function() {
this.$ = this._hasMap;
this._listener = new HashListener();
this._hashChangedHandler = this._hashChanged.bind(this);
window.addEventListener('hashchange', this._hashChangedHandler);
this._hashChanged();
}
,destroy: function() {
window.removeEventListener('hashchange', this._hashChangedHandler);
}
,getListener: function() {
return this._listener;
}
/**
* Gets the hash part of the URL.
*
* @param {string} key The variable name
*/
,get: function(key) {
return this._hashMap[key];
}
/**
* Unsets a hash key.
*
* @param {string} key The variable name
*/
,unset: function(key) {
this.add({[key]: undefined});
}
/**
* Sets the hash part of the URL, respecting the current hash variables.
*
* @param {Object} map A key-value map
*/
,add: function(map) {
var newMap = this._hashMap;
for (var key in map)
newMap[key] = map[key];
this.set(newMap);
}
/**
* Sets the hash part of the URL.
*
* @param {Object} map A key-value map
*/
,set: function(map) {
if (map)
for (var key in map)
if (map[key] === null || map[key] === undefined)
delete map[key];
var newHash = this.make(map);
if (!map)
map = {};
if (newHash !== this._hash) {
this._hashMap = map;
this.$ = map;
this._hash = newHash;
this._blockChanged = true;
location.hash = newHash;
this._blockChanged = false;
this._listener.changed();
module.exports = new Class({
Extends: Lot
,Properties: {
/**
* The main window object.
*/
window:
{
type: Window
,set: function(x) {
this._window = x;
x.addEventListener('hashchange', this._hashChangedHandler);
this._hashChanged();
}
,get: function() {
return this._window;
}
}
}
,initialize: function(props) {
Object.assign(this, {
_hash: null
,_hashLock: false
,_window: null
,_hashChangedHandler: this._hashChanged.bind(this)
});
this.parent(props);
}
,_paramsChanged: function() {
this.updateHash();
}
/**
* Creates a URL with the given hash data.
*
* @param {Object} map A key-value map
* @param {boolean} add %true to combine with the current map, %false otherwise
* @return {String} The URL
* @param {Object} params A key-value object
* @param {boolean} add %true to combine with the current params, %false otherwise
* @return {string} The URL
*/
,make: function(map, add) {
var hash = '#!';
if (add && map)
for (var key in this._hashMap)
if (!map[key])
map[key] = this._hashMap[key];
,make: function(params, add) {
if (add) {
params = Object.assign({}, params);
for (var key in map) {
for (var key in this._params)
if (!params[key])
params[key] = this._params[key];
}
return this.renderHash(params);
}
/**
* Updates the window hash with current params.
*/
,updateHash: function() {
if (this._hashLock)
return;
this._hash = this.renderHash(this._params);
this._hashLock = true;
location.hash = this._hash;
this._hashLock = false;
}
/*
* Called when window hash changes.
*/
,_hashChanged: function() {
var newHash = location.hash;
if (this._hashLock || this._hash === newHash)
return;
this._hash = newHash;
this._hashLock = true;
this.params = this.parseHash(newHash);
this._hashLock = false;
}
/**
* Creates a URL with the given hash data.
*
* @param {Object} params The key-value object
* @return {string} The URL
*/
,renderHash: function(params) {
var hash = '#!';
for (var key in params)
if (params[key] !== undefined) {
if (hash.length > 2)
hash += '&';
hash += encodeURIComponent(key) +'='+ encodeURIComponent(map[key]);
hash += encodeURIComponent(key) +'='+ this.renderValue(params[key]);
}
return hash;
}
,_hashChanged: function() {
var newHash = location.hash;
if (this._blockChanged || newHash === this._hash)
return;
/**
* Parses a hash string to a key-value object.
*
* @param {string} hashString The hash string
* @return {Object} The key-value object
*/
,parseHash: function(hashString) {
var newMap = hashMap = {};
var kvPairs = newHash.substring(2).split('&');
var kvPairs = hashString.substr(2).split('&');
for (var i = 0; i < kvPairs.length; i++) {
var kvPair = kvPairs[i].split('=', 2);
if (kvPair[0])
newMap[decodeURIComponent(kvPair[0])] = decodeURIComponent(kvPair[1]);
newMap[decodeURIComponent(kvPair[0])] = this.parseValue(kvPair[1]);
}
this._hashMap = newMap;
this.$ = newMap;
this._hash = newHash;
this._listener.changed();
return newMap;
}
};
,renderValue: function(v) {
if (v == null)
return '';
switch (typeof v) {
case 'object':
if (v instanceof Date)
return VnDate.strftime(v, '%Y-%m-%d');
else
return JSON.stringify(v)
}
return v;
}
,parseValue: function(v) {
if (v == null)
return v;
v = decodeURIComponent(v);
if (v === '')
return null;
return v;
}
,_destroy: function() {
this._window.removeEventListener('hashchange', this._hashChangedHandler);
this._window = null;
this.parent();
}
});

View File

@ -1,48 +1,40 @@
module.exports =
{
getPageYOffset: function ()
{
module.exports = {
getPageYOffset: function() {
if (document.documentElement.scrollTop)
return document.documentElement.scrollTop;
else
return document.body.scrollTop;
},
getPageXOffset: function ()
{
getPageXOffset: function() {
if (document.documentElement.scrollLeft)
return document.documentElement.scrollLeft;
else
return document.body.scrollLeft;
},
getInnerHeight: function ()
{
getInnerHeight: function() {
if (document.documentElement.clientHeight)
return document.documentElement.clientHeight;
else
return document.body.clientHeight;
},
getInnerWidth: function ()
{
getInnerWidth: function() {
if (document.documentElement.clientWidth)
return document.documentElement.clientWidth;
else
return document.body.clientWidth;
},
createRadio: function (radioName)
{
createRadio: function(radioName) {
var radio;
try {
radio = document.createElement ('<input type="radio" name="' + radioName + '">');
}
catch (e)
{
radio = document.createElement ('input');
radio = document.createElement('<input type="radio" name="' + radioName + '">');
} catch (e) {
radio = document.createElement('input');
radio.type = 'radio';
radio.name = radioName;
}
@ -50,30 +42,26 @@ module.exports =
return radio;
},
setInputTypeNumber: function (input)
{
setInputTypeNumber: function(input) {
input.type = 'text';
}
};
if (!Function.bind)
{
Function.prototype.bind = function ()
{
if (!Function.bind) {
Function.prototype.bind = function() {
var bindFunc = this;
var bindThis = arguments[0];
var bindArgs = arguments;
var IE_bind = function ()
{
var args = new Array ();
var IE_bind = function() {
var args = new Array();
for (var i = 1; i < bindArgs.length; i++)
args.push (bindArgs[i]);
args.push(bindArgs[i]);
for (var i = 0; i < arguments.length; i++)
args.push (arguments[i]);
args.push(arguments[i]);
bindFunc.apply (bindThis, args);
bindFunc.apply(bindThis, args);
}
return IE_bind;
@ -82,33 +70,28 @@ if (!Function.bind)
// attachEvent -> addEventListener
if (window.attachEvent && !window.addEventListener)
{
function IE_addEventListener (signal, func, capture)
{
if (window.attachEvent && !window.addEventListener) {
function IE_addEventListener(signal, func, capture) {
var obj = this;
func.IE_eventHandler = function (event)
{
func.IE_eventHandler = function(event) {
event.target = event.srcElement;
event.layerY = event.clientY;
event.layerX = event.clientX;
event.pageX = event.offsetX;
event.pageY = event.offsetY;
event.stopPropagation = function ()
{
event.stopPropagation = function() {
this.cancelBubble = true;
}
func.call (obj, event);
func.call(obj, event);
}
this.attachEvent ('on' + signal, func.IE_eventHandler);
this.attachEvent('on' + signal, func.IE_eventHandler);
}
function IE_removeEventListener (signal, func, capture)
{
this.detachEvent ('on' + signal, func.IE_eventHandler);
function IE_removeEventListener(signal, func, capture) {
this.detachEvent('on' + signal, func.IE_eventHandler);
}
window.addEventListener = IE_addEventListener;
@ -118,9 +101,8 @@ if (window.attachEvent && !window.addEventListener)
var IE_createElement = document.createElement;
document.createElement = function (tagName)
{
var node = IE_createElement (tagName);
document.createElement = function(tagName) {
var node = IE_createElement(tagName);
node.addEventListener = IE_addEventListener;
node.removeEventListener = IE_removeEventListener;
return node;
@ -129,11 +111,9 @@ if (window.attachEvent && !window.addEventListener)
// ActiveXObject ('Microsoft.XMLHTTP') -> XMLHttpRequest
if (!window.XMLHttpRequest && window.ActiveXObject)
{
function XMLHttpRequest ()
{
return new ActiveXObject ('Microsoft.XMLHTTP');
if (!window.XMLHttpRequest && window.ActiveXObject) {
function XMLHttpRequest() {
return new ActiveXObject('Microsoft.XMLHTTP');
}
}

67
js/vn/iterator-iface.js Normal file
View File

@ -0,0 +1,67 @@
var LotIface = require('./lot-iface');
var ModelIface = require('./model-iface');
module.exports = new Class({
Implements: LotIface
,Properties: {
/**
* The model associated to this form.
*/
model: {
type: ModelIface
},
/**
* The row where the form positioned, has -1 if the row is unselected.
*/
row: {
type: Number
},
/**
* The number of rows in the form.
*/
numRows: {
type: Number
},
/**
* Checks if the form data is ready.
*/
ready: {
type: Boolean
}
}
,insertRow: function() {
if (this._model)
this.row = this._model.insertRow();
}
/**
* Removes the current row.
*/
,deleteRow: function() {
if (this._row >= 0)
this._model.deleteRow(this._row);
}
/**
* Gets a value from the form.
*
* @param {string} columnName The column name
* @return {Object} The value
*/
,get: function(columnName) {
return this._model ?
this._model.get(this._row, columnName) : undefined;
}
/**
* Sets a value on the form.
*
* @param {string} columnName The column name
* @param {Object} value The new value
*/
,set: function(columnName, value) {
this._model.set(this._row, columnName, value);
}
});

75
js/vn/iterator.js Normal file
View File

@ -0,0 +1,75 @@
var Lot = require('./lot');
var IteratorIface = require('./iterator-iface');
var ModelIface = require('./model-iface');
/**
* A light iterator for models. It assumes that its row and model properties
* are always valid.
*/
module.exports = new Class({
Extends: Lot
,Implements: IteratorIface
,Properties: {
model: {
type: ModelIface
,set: function(x) {
this._model = x;
}
,get: function() {
return this._model;
}
},
row: {
type: Number
,set: function(x) {
this._row = x;
this.rowChanged();
}
,get: function() {
return this._row;
}
},
numRows: {
type: Number
,get: function() {
return this._model ?
this._model.numRows : 0;
}
},
ready: {
type: Boolean
,get: function() {
return this._model ?
this._model.ready : false;
}
}
}
,_model: null
,initialize: function(props) {
Object.assign(this, {
_row: -1
,_rowLock: false
});
this.parent(props);
}
,_paramsChanged: function(diff) {
if (!this._rowLock)
for (var key in diff)
this._model.set(this._row, key, diff[key]);
}
,rowChanged: function() {
var row;
if (this._model)
row = this._model.getObject(this._row);
this._rowLock = true;
this.params = row != null ? row : {};
this._rowLock = false;
}
});

View File

@ -70,7 +70,7 @@ module.exports = new Class({
var storage = remember ? localStorage : sessionStorage;
storage.setItem('vnToken', this.token);
this.signalEmit('openned');
this.emit('openned');
} else
this._closeClient();
@ -93,7 +93,7 @@ module.exports = new Class({
* Called when close operation is done.
*/
,_onClose: function(callback, json, error) {
this.signalEmit('closed');
this.emit('closed');
if (callback)
callback(this, null, error);
@ -221,7 +221,7 @@ module.exports = new Class({
this._requestsCount++;
if (this._requestsCount === 1)
this.signalEmit('loading-changed', true);
this.emit('loading-changed', true);
}
,_onStateChange: function(request, callback) {
@ -231,7 +231,7 @@ module.exports = new Class({
this._requestsCount--;
if (this._requestsCount === 0)
this.signalEmit('loading-changed', false);
this.emit('loading-changed', false);
var data = null;
var error = null;
@ -314,7 +314,7 @@ module.exports = new Class({
if (error.exception == 'SessionExpired')
this.clearToken();
this.signalEmit('error', error);
this.emit('error', error);
}
}
});

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