Catalog filter, builder ids
gitea/hedera-web/pipeline/head This commit looks good Details

This commit is contained in:
Juan Ferrer 2022-05-28 21:27:36 +02:00
parent 0141eea534
commit 3de2c2f9fe
22 changed files with 475 additions and 484 deletions

2
debian/changelog vendored
View File

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

View File

@ -25,7 +25,7 @@ Hedera.Catalog = new Class({
,activate: function() { ,activate: function() {
document.body.appendChild(this.$.rightPanel); document.body.appendChild(this.$.rightPanel);
this.$.itemsModel.setInfo('i', 'item', 'vn', ['id']); this.$.items.setInfo('i', 'item', 'vn', ['id']);
if (localStorage.getItem('hederaView')) if (localStorage.getItem('hederaView'))
this.setView(parseInt(localStorage.getItem('hederaView'))); this.setView(parseInt(localStorage.getItem('hederaView')));
@ -39,6 +39,103 @@ Hedera.Catalog = new Class({
Vn.Node.remove(this.$.rightPanel); Vn.Node.remove(this.$.rightPanel);
} }
,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;
if (lot.search != null || lot.type != null) {
const filter = new Sql.Operation({
type: Sql.Operation.Type.AND
});
const exprs = filter.exprs;
let idSearch = false;
if (lot.search != null) {
idSearch = /^\d+$/.test(lot.search);
exprs.add(idSearch ? $.idOp : $.nameOp);
}
if (!idSearch) {
if (lot.realm != null)
exprs.add($.realmOp);
if (lot.type != null)
exprs.add($.typeOp);
const tags = [
'color',
'origin',
'category',
'producer'
];
for (const tag of tags)
if (lot[tag] != null)
exprs.add($[`${tag}Op`]);
}
const batch = new Sql.Batch();
batch.addObject('filter', filter);
batch.block();
$.items.batch = batch;
} else
$.items.batch = null;
}
,onRealmChange: function() {
const hasRealm = this.$.realm.value != null;
this.$.filters.style.display = hasRealm ? 'block' : 'none';
this.$.realmMsg.style.display = hasRealm ? 'none' : 'block';
this.onFilterChange();
this.refreshTitle();
}
,onTypeChange: function() {
this.onFilterChange();
this.refreshTitle();
}
,refreshTitle: function() {
const types = this.$.types;
const realms = this.$.realms;
const type = this.$.type.value;
const realm = this.$.realm.value;
let typeName;
let realmName;
if (type && types.ready) {
var row = types.search('id', type);
if (row != -1) typeName = types.get(row, 'name');
}
if (realm && realms.ready) {
var row = realms.search('id', realm);
if (row != -1) realmName = realms.get(row, 'name');
}
let title = _('Catalog');
let subtitle = '';
if (typeName) {
title = typeName;
subtitle = realmName;
} else if (realmName) {
title = realmName;
}
Vn.Node.setText(this.$.titleText, title);
Vn.Node.setText(this.$.subtitle, subtitle);
}
,setView: function(view) { ,setView: function(view) {
if (view === Hedera.Catalog.View.GRID) { if (view === Hedera.Catalog.View.GRID) {
this.$.viewButton.setProperties({ this.$.viewButton.setProperties({
@ -87,16 +184,11 @@ Hedera.Catalog = new Class({
Db.Model.SortWay.ASC : Db.Model.SortWay.DESC; Db.Model.SortWay.ASC : Db.Model.SortWay.DESC;
if (sortField) if (sortField)
this.$.itemsModel.sortByName(sortField, sortWay); this.$.items.sortByName(sortField, sortWay);
this.hideMenu(); this.hideMenu();
} }
,onFilterChange: function(param, newValue) {
if (newValue)
this.hideMenu();
}
,realmRenderer: function(builder, form) { ,realmRenderer: function(builder, form) {
var link = builder.$.link; var link = builder.$.link;
link.href = this.hash.make({ link.href = this.hash.make({
@ -105,57 +197,6 @@ Hedera.Catalog = new Class({
}); });
} }
,onRealmChange: function(param, newValue) {
if (newValue) {
this.$.filters.style.display = 'block';
this.$.realmMsg.style.display = 'none';
} else {
this.$.filters.style.display = 'none';
this.$.realmMsg.style.display = 'block';
}
this.refreshFilter(newValue, undefined);
}
,onTypeChange: function(param, newValue) {
this.onFilterChange(param, newValue);
this.refreshTitle();
this.refreshFilter(undefined, newValue);
}
,refreshFilter: function(realm, type) {
var batch = this.$.filterBatch;
batch.block();
this.$.realmValue.value = realm;
this.$.typeValue.value = type;
this.$.search.value = undefined;
this.$.color.value = undefined;
this.$.origin.value = undefined;
this.$.category.value = undefined;
this.$.producer.value = undefined;
batch.unblock();
batch.changed();
}
,refreshTitle: function() {
var types = this.$.typesModel;
if (!types.ready)
return;
var title = _('Catalog');
var type = this.$.type.value;
if (type) {
var row = types.search('id', type);
if (row != -1)
title = types.get(row, 'name');
}
Vn.Node.setText(this.$.titleText, title);
}
,onRightPanelClick: function(event) { ,onRightPanelClick: function(event) {
event.stopPropagation(); event.stopPropagation();
} }

View File

@ -1,6 +1,10 @@
.catalog { .catalog {
margin-right: 18em; margin-right: 18em;
} }
.title ._subtitle {
font-size: .7rem;
color: #bbb;
}
/* Right panel */ /* Right panel */
@ -177,7 +181,16 @@
.item-info > .htk-button > img { .item-info > .htk-button > img {
vertical-align: middle; vertical-align: middle;
} }
.item-info .item-id {
float: right;
font-size: .8rem;
line-height: 1.8em;
color: #777;
}
.item-info .available-price { .item-info .available-price {
position: absolute;
bottom: 0;
right: 0;
white-space: nowrap; white-space: nowrap;
font-size: .95em; font-size: .95em;
text-align: right; text-align: right;
@ -251,11 +264,6 @@
flex: auto; flex: auto;
overflow: hidden; overflow: hidden;
} }
.grid-view .item-info .available-price {
position: absolute;
bottom: 0;
right: 0;
}
.grid-view .item-info .tags td { .grid-view .item-info .tags td {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
@ -305,13 +313,6 @@
.list-view .item-info > .htk-button { .list-view .item-info > .htk-button {
float: right; float: right;
} }
.list-view .item-info .available-price {
clear: both;
float: right;
position:absolute;
bottom: 0;
right: 0;
}
.list-view .item-info .tags { .list-view .item-info .tags {
display: block; display: block;
text-overflow: ellipsis; text-overflow: ellipsis;

View File

@ -1,45 +1,91 @@
<vn> <vn>
<div id="title">
<h1 id="title-text"><t>Catalog</t></h1>
<div id="subtitle"></div>
</div>
<div id="actions" class="catalog-actions">
<htk-search-entry
param="search"/>
<htk-bar-button
id="view-button"
tip="_Switch view"
icon="view_list"
on-click="this.onSwitchViewClick()"/>
<htk-bar-button
icon="shopping_cart_checkout"
tip="_ShoppingBasket"
on-click="this.onBasketClick()"/>
<button
class="menu"
on-click="onShowMenuClick">
<htk-icon name="menu" alt="_Menu"/>
</button>
</div>
<vn-group> <vn-group>
<vn-param id="card-item"/>
<vn-param id="realm" on-changed="onRealmChange"/>
<vn-param id="type" on-changed="onTypeChange"/>
<vn-param id="search" on-changed="onFilterChange"/>
<vn-param id="color" on-changed="onFilterChange"/>
<vn-param id="origin" on-changed="onFilterChange"/>
<vn-param id="category" on-changed="onFilterChange"/>
<vn-param id="producer" on-changed="onFilterChange"/>
<vn-hash-param key="realm" param="realm"/> <vn-hash-param key="realm" param="realm"/>
<vn-hash-param key="type" param="type"/> <vn-hash-param key="type" param="type"/>
<sql-filter type="AND" id="filter"> </vn-group>
<sql-filter-item type="EQUAL" primary="false" id="op-realm"> <vn-group>
<sql-field target="t" name="categoryFk"/> <vn-param id="card-item"/>
<sql-value id="realm-value"/> <vn-param id="search" on-changed="this.onFilterChange()"/>
</sql-filter-item> <vn-param id="realm" on-changed="this.onRealmChange()"/>
<sql-filter-item type="EQUAL" id="op-type"> <vn-param id="type" on-changed="this.onTypeChange()"/>
<sql-field target="i" name="typeFk"/> <vn-param id="color" on-changed="this.onFilterChange()"/>
<sql-value id="type-value"/> <vn-param id="origin" on-changed="this.onFilterChange()"/>
</sql-filter-item> <vn-param id="category" on-changed="this.onFilterChange()"/>
<sql-filter-item type="LIKE" id="op-name"> <vn-param id="producer" on-changed="this.onFilterChange()"/>
</vn-group>
<vn-group>
<sql-operation
id="id-op"
type="EQUAL">
<sql-field target="i" name="id"/>
<sql-value param="search"/>
</sql-operation>
<sql-operation
id="name-op"
type="LIKE">
<sql-field target="i" name="longName"/> <sql-field target="i" name="longName"/>
<sql-search-tags param="search"/> <sql-search-tags param="search"/>
</sql-filter-item> </sql-operation>
<sql-filter-item type="EQUAL" id="op-color"> <sql-operation
id="realm-op"
type="EQUAL">
<sql-field target="t" name="categoryFk"/>
<sql-value param="realm"/>
</sql-operation>
<sql-operation
id="type-op"
type="EQUAL">
<sql-field target="i" name="typeFk"/>
<sql-value param="type"/>
</sql-operation>
<sql-operation
id="color-op"
type="EQUAL">
<sql-field target="i" name="inkFk"/> <sql-field target="i" name="inkFk"/>
<sql-value param="color"/> <sql-value param="color"/>
</sql-filter-item> </sql-operation>
<sql-filter-item type="EQUAL" id="op-origin"> <sql-operation
type="EQUAL"
id="origin-op">
<sql-field target="i" name="originFk"/> <sql-field target="i" name="originFk"/>
<sql-value param="origin"/> <sql-value param="origin"/>
</sql-filter-item> </sql-operation>
<sql-filter-item type="EQUAL" id="op-category"> <sql-operation
type="EQUAL"
id="category-op">
<sql-field target="i" name="category"/> <sql-field target="i" name="category"/>
<sql-value param="category"/> <sql-value param="category"/>
</sql-filter-item> </sql-operation>
<sql-filter-item type="EQUAL" id="op-producer"> <sql-operation
id="producer-op"
type="EQUAL">
<sql-field target="i" name="producerFk"/> <sql-field target="i" name="producerFk"/>
<sql-value param="producer"/> <sql-value param="producer"/>
</sql-filter-item> </sql-operation>
</sql-filter> </vn-group>
<vn-group>
<db-form id="basket" on-ready="onBasketReady"> <db-form id="basket" on-ready="onBasketReady">
<db-model property="model"> <db-model property="model">
SELECT b.id, b.sent, a.description agency, m.code method SELECT b.id, b.sent, a.description agency, m.code method
@ -49,7 +95,7 @@
</db-model> </db-model>
</db-form> </db-form>
<db-model <db-model
id="items-model" id="items"
result-index="2" result-index="2"
on-status-changed="onItemsChange"> on-status-changed="onItemsChange">
CREATE TEMPORARY TABLE tmp.item CREATE TEMPORARY TABLE tmp.item
@ -77,47 +123,21 @@
WHERE b.available > 0 WHERE b.available > 0
ORDER BY i.relevancy DESC, i.name, i.size ORDER BY i.relevancy DESC, i.name, i.size
LIMIT 5000; LIMIT 5000;
<sql-batch property="batch" id="filter-batch">
<custom>
<item name="filter" object="filter"/>
</custom>
</sql-batch>
</db-model> </db-model>
<db-form id="card" model="items-model"/> <db-form id="card" model="items"/>
<sql-batch id="card-batch"> <sql-batch id="card-batch">
<custom> <custom>
<item name="item" param="card-item"/> <item name="item" param="card-item"/>
</custom> </custom>
</sql-batch> </sql-batch>
</vn-group> </vn-group>
<div id="title">
<h1 id="title-text"><t>Catalog</t></h1>
</div>
<div id="actions" class="catalog-actions">
<htk-search-entry
param="search"/>
<htk-bar-button
id="view-button"
tip="_Switch view"
icon="view_list"
on-click="this.onSwitchViewClick()"/>
<htk-bar-button
icon="shopping_cart_checkout"
tip="_ShoppingBasket"
on-click="this.onBasketClick()"/>
<button
class="menu"
on-click="onShowMenuClick">
<htk-icon name="menu" alt="_Menu"/>
</button>
</div>
<div id="form" class="catalog"> <div id="form" class="catalog">
<div id="main" class="main"> <div id="main" class="main">
<htk-repeater <htk-repeater
id="grid-view" id="grid-view"
empty-message="_Choose filter from right menu" empty-message="_Choose filter from right menu"
form-id="item" form-id="item"
model="items-model" > model="items" >
<custom> <custom>
<div <div
id="item-box" id="item-box"
@ -134,6 +154,9 @@
title="_Zoom image"/> title="_Zoom image"/>
<div class="item-info"> <div class="item-info">
<h2> <h2>
<span class="item-id">
#{{item.id}}
</span>
{{item.item}} {{item.item}}
</h2> </h2>
<p class="sub-name"> <p class="sub-name">
@ -187,13 +210,13 @@
<div class="categories"> <div class="categories">
<div class="realms"> <div class="realms">
<htk-repeater <htk-repeater
model="realms-model"
form-id="form" form-id="form"
renderer="realmRenderer" renderer="realmRenderer"
class="realms-box"> class="realms-box">
<db-model <db-model
id="realms-model" id="realms"
property="model"> property="model"
on-status-changed="refreshTitle">
SELECT c.id, l.name, c.color, c.code SELECT c.id, l.name, c.color, c.code
FROM vn.itemCategory c FROM vn.itemCategory c
JOIN vn.itemCategoryL10n l ON l.id = c.id JOIN vn.itemCategoryL10n l ON l.id = c.id
@ -220,9 +243,10 @@
<h2><t>Filter by</t></h2> <h2><t>Filter by</t></h2>
<vn-filter <vn-filter
placeholder="_Family" placeholder="_Family"
param="type"> param="type"
id="type-filter">
<db-model <db-model
id="types-model" id="types"
property="model" property="model"
conn="conn" conn="conn"
result-index="1" result-index="1"
@ -245,7 +269,8 @@
</vn-filter> </vn-filter>
<vn-filter <vn-filter
placeholder="_Color" placeholder="_Color"
param="color"> param="color"
id="color-filter">
<db-model property="model" auto-load="false" result-index="1"> <db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable; CALL myBasket_getAvailable;
SELECT DISTINCT l.id, l.name SELECT DISTINCT l.id, l.name
@ -256,18 +281,11 @@
WHERE #filter WHERE #filter
ORDER BY name ORDER BY name
</db-model> </db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter> </vn-filter>
<vn-filter <vn-filter
placeholder="_Producer" placeholder="_Producer"
param="producer"> param="producer"
id="producer-filter">
<db-model property="model" auto-load="false" result-index="1"> <db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable; CALL myBasket_getAvailable;
SELECT DISTINCT p.id, p.name SELECT DISTINCT p.id, p.name
@ -278,18 +296,11 @@
WHERE #filter WHERE #filter
ORDER BY name ORDER BY name
</db-model> </db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-origin"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
</sql-filter>
</vn-filter> </vn-filter>
<vn-filter <vn-filter
placeholder="_Origin" placeholder="_Origin"
param="origin"> param="origin"
id="origin-filter">
<db-model property="model" auto-load="false" result-index="1"> <db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable; CALL myBasket_getAvailable;
SELECT DISTINCT o.id, l.name, o.code SELECT DISTINCT o.id, l.name, o.code
@ -301,18 +312,11 @@
WHERE #filter WHERE #filter
ORDER BY name ORDER BY name
</db-model> </db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-category"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter> </vn-filter>
<vn-filter <vn-filter
placeholder="_Category" placeholder="_Category"
param="category"> param="category"
id="category-filter">
<db-model property="model" auto-load="false" result-index="1"> <db-model property="model" auto-load="false" result-index="1">
CALL myBasket_getAvailable; CALL myBasket_getAvailable;
SELECT DISTINCT i.category, i.category SELECT DISTINCT i.category, i.category
@ -322,14 +326,6 @@
WHERE #filter WHERE #filter
ORDER BY category ORDER BY category
</db-model> </db-model>
<sql-filter property="filter" always-ready="true" type="AND">
<pointer object="op-realm"/>
<pointer object="op-type"/>
<pointer object="op-name"/>
<pointer object="op-color"/>
<pointer object="op-origin"/>
<pointer object="op-producer"/>
</sql-filter>
</vn-filter> </vn-filter>
</div> </div>
<div id="order" class="order"> <div id="order" class="order">

View File

@ -1,5 +1,5 @@
var NodeBuilder = require('./node-builder'); var NodeBuilder = require('../vn/node-builder');
/** /**
* Represents a grid column. This is an abstract class and should not be * Represents a grid column. This is an abstract class and should not be

View File

@ -59,7 +59,6 @@ module.exports = new Class({
} }
,_onChange: function() { ,_onChange: function() {
console.log(this._val);
if (this.node.checked && this._radioGroup) if (this.node.checked && this._radioGroup)
this._radioGroup.value = this._val || this.value; this._radioGroup.value = this._val || this.value;
} }

View File

@ -3,8 +3,7 @@ require('db/db');
require('./style/index.scss'); require('./style/index.scss');
Htk = module.exports = { Htk = module.exports = {
NodeBuilder : require('./node-builder') Widget : require('./widget')
,Widget : require('./widget')
,Component : require('./component') ,Component : require('./component')
,Popup : require('./popup') ,Popup : require('./popup')
,Dialog : require('./dialog') ,Dialog : require('./dialog')

View File

@ -1,10 +1,9 @@
const NodeBuilder = require('./node-builder'); const NodeBuilder = require('../vn/node-builder');
const Widget = new Class({ const Widget = new Class({
Extends: NodeBuilder Extends: NodeBuilder
,Properties: ,Properties: {
{
/** /**
* Main HTML node that represents the widget * Main HTML node that represents the widget
*/ */
@ -24,7 +23,7 @@ const Widget = new Class({
this.node.style = x; this.node.style = x;
} }
,get: function() { ,get: function() {
return this.node.style; return this._node.style;
} }
}, },
/** /**
@ -46,7 +45,7 @@ const Widget = new Class({
classList: { classList: {
type: Object type: Object
,get: function() { ,get: function() {
return this.node.classList; return this._node.classList;
} }
}, },
/** /**
@ -55,12 +54,26 @@ const Widget = new Class({
title: { title: {
type: String type: String
,set: function(x) { ,set: function(x) {
this.node.title = x; this._node.title = x;
} }
,get: function() { ,get: function() {
return this.node.title; return this._node.title;
} }
},
/**
* The HTML id of the element.
*/
htmlId:
{
type: String
,set: function(x) {
this._htmlId = x;
this._node.id = x;
} }
,get: function() {
return this._htmlId;
}
},
} }
,_node: null ,_node: null

View File

@ -8,10 +8,8 @@ var Value = require('./value');
module.exports = new Class({ module.exports = new Class({
Extends: Object Extends: Object
,Tag: 'sql-batch' ,Tag: 'sql-batch'
,Properties: ,Properties: {
{ blocked: {
blocked:
{
type: Boolean type: Boolean
,set: function(x) { ,set: function(x) {
this._blocked = x; this._blocked = x;

View File

@ -6,27 +6,23 @@ var Field = require ('./field');
/** /**
* The equivalent of a SQL DML. * The equivalent of a SQL DML.
*/ */
module.exports = new Class module.exports = new Class({
({
Extends: Stmt Extends: Stmt
,field: [] ,field: []
,expr: [] ,expr: []
,addSet: function (fieldName, value) ,addSet: function(fieldName, value) {
{
this.expr.push(new Value({value: value})); this.expr.push(new Value({value: value}));
this.field.push(new Field({name: fieldName})); this.field.push(new Field({name: fieldName}));
} }
,addExpr: function (fieldName, expr) ,addExpr: function(fieldName, expr) {
{
this.expr.push(expr); this.expr.push(expr);
this.field.push(new Field({name: fieldName})); this.field.push(new Field({name: fieldName}));
} }
,delSet: function () ,delSet: function() {
{
this.field.splice(0, this.field.length); this.field.splice(0, this.field.length);
this.expr.splice(0, this.expr.length); this.expr.splice(0, this.expr.length);
} }

View File

@ -4,8 +4,7 @@ var Object = require('./object');
/** /**
* The equivalent of a SQL expression. * The equivalent of a SQL expression.
*/ */
module.exports = new Class module.exports = new Class({
({
Extends: Object Extends: Object
,Tag: 'sql-expr' ,Tag: 'sql-expr'
}); });

View File

@ -4,14 +4,11 @@ var Operation = require('./operation');
/** /**
* The equivalent of a SQL operation. * The equivalent of a SQL operation.
*/ */
module.exports = new Class module.exports = new Class({
({
Extends: Operation Extends: Operation
,Tag: 'sql-filter-item' ,Tag: 'sql-filter-item'
,Properties: ,Properties: {
{ primary: {
primary:
{
type: Boolean type: Boolean
} }
} }

View File

@ -4,20 +4,16 @@ var Operation = require ('./operation');
/** /**
* The equivalent of a SQL operation. * The equivalent of a SQL operation.
*/ */
module.exports = new Class module.exports = new Class({
({
Extends: Operation Extends: Operation
,Tag: 'sql-filter' ,Tag: 'sql-filter'
,Properties: ,Properties: {
{ alwaysReady: {
alwaysReady:
{
type: Boolean type: Boolean
} }
} }
,isReady: function () ,isReady: function() {
{
if (this.alwaysReady) if (this.alwaysReady)
return true; return true;
@ -29,15 +25,13 @@ module.exports = new Class
return false; return false;
} }
,render: function (batch) ,render: function(batch) {
{
var isReady = false; var isReady = false;
var newOp = new Operation({type: this.type}); var newOp = new Operation({type: this.type});
var e = this.exprs.getArray(); var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++) for (var i = 0; i < e.length; i++)
if (e[i].isReady ()) if (e[i].isReady()) {
{
newOp.exprs.add(e[i]); newOp.exprs.add(e[i]);
isReady = true; isReady = true;
} }

View File

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

View File

@ -1,8 +1,7 @@
/** /**
* Base class for all objects on this library. * Base class for all objects on this library.
*/ */
module.exports = new Class module.exports = new Class({
({
Extends: Vn.Object Extends: Vn.Object
/** /**
@ -18,8 +17,7 @@ module.exports = new Class
* *
* @return {boolean} %true if the object is ready, %false otherwise * @return {boolean} %true if the object is ready, %false otherwise
*/ */
,isReady: function () ,isReady: function() {
{
return true; return true;
} }

View File

@ -10,8 +10,7 @@ var Expr = require ('./expr');
var Operation = new Class(); var Operation = new Class();
module.exports = Operation; module.exports = Operation;
var Type = var Type = {
{
EQUAL : 0 EQUAL : 0
,LIKE : 1 ,LIKE : 1
,AND : 2 ,AND : 2
@ -19,8 +18,7 @@ var Type =
,REGEXP : 4 ,REGEXP : 4
}; };
var Operators = var Operators = [
[
'=' '='
,'LIKE' ,'LIKE'
,'AND' ,'AND'
@ -28,54 +26,44 @@ var Operators =
,'REGEXP' ,'REGEXP'
]; ];
Operation.extend Operation.extend({
({
Type: Type Type: Type
,Operators: Operators ,Operators: Operators
}); });
Operation.implement Operation.implement({
({
Extends: Expr Extends: Expr
,Tag: 'sql-operation' ,Tag: 'sql-operation'
,Properties: ,Properties: {
{ type: {
type:
{
enumType: Type enumType: Type
,value: -1 ,value: -1
} }
} }
,initialize: function (props) ,initialize: function(props) {
{
this.parent(props); this.parent(props);
this.link({exprs: new Sql.List()}, {'changed': this.onListChange}); this.link({exprs: new Sql.List()}, {'changed': this.onListChange});
} }
,appendChild: function (child) ,appendChild: function(child) {
{
this.exprs.add(child); this.exprs.add(child);
} }
,onListChange: function () ,onListChange: function() {
{
this.signalEmit('changed'); this.signalEmit('changed');
} }
,isReady: function () ,isReady: function() {
{
return this.exprs.isReady(); return this.exprs.isReady();
} }
,render: function (batch) ,render: function(batch) {
{
var sql = '('; var sql = '(';
var operator = ' '+ Operators[this.type] +' '; var operator = ' '+ Operators[this.type] +' ';
var e = this.exprs.getArray(); var e = this.exprs.getArray();
for (var i = 0; i < e.length; i++) for (var i = 0; i < e.length; i++) {
{
if (i > 0) if (i > 0)
sql += operator; sql += operator;

View File

@ -8,13 +8,11 @@ module.exports = new Class({
Extends: Expr Extends: Expr
,Tag: 'sql-value' ,Tag: 'sql-value'
,Properties: ,Properties: {
{
/** /**
* The master param. * The master param.
*/ */
param: param: {
{
type: Vn.Param type: Vn.Param
,set: function(x) { ,set: function(x) {
this.link({_param: x}, {'changed': this.onParamChange}); this.link({_param: x}, {'changed': this.onParamChange});
@ -27,8 +25,7 @@ module.exports = new Class({
/** /**
* The value. * The value.
*/ */
value: value: {
{
type: String type: String
,set: function(x) { ,set: function(x) {
if (Vn.Value.compare(x, this._value)) if (Vn.Value.compare(x, this._value))

View File

@ -1,4 +1,6 @@
const VnObject = require('./object'); const VnObject = require('./object');
const Widget = require('../htk/widget');
const VnNode = require('./node');
const Scope = require('./scope'); const Scope = require('./scope');
const kebabToCamel = require('./string-util').kebabToCamel; const kebabToCamel = require('./string-util').kebabToCamel;
@ -123,8 +125,10 @@ module.exports = new Class({
if (isElement) { if (isElement) {
var nodeId = node.getAttribute('id'); var nodeId = node.getAttribute('id');
if (nodeId) if (nodeId) {
this._contextMap[kebabToCamel(nodeId)] = context.id; this._contextMap[kebabToCamel(nodeId)] = context.id;
context.nodeId = nodeId;
}
var tags = this._tags[tagName]; var tags = this._tags[tagName];
@ -161,23 +165,24 @@ module.exports = new Class({
if (this._contexts === null) if (this._contexts === null)
return null; return null;
const doc = dstDocument ? dstDocument : document;
const contexts = this._contexts; const contexts = this._contexts;
const len = contexts.length; const len = contexts.length;
const objects = new Array(len); const objects = new Array(len);
const doc = dstDocument ? dstDocument : document; const scope = new Scope(this, objects, thisArg, parentScope);
for (var i = 0; i < len; i++) { for (var i = 0; i < len; i++) {
var context = contexts[i]; var context = contexts[i];
if (context.tagName) if (context.tagName)
objects[i] = this.elementInstantiate(doc, context); objects[i] = this.elementInstantiate(doc, context, scope);
else if (context.klass) else if (context.klass)
objects[i] = this.objectInstantiate(doc, context); objects[i] = this.objectInstantiate(doc, context, scope);
else else
objects[i] = this.textInstantiate(doc, context); objects[i] = this.textInstantiate(doc, context, scope);
} }
return new Scope(this, objects, thisArg, parentScope); return scope;
} }
,link: function(scope, exprScope) { ,link: function(scope, exprScope) {
@ -502,13 +507,20 @@ module.exports = new Class({
} }
} }
,objectInstantiate: function(doc, context) { ,objectInstantiate: function(doc, context, scope) {
return new context.klass(); const object = new context.klass();
object.setProperties(context.props);
if (context.nodeId && object instanceof Widget) {
var id = context.nodeId;
object.htmlId = scope.getHtmlId(id);
object.className = '_'+ id +' '+ object.className;
}
return object;
} }
,objectLink: function(context, object, objects, scope, exprScope) { ,objectLink: function(context, object, objects, scope, exprScope) {
object.setProperties(context.props);
const objectProps = context.objectProps; const objectProps = context.objectProps;
for (const prop in objectProps) for (const prop in objectProps)
object[prop] = objects[objectProps[prop]]; object[prop] = objects[objectProps[prop]];
@ -609,20 +621,28 @@ module.exports = new Class({
}; };
} }
,elementInstantiate: function(doc, context) { ,elementInstantiate: function(doc, context, scope) {
return doc.createElement(context.tagName); var object = doc.createElement(context.tagName);
}
,elementLink: function(context, object, objects, scope, exprScope) {
const attributes = context.attributes; const attributes = context.attributes;
for (const attribute in attributes) for (const attribute in attributes)
object.setAttribute(attribute, attributes[attribute]); object.setAttribute(attribute, attributes[attribute]);
if (context.nodeId) {
const id = context.nodeId;
object.setAttribute('id', scope.getHtmlId(id));
VnNode.addClass(object, '_'+ id);
}
return object;
}
,elementLink: function(context, object, objects, scope, exprScope) {
const childs = context.childs; const childs = context.childs;
for (var i = 0; i < childs.length; i++) { for (var i = 0; i < childs.length; i++) {
let child = objects[childs[i]]; let child = objects[childs[i]];
if (child instanceof Htk.Widget) if (child instanceof Widget)
child = child.node; child = child.node;
if (child instanceof Node) if (child instanceof Node)
object.appendChild(child); object.appendChild(child);

View File

@ -1,6 +1,7 @@
const VnObject = require('./object');
module.exports = new Class({ module.exports = new Class({
Extends: Vn.Object Extends: VnObject
,doc: null ,doc: null

View File

@ -1,6 +1,8 @@
const VnObject = require('./object'); const VnObject = require('./object');
const kebabToCamel = require('./string-util').kebabToCamel; const kebabToCamel = require('./string-util').kebabToCamel;
let scopeUid = 0;
module.exports = new Class({ module.exports = new Class({
Extends: VnObject Extends: VnObject
@ -9,6 +11,7 @@ module.exports = new Class({
this.objects = objects; this.objects = objects;
this.thisArg = thisArg; this.thisArg = thisArg;
this.parentScope = parent; this.parentScope = parent;
this.uid = ++scopeUid;
this.$ = parent ? Object.create(parent.$) : {}; this.$ = parent ? Object.create(parent.$) : {};
if (!thisArg && parent) if (!thisArg && parent)

View File

@ -16,6 +16,7 @@ Vn = module.exports = {
,Hash : require('./hash') ,Hash : require('./hash')
,HashParam : require('./hash-param') ,HashParam : require('./hash-param')
,Node : require('./node') ,Node : require('./node')
,NodeBuilder : require('./node-builder')
,Builder : require('./builder') ,Builder : require('./builder')
,JsonException : require('./json-exception') ,JsonException : require('./json-exception')
,JsonConnection : require('./json-connection') ,JsonConnection : require('./json-connection')
@ -28,10 +29,8 @@ Vn = module.exports = {
,head: document.getElementsByTagName('head')[0] ,head: document.getElementsByTagName('head')[0]
,isMobileCached: null ,isMobileCached: null
,getVersion: function () ,getVersion: function() {
{ if (this._version === undefined) {
if (this._version === undefined)
{
var re = /[; ]vnVersion=([^\\s;]*)/; var re = /[; ]vnVersion=([^\\s;]*)/;
var sMatch = (' '+ document.cookie).match(re); var sMatch = (' '+ document.cookie).match(re);
this._version = (sMatch) ? '?'+ unescape(sMatch[1]) : ''; this._version = (sMatch) ? '?'+ unescape(sMatch[1]) : '';
@ -46,12 +45,10 @@ Vn = module.exports = {
* *
* @param {string} fileName The stylesheet file name * @param {string} fileName The stylesheet file name
*/ */
,includeCss: function (fileName) ,includeCss: function(fileName) {
{
var cssData = this.cssIncludes[fileName]; var cssData = this.cssIncludes[fileName];
if (!cssData) if (!cssData) {
{
var link = document.createElement('link'); var link = document.createElement('link');
link.rel = 'stylesheet'; link.rel = 'stylesheet';
link.type = 'text/css'; link.type = 'text/css';
@ -63,9 +60,7 @@ Vn = module.exports = {
included: true included: true
,link: link ,link: link
}; };
} } else if (!cssData.included) {
else if (!cssData.included)
{
cssData.link.disabled = false; cssData.link.disabled = false;
cssData.included = true; cssData.included = true;
} }
@ -76,19 +71,16 @@ Vn = module.exports = {
* *
* @param {string} fileName The stylesheet file name * @param {string} fileName The stylesheet file name
*/ */
,excludeCss: function (fileName) ,excludeCss: function(fileName) {
{
var cssData = this.cssIncludes[fileName]; var cssData = this.cssIncludes[fileName];
if (cssData && cssData.included) if (cssData && cssData.included) {
{
cssData.link.disabled = true; cssData.link.disabled = true;
cssData.included = false; cssData.included = false;
} }
} }
,_createIncludeData: function (path) ,_createIncludeData: function(path) {
{
var includeData = { var includeData = {
depCount: 0 depCount: 0
,success: false ,success: false
@ -101,8 +93,7 @@ Vn = module.exports = {
return includeData; return includeData;
} }
,_handleCallback: function (includeData, callback) ,_handleCallback: function(includeData, callback) {
{
if (!callback) if (!callback)
return; return;
@ -112,8 +103,7 @@ Vn = module.exports = {
includeData.callbacks.push(callback); includeData.callbacks.push(callback);
} }
,_resolveDeps: function (includeData) ,_resolveDeps: function(includeData) {
{
includeData.success = true; includeData.success = true;
var callbacks = includeData.callbacks; var callbacks = includeData.callbacks;
@ -125,8 +115,7 @@ Vn = module.exports = {
var dependants = includeData.dependants; var dependants = includeData.dependants;
if (dependants) if (dependants)
for (var i = 0; i < dependants.length; i++) for (var i = 0; i < dependants.length; i++) {
{
var dependant = dependants[i]; var dependant = dependants[i];
dependant.depCount--; dependant.depCount--;
@ -146,10 +135,8 @@ Vn = module.exports = {
* *
* @param {Function} callback The main function * @param {Function} callback The main function
*/ */
,main: function (callback) ,main: function(callback) {
{ if (this.mainCalled) {
if (this.mainCalled)
{
Vn.warning("Vn: main method should be called only once"); Vn.warning("Vn: main method should be called only once");
return; return;
} }
@ -164,15 +151,13 @@ Vn = module.exports = {
var scripts = this.head.getElementsByTagName('script'); var scripts = this.head.getElementsByTagName('script');
var includes = this.currentDeps; var includes = this.currentDeps;
for (var i = 0; i < scripts.length; i++) for (var i = 0; i < scripts.length; i++) {
{
var path = scripts[i].src.substr(basePath.length); var path = scripts[i].src.substr(basePath.length);
path = path.substr(0, path.indexOf('.js')) +'.js'; path = path.substr(0, path.indexOf('.js')) +'.js';
var includeData = this.includes[path]; var includeData = this.includes[path];
if (includeData === undefined) if (includeData === undefined) {
{
this.currentDeps = includes; this.currentDeps = includes;
var includeData = this._createIncludeData(path); var includeData = this._createIncludeData(path);
this._onScriptLoad(includeData, true); this._onScriptLoad(includeData, true);
@ -183,20 +168,17 @@ Vn = module.exports = {
window.addEventListener('load', this._onWindowLoad.bind(this)); window.addEventListener('load', this._onWindowLoad.bind(this));
} }
,_onMainDepsLoad: function () ,_onMainDepsLoad: function() {
{
this.mainDepsLoaded = true; this.mainDepsLoaded = true;
this._callMain(); this._callMain();
} }
,_onWindowLoad: function () ,_onWindowLoad: function() {
{
this.windowReady = true; this.windowReady = true;
this._callMain(); this._callMain();
} }
,_callMain: function () ,_callMain: function() {
{
if (this.mainCallback && this.windowReady && this.mainDepsLoaded) if (this.mainCallback && this.windowReady && this.mainDepsLoaded)
this.mainCallback(); this.mainCallback();
} }
@ -207,10 +189,8 @@ Vn = module.exports = {
* *
* @param {...} The list of files as function arguments * @param {...} The list of files as function arguments
*/ */
,include: function () ,include: function() {
{ for (var i = 0; i < arguments.length; i++) {
for (var i = 0; i < arguments.length; i++)
{
var includeData = this._realIncludeJs(arguments[i] +'.js'); var includeData = this._realIncludeJs(arguments[i] +'.js');
if (!includeData.success) if (!includeData.success)
@ -224,10 +204,8 @@ Vn = module.exports = {
* *
* @param {...} The list of files as function arguments * @param {...} The list of files as function arguments
*/ */
,resource: function () ,resource: function() {
{ for (var i = 0; i < arguments.length; i++) {
for (var i = 0; i < arguments.length; i++)
{
var includeData = this._realLoadXml(arguments[i]); var includeData = this._realLoadXml(arguments[i]);
if (!includeData.success) if (!includeData.success)
@ -241,8 +219,7 @@ Vn = module.exports = {
* *
* @param {Function} callback The callback function * @param {Function} callback The callback function
*/ */
,define: function (callback) ,define: function(callback) {
{
this.currentCallback = callback; this.currentCallback = callback;
} }
@ -252,8 +229,7 @@ Vn = module.exports = {
* @param {string} libName The folder of the library * @param {string} libName The folder of the library
* @param {Array<string>} files Array with every library file name * @param {Array<string>} files Array with every library file name
*/ */
,includeLib: function (libName, files) ,includeLib: function(libName, files) {
{
Vn.Locale.loadScript('js/'+ libName +'.js'); Vn.Locale.loadScript('js/'+ libName +'.js');
for (var i = 0; i < files.length; i++) for (var i = 0; i < files.length; i++)
@ -268,18 +244,15 @@ Vn = module.exports = {
* @param {Function} callback The function to call when script is * @param {Function} callback The function to call when script is
* downloaded and included * downloaded and included
*/ */
,includeJs: function (fileName, callback, skipVersion) ,includeJs: function(fileName, callback, skipVersion) {
{
var includeData = this._realIncludeJs(fileName, skipVersion); var includeData = this._realIncludeJs(fileName, skipVersion);
this._handleCallback(includeData, callback); this._handleCallback(includeData, callback);
} }
,_realIncludeJs: function (fileName, skipVersion) ,_realIncludeJs: function(fileName, skipVersion) {
{
var includeData = this.includes[fileName]; var includeData = this.includes[fileName];
if (includeData === undefined) if (includeData === undefined) {
{
includeData = this._createIncludeData(fileName); includeData = this._createIncludeData(fileName);
var src = fileName; var src = fileName;
@ -305,34 +278,28 @@ Vn = module.exports = {
return includeData; return includeData;
} }
,_onScriptStateChange: function (includeData, script) ,_onScriptStateChange: function(includeData, script) {
{
if (script.readyState == 'complete') if (script.readyState == 'complete')
this._onScriptLoad(includeData, true); this._onScriptLoad(includeData, true);
} }
,_onScriptLoad: function (includeData, loaded) ,_onScriptLoad: function(includeData, loaded) {
{
includeData.loaded = loaded; includeData.loaded = loaded;
if (loaded) if (loaded) {
{
if (this.currentCallback) if (this.currentCallback)
includeData.callbacks.unshift(this.currentCallback); includeData.callbacks.unshift(this.currentCallback);
var includes = this.currentDeps; var includes = this.currentDeps;
if (includes && includes.length > 0) if (includes && includes.length > 0) {
{
includeData.depCount = includes.length; includeData.depCount = includes.length;
for (var i = 0; i < includes.length; i++) for (var i = 0; i < includes.length; i++)
includes[i].dependants.push(includeData); includes[i].dependants.push(includeData);
} } else
else
this._resolveDeps(includeData); this._resolveDeps(includeData);
} } else
else
this._resolveDeps(includeData); this._resolveDeps(includeData);
this.currentDeps = []; this.currentDeps = [];
@ -345,18 +312,15 @@ Vn = module.exports = {
* @param {string} path The file path * @param {string} path The file path
* @param {Function} callback The function to call when file is downloaded * @param {Function} callback The function to call when file is downloaded
*/ */
,loadXml: function (path, callback) ,loadXml: function(path, callback) {
{
var includeData = this._realLoadXml(path); var includeData = this._realLoadXml(path);
this._handleCallback(includeData, callback); this._handleCallback(includeData, callback);
} }
,_realLoadXml: function (path) ,_realLoadXml: function(path) {
{
var includeData = this.includes[path]; var includeData = this.includes[path];
if (includeData === undefined) if (includeData === undefined) {
{
includeData = this._createIncludeData(path); includeData = this._createIncludeData(path);
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
@ -369,8 +333,7 @@ Vn = module.exports = {
return includeData; return includeData;
} }
,_onXmlReady: function (includeData, request) ,_onXmlReady: function(includeData, request) {
{
if (request.readyState != 4) if (request.readyState != 4)
return; return;
@ -388,8 +351,7 @@ Vn = module.exports = {
* @param {string} path The file path * @param {string} path The file path
* @return {Object} The DOM object * @return {Object} The DOM object
*/ */
,getXml: function (path) ,getXml: function(path) {
{
var includeData = this.includes[path]; var includeData = this.includes[path];
if (!(includeData && includeData.success)) if (!(includeData && includeData.success))
@ -403,10 +365,8 @@ Vn = module.exports = {
* *
* return {boolean} %true if is mobile, %false otherwise. * return {boolean} %true if is mobile, %false otherwise.
*/ */
,isMobile: function () ,isMobile: function() {
{ if (this.isMobileCached === null) {
if (this.isMobileCached === null)
{
var regExp = /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i; var regExp = /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i;
this.isMobileCached = navigator.userAgent.match(regExp); this.isMobileCached = navigator.userAgent.match(regExp);
} }

View File

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