From 49085f3597b933787db00408c43acf78bf7d5463 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 11 Sep 2015 11:37:16 +0200 Subject: [PATCH 01/39] =?UTF-8?q?Dise=C3=B1o=20responsive,=20ahora=20se=20?= =?UTF-8?q?aprobecha=20mejor=20el=20espacio,=20imports=20usan=20Javascript?= =?UTF-8?q?,=20vista=20de=20rejilla=20en=20catalogo,=20mas...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/vn/hedera/js.php | 4 +- lib/vn/tpv/tpv.php | 12 +- web/forms/account/address-list/ui.xml | 23 +- web/forms/account/address/ui.xml | 26 +- web/forms/account/conf/ui.xml | 19 +- web/forms/admin/access-log/ui.xml | 6 +- web/forms/admin/links/ui.xml | 6 +- web/forms/admin/photos/ui.xml | 6 +- web/forms/admin/users/ui.xml | 6 +- web/forms/admin/visits/ui.xml | 34 +- web/forms/agencies/packages/ui.xml | 6 +- web/forms/agencies/provinces/provinces.js | 5 - web/forms/agencies/provinces/ui.xml | 13 +- web/forms/cms/about/ui.xml | 3 + web/forms/cms/contact/ui.xml | 6 +- web/forms/cms/home/ui.xml | 3 + web/forms/cms/location/ui.xml | 3 + web/forms/cms/training/ui.xml | 3 + web/forms/cms/why/ui.xml | 6 +- web/forms/ecomerce/basket/ui.xml | 33 +- web/forms/ecomerce/catalog/catalog.js | 57 ++- web/forms/ecomerce/catalog/mobile.css | 13 - web/forms/ecomerce/catalog/style.css | 171 ++++--- web/forms/ecomerce/catalog/ui.xml | 157 ++++--- web/forms/ecomerce/checkout/ui.xml | 19 +- web/forms/ecomerce/confirm/ui.xml | 6 +- web/forms/ecomerce/invoices/ui.xml | 42 +- web/forms/ecomerce/orders/ui.xml | 39 +- web/forms/ecomerce/ticket/ui.xml | 18 +- web/forms/news/new/style.css | 2 +- web/forms/news/new/ui.xml | 23 +- web/forms/news/news/ui.xml | 20 +- web/global/metatags.php | 4 +- web/image/dark/exit.svg | 61 +++ web/image/exit.svg | 61 +++ web/js/db/conn.js | 9 +- web/js/db/db.js | 5 + web/js/db/main.js | 20 +- web/js/db/main.php | 2 +- web/js/hedera/app.js | 87 ++++ web/js/hedera/gui.css | 332 ++++++++++++++ web/js/hedera/gui.js | 526 ++++++++++++++++++++++ web/js/hedera/gui.xml | 49 ++ web/js/hedera/hedera.js | 4 + web/js/hedera/login.css | 162 +++++++ web/js/hedera/login.js | 74 +++ web/js/hedera/login.xml | 57 +++ web/js/hedera/main.js | 19 + web/js/hedera/module.js | 88 ++++ web/js/hedera/style.css | 382 ++++++++++++++++ web/js/hedera/tpv.js | 124 +++++ web/js/htk/htk.js | 40 +- web/js/htk/image-editor.js | 10 +- web/js/htk/loader.css | 74 +++ web/js/htk/loader.js | 12 + web/js/htk/main.js | 46 +- web/js/htk/main.php | 2 +- web/js/htk/style.css | 505 +++++++++++++++++++++ web/js/htk/widget.js | 8 + web/js/misc/main.js | 4 + web/js/sql/main.js | 32 +- web/js/sql/main.php | 2 +- web/js/sql/sql.js | 5 + web/js/vn/locale.js | 13 +- web/js/vn/main.js | 203 +-------- web/js/vn/main.php | 2 +- web/js/vn/vn.js | 229 ++++++++++ web/locale/ca/js/hedera.js | 49 ++ web/locale/ca/js/vn.js | 43 -- web/locale/es/js/hedera.js | 49 ++ web/locale/es/js/vn.js | 43 -- web/locale/fr/js/hedera.js | 49 ++ web/locale/fr/js/vn.js | 43 -- web/pages/login/login.js | 15 +- web/pages/main/head.php | 13 + web/pages/main/html.php | 15 + web/pages/main/main.js | 13 + web/pages/main/opensans.ttf | Bin 0 -> 217360 bytes web/pages/main/style.css | 17 + web/pages/version-menu/style.css | 15 +- web/pages/web/html.php | 8 +- web/pages/web/web.js | 15 +- 82 files changed, 3660 insertions(+), 770 deletions(-) delete mode 100755 web/forms/ecomerce/catalog/mobile.css create mode 100644 web/image/dark/exit.svg create mode 100644 web/image/exit.svg create mode 100755 web/js/db/db.js create mode 100644 web/js/hedera/app.js create mode 100755 web/js/hedera/gui.css create mode 100755 web/js/hedera/gui.js create mode 100755 web/js/hedera/gui.xml create mode 100644 web/js/hedera/hedera.js create mode 100755 web/js/hedera/login.css create mode 100755 web/js/hedera/login.js create mode 100755 web/js/hedera/login.xml create mode 100644 web/js/hedera/main.js create mode 100755 web/js/hedera/module.js create mode 100755 web/js/hedera/style.css create mode 100755 web/js/hedera/tpv.js create mode 100644 web/js/htk/loader.css create mode 100755 web/js/htk/loader.js create mode 100755 web/js/htk/style.css create mode 100755 web/js/misc/main.js create mode 100755 web/js/sql/sql.js mode change 100755 => 100644 web/js/vn/main.js create mode 100755 web/js/vn/vn.js create mode 100755 web/locale/ca/js/hedera.js create mode 100755 web/locale/es/js/hedera.js create mode 100755 web/locale/fr/js/hedera.js create mode 100755 web/pages/main/head.php create mode 100755 web/pages/main/html.php create mode 100755 web/pages/main/main.js create mode 100755 web/pages/main/opensans.ttf create mode 100755 web/pages/main/style.css mode change 100755 => 100644 web/pages/web/web.js diff --git a/lib/vn/hedera/js.php b/lib/vn/hedera/js.php index adcd2fc3..df3d5963 100755 --- a/lib/vn/hedera/js.php +++ b/lib/vn/hedera/js.php @@ -10,7 +10,7 @@ class Js static function includeFile ($fileName) { - echo ''."\n\t"; + echo ''."\n\t\t"; } static function includeLib ($libName) @@ -28,7 +28,7 @@ class Js static function includeCss ($fileName) { - echo ''."\n\t"; + echo ''."\n\t\t"; } static function isMobile () diff --git a/lib/vn/tpv/tpv.php b/lib/vn/tpv/tpv.php index 7f29a495..f1a5f0d9 100755 --- a/lib/vn/tpv/tpv.php +++ b/lib/vn/tpv/tpv.php @@ -102,14 +102,14 @@ class Tpv $folder = sprintf ('INBOX.%s', $folder); if (!imap_mail_move ($imap, $msg, $folder)) - error_log ('TPV: IMAP: Can\'t move message to %s: %s' + trigger_error (sprintf ('TPV: IMAP: Can\'t move message to %s: %s' ,$folder ,imap_last_error () - ); + ), E_USER_WARNING); } if ($inbox && ($count = count ($inbox)) > 0) - error_log ('TPV: %d mails processed.', $count); + trigger_error (sprintf ('TPV: %d mails processed.', $count)); imap_expunge ($imap); @@ -138,13 +138,13 @@ class Tpv $deleted += count ($messages); } - error_log ('TPV: Cleaner: %d mails deleted.', $deleted); + trigger_error (sprintf ('TPV: Cleaner: %d mails deleted.', $deleted)); } imap_close ($imap); } else - error_log ('TPV: IMAP: %s', imap_last_error ()); + trigger_error (sprintf ('TPV: IMAP: %s', imap_last_error ()), E_USER_ERROR); self::deinit (); } @@ -207,7 +207,7 @@ class Tpv } catch (\Exception $e) { - error_log ("TPV: DB: %s", $e->getMessage ()); + trigger_error (sprintf ("TPV: DB: %s", $e->getMessage ()), E_USER_WARNING); } } diff --git a/web/forms/account/address-list/ui.xml b/web/forms/account/address-list/ui.xml index 033c2c0a..41858817 100755 --- a/web/forms/account/address-list/ui.xml +++ b/web/forms/account/address-list/ui.xml @@ -14,22 +14,17 @@ WHERE active != FALSE +
+

Addresses

+
+
+ +
-
-

Addresses

-
- - -
-
-
+
+

AddEditAddress

+
+
+ + +
-
-

AddEditAddress

-
- - -
-
diff --git a/web/forms/account/conf/ui.xml b/web/forms/account/conf/ui.xml index 7fd48b11..a1468a72 100755 --- a/web/forms/account/conf/ui.xml +++ b/web/forms/account/conf/ui.xml @@ -16,18 +16,17 @@ WHERE active != FALSE +
+

Configuration

+
+
+ +
-
-

Configuration

-
- -
-
-
diff --git a/web/forms/admin/access-log/ui.xml b/web/forms/admin/access-log/ui.xml index 1dff1256..8742652a 100755 --- a/web/forms/admin/access-log/ui.xml +++ b/web/forms/admin/access-log/ui.xml @@ -13,11 +13,11 @@ +
+

AccessLog

+
-
-

AccessLog

-
diff --git a/web/forms/admin/links/ui.xml b/web/forms/admin/links/ui.xml index 41c8adaf..eb0cb4de 100755 --- a/web/forms/admin/links/ui.xml +++ b/web/forms/admin/links/ui.xml @@ -1,9 +1,9 @@ +
+

ControlPanel

+
-
-

ControlPanel

-
SELECT image, name, description, link FROM link diff --git a/web/forms/admin/photos/ui.xml b/web/forms/admin/photos/ui.xml index c0b67e9f..b19d92d8 100755 --- a/web/forms/admin/photos/ui.xml +++ b/web/forms/admin/photos/ui.xml @@ -1,9 +1,9 @@ +
+

Photos

+
-
-

Photos

-
+
+

UserManagement

+
-
-

UserManagement

-
diff --git a/web/forms/admin/visits/ui.xml b/web/forms/admin/visits/ui.xml index 9683a5a2..c9d502a2 100755 --- a/web/forms/admin/visits/ui.xml +++ b/web/forms/admin/visits/ui.xml @@ -1,23 +1,23 @@ +
+

VisitsManagement

+
+
+ + + +
-
-

VisitsManagement

-
- - - -
-
diff --git a/web/forms/agencies/packages/ui.xml b/web/forms/agencies/packages/ui.xml index 3853b34e..dde003b9 100755 --- a/web/forms/agencies/packages/ui.xml +++ b/web/forms/agencies/packages/ui.xml @@ -1,9 +1,9 @@ +
+

ListByAgency

+
-
-

ListByAgency

-
CALL vn2008.agencia_volume () diff --git a/web/forms/agencies/provinces/provinces.js b/web/forms/agencies/provinces/provinces.js index b160d5e0..8e799ba2 100755 --- a/web/forms/agencies/provinces/provinces.js +++ b/web/forms/agencies/provinces/provinces.js @@ -2,10 +2,5 @@ Vn.Provinces = new Class ({ Extends: Vn.Module - - ,onReturnClick: function () - { - window.history.back(); - } }); diff --git a/web/forms/agencies/provinces/ui.xml b/web/forms/agencies/provinces/ui.xml index 85fc9fab..ac37cc8d 100755 --- a/web/forms/agencies/provinces/ui.xml +++ b/web/forms/agencies/provinces/ui.xml @@ -4,18 +4,11 @@ +
+

ByProvince

+
-
-

ByProvince

-
- -
-
-
CALL vn2008.desglose_volume (#agency) diff --git a/web/forms/cms/about/ui.xml b/web/forms/cms/about/ui.xml index 0a1589a2..f88ce594 100755 --- a/web/forms/cms/about/ui.xml +++ b/web/forms/cms/about/ui.xml @@ -1,4 +1,7 @@ +
+

About

+
diff --git a/web/forms/cms/contact/ui.xml b/web/forms/cms/contact/ui.xml index 9c347d71..b12a942a 100755 --- a/web/forms/cms/contact/ui.xml +++ b/web/forms/cms/contact/ui.xml @@ -1,9 +1,9 @@ +
+

IWantCustomer

+
-
-

IWantCustomer

-

FillFormData diff --git a/web/forms/cms/home/ui.xml b/web/forms/cms/home/ui.xml index b722ede4..8f75c612 100755 --- a/web/forms/cms/home/ui.xml +++ b/web/forms/cms/home/ui.xml @@ -1,4 +1,7 @@ +

+

Home

+
diff --git a/web/forms/cms/location/ui.xml b/web/forms/cms/location/ui.xml index 91571408..58388869 100755 --- a/web/forms/cms/location/ui.xml +++ b/web/forms/cms/location/ui.xml @@ -1,3 +1,6 @@ +
+

Location

+
diff --git a/web/forms/cms/training/ui.xml b/web/forms/cms/training/ui.xml index 314a3c96..8880d57f 100755 --- a/web/forms/cms/training/ui.xml +++ b/web/forms/cms/training/ui.xml @@ -1,4 +1,7 @@ +
+

Training

+
diff --git a/web/forms/cms/why/ui.xml b/web/forms/cms/why/ui.xml index 8ad3f086..dfc6db71 100755 --- a/web/forms/cms/why/ui.xml +++ b/web/forms/cms/why/ui.xml @@ -1,9 +1,9 @@ +
+

AboutCompany

+
-
-

AboutCompany

-
  • BecauseOurBigCatalog
  • diff --git a/web/forms/ecomerce/basket/ui.xml b/web/forms/ecomerce/basket/ui.xml index 089e28b5..df7a9b9e 100755 --- a/web/forms/ecomerce/basket/ui.xml +++ b/web/forms/ecomerce/basket/ui.xml @@ -1,23 +1,22 @@ +
    +

    ShoppingBasket

    +
    +
    + + + +
    -
    -

    ShoppingBasket

    -
    - - - -
    -
    -
    diff --git a/web/forms/ecomerce/catalog/catalog.js b/web/forms/ecomerce/catalog/catalog.js index 2f0b1791..95fddb94 100755 --- a/web/forms/ecomerce/catalog/catalog.js +++ b/web/forms/ecomerce/catalog/catalog.js @@ -23,6 +23,11 @@ Vn.Catalog = new Class } } + ,deactivate: function () + { + this.gui.$('top-bar').style.backgroundColor = ''; + } + ,onBasketForGuest: function () { this.onBasketCheck (true); @@ -82,14 +87,14 @@ Vn.Catalog = new Class color = '#'+ realms.get (row, 'color'); } - this.$('header').style.backgroundColor = color; - + this.gui.$('top-bar').style.backgroundColor = color; +/* var tr = this.$('items-grid').getNode () .getElementsByTagName ('thead')[0] .getElementsByTagName ('tr')[0]; //.querySelector ('thead tr'); tr.style.backgroundColor = color; - } +*/ } ,refreshTitle: function (title) { @@ -110,7 +115,7 @@ Vn.Catalog = new Class else if (this.$('search-entry').value) title = _('SearchResults'); - Vn.Node.setText (this.$('title'), title); + Vn.Node.setText (this.$('title-text'), title); } ,onSearch: function (event) @@ -163,6 +168,11 @@ Vn.Catalog = new Class Htk.Toast.showError (_('YouMustBeLoggedIn')); } + ,nameRenderer: function (renderer, form) + { + renderer.subtitle = form.get ('producer'); + } + ,featuresRender: function (renderer, form) { renderer.value = form.get ('Medida') +' '+ form.get ('Categoria') +' '+ form.get ('Color'); @@ -199,8 +209,18 @@ Vn.Catalog = new Class column.td.className = ''; } } + + ,onGridAddItemClick: function (button, form) + { + this.showAmountPopup (button, form.row); + } ,onAddItemClick: function (column, value, row, button) + { + this.showAmountPopup (button, row); + } + + ,showAmountPopup: function (button, row) { if (Vn.Url.getQuery ('guest')) { @@ -213,7 +233,7 @@ Vn.Catalog = new Class this.itemRow = row; this.onEraseClick (); - this.popup.show (button); + this.popup.show (button); } ,onAddLotClick: function (column, value, row, button) @@ -283,3 +303,30 @@ Vn.Catalog = new Class } }); +Htk.ColumnCheck = new Class +({ + Extends: Htk.Column + ,Tag: 'vn-column-item' + + ,render: function (tr) + { + var td = this.parent (tr); + td.style.textAlign = 'left'; + + if (this.value) + { + var node = document.createTextNode ( + Vn.Value.format (this.value, this._format)); + td.appendChild (node); + } + + if (this.subtitle) + { + td.appendChild (document.createElement ('br')); + td.appendChild (document.createTextNode (this.subtitle)); + } + + return td; + } +}); + diff --git a/web/forms/ecomerce/catalog/mobile.css b/web/forms/ecomerce/catalog/mobile.css deleted file mode 100755 index 804c7e9e..00000000 --- a/web/forms/ecomerce/catalog/mobile.css +++ /dev/null @@ -1,13 +0,0 @@ - -.catalog button.menu -{ - display: block; -} -.catalog div.menu -{ - display: none; -} -.catalog div.center -{ - right: 0; -} diff --git a/web/forms/ecomerce/catalog/style.css b/web/forms/ecomerce/catalog/style.css index 0a459105..623fe3e5 100755 --- a/web/forms/ecomerce/catalog/style.css +++ b/web/forms/ecomerce/catalog/style.css @@ -24,9 +24,9 @@ left: 0; right: 0; overflow: auto; - padding: 1em; + padding: .4em; } -.catalog div.main .box +.catalog div.main .list-view { margin: 0 auto; max-width: 50em; @@ -45,7 +45,7 @@ { max-width: 15em; } -.catalog .search +.search { float: left; display: block; @@ -53,38 +53,23 @@ height: 2.2em; padding: 0; } -.catalog .search > input +.search > input { margin: 0; border: none; width: 10em; box-shadow: none; } -.catalog .search > input:focus +.search > input:focus { background-color: initial; } -.catalog .search > img +.search > img { margin: 0.4em; margin-top: 0; vertical-align: middle; } -.catalog button.menu -{ - float: left; - display: none; - border: none; - background-color: transparent; - box-shadow: none; - padding: 0.3em; - padding-left: 0; - margin-left: 0; -} -.catalog button.menu > img -{ - height: 1.8em; -} /* Menu */ @@ -160,46 +145,6 @@ button.basket:hover background-color: rgba(1, 1, 1, .1); } -/* Grid view */ - -.item-box -{ - padding: 1em; - border-bottom: 1px solid #DDD; - min-height: 14em; -} -.item-box > .image -{ - width: 8em; - height: 14em; - float: left; - margin-right: 1em; -} -.item-box img -{ - max-width: 8em; - max-height: 8em; - display: block; - margin: 0 auto; -} -.item-box p -{ - margin: 0; - padding: 0.6em; -} -.item-box h2 -{ - font-weight: normal; -} -.item-box .amount -{ - width: 3em; -} -.amount-p -{ - text-align: right; -} - /* Lots popup*/ div.amount @@ -240,18 +185,17 @@ button.confirm > img { height: 6em; } -.items > tbody img -{ - max-height: 6em; - max-width: 6em; - border-radius: 50%; -} .items .icon { width: 6em; padding: .2em; padding-right: .5em; } +.items .icon > img +{ + max-height: 6em; + max-width: 6em; +} td.second-category { font-weight: bold; @@ -262,8 +206,99 @@ td.third-category font-weight: bold; color: red; } -td.price +.catalog .price { color: green; + font-size: 1.1em; +} + +/* Grid view */ + +.catalog .grid-view +{ + text-align: center; +} +.item-box +{ + text-align: left; + position: relative; + width: 22em; + display: inline-block; + padding: .8em; + margin: .4em; + margin-bottom: .1em; + height: 9em; + overflow: hidden; +} +.item-box > .image +{ + width: 9em; + height: 100%; + float: left; + margin-right: 1em; +} +.item-box img +{ + max-width: 9em; + max-height: 9em; + display: block; + margin: 0 auto; +} +.item-box > p +{ + margin: 0; + padding: 0; + font-size: .9em; +} +.item-box > h2 +{ + font-size: 1.1em; + font-weight: normal; +} +.item-box > .aval-price +{ + position: absolute; + bottom: 1em; + right: 4em; +} +.item-box > .add-button +{ + position: absolute; + bottom: .5em; + right: .5em; +} + +/* Mobile */ + +.catalog-actions button.menu +{ + float: left; + display: none; + border: none; + background-color: transparent; + box-shadow: none; + padding: 0.3em; + padding-left: 0; + margin-left: 0; +} +.catalog-actions button.menu > img +{ + height: 1.8em; +} + +@media (max-width: 950px) +{ + .catalog-actions button.menu + { + display: block; + } + .catalog div.menu + { + display: none; + } + .catalog div.center + { + right: 0; + } } diff --git a/web/forms/ecomerce/catalog/ui.xml b/web/forms/ecomerce/catalog/ui.xml index 6fce9b7c..aff6192a 100755 --- a/web/forms/ecomerce/catalog/ui.xml +++ b/web/forms/ecomerce/catalog/ui.xml @@ -29,7 +29,7 @@ SELECT Id_Article item_id FROM vn2008.Articles WHERE #filter; CALL bionic_calc (); - SELECT t.item_id, t.available, t.price, + SELECT t.item_id, t.available, t.price, t.producer, a.Foto, a.Article, a.Categoria, a.Medida, a.Tallos, a.Color, o.Abreviatura FROM tmp.bionic_item t JOIN vn2008.Articles a ON a.Id_Article = t.item_id @@ -59,51 +59,87 @@ +
    +

    Catalog

    +
    +
    + + +
    -
    - - diff --git a/web/forms/ecomerce/checkout/ui.xml b/web/forms/ecomerce/checkout/ui.xml index e89eaf47..3975ecee 100755 --- a/web/forms/ecomerce/checkout/ui.xml +++ b/web/forms/ecomerce/checkout/ui.xml @@ -47,18 +47,17 @@ +
    +

    ConfigureOrder

    +
    +
    + +
    -
    -

    ConfigureOrder

    -
    - -
    -
    -
    +
    +

    OrderSummary

    +
    -
    -

    OrderSummary

    -

    diff --git a/web/forms/ecomerce/invoices/ui.xml b/web/forms/ecomerce/invoices/ui.xml index 74c0c392..7a257509 100755 --- a/web/forms/ecomerce/invoices/ui.xml +++ b/web/forms/ecomerce/invoices/ui.xml @@ -1,27 +1,27 @@ +

    +

    Invoices

    +
    -
    -

    Invoices

    -
    -
    - - - SELECT invoice_id, serial_num, issued, amount - FROM invoice_view - ORDER BY issued DESC - LIMIT 100 - - - - - - -
    +
    + + + SELECT invoice_id, serial_num, issued, amount + FROM invoice_view + ORDER BY issued DESC + LIMIT 100 + + + + + + +
    diff --git a/web/forms/ecomerce/orders/ui.xml b/web/forms/ecomerce/orders/ui.xml index 97a2228a..8fd34645 100755 --- a/web/forms/ecomerce/orders/ui.xml +++ b/web/forms/ecomerce/orders/ui.xml @@ -1,26 +1,25 @@ +
    +

    LastOrders

    +
    +
    +
    + PendingBalance: + + + + Info +
    + + +
    -
    -

    LastOrders

    -
    -
    - PendingBalance: - - - - Info -
    - - -
    -
    -
    diff --git a/web/forms/ecomerce/ticket/ui.xml b/web/forms/ecomerce/ticket/ui.xml index 5f6bc1b8..f4fab0d2 100755 --- a/web/forms/ecomerce/ticket/ui.xml +++ b/web/forms/ecomerce/ticket/ui.xml @@ -18,17 +18,17 @@ +
    +

    OrderDetail

    +
    +
    + +
    -
    -

    OrderDetail

    -
    - -
    -
diff --git a/web/forms/news/new/style.css b/web/forms/news/new/style.css index 7f0704d8..1ff4072b 100755 --- a/web/forms/news/new/style.css +++ b/web/forms/news/new/style.css @@ -33,7 +33,7 @@ } .new textarea { - min-height: 26em; + min-height: 20em; } .new .foot diff --git a/web/forms/news/new/ui.xml b/web/forms/news/new/ui.xml index 26e749a6..f61c460f 100755 --- a/web/forms/news/new/ui.xml +++ b/web/forms/news/new/ui.xml @@ -14,22 +14,17 @@ +
+

AddEditNew

+
+
+ +
-
-

AddEditNew

-
- - -
-
-
diff --git a/web/forms/news/news/ui.xml b/web/forms/news/news/ui.xml index bef968bd..cb50f057 100755 --- a/web/forms/news/news/ui.xml +++ b/web/forms/news/news/ui.xml @@ -1,16 +1,16 @@ +
+

NewsManagement

+
+
+ +
-
-

NewsManagement

-
- -
-
- + SELECT n.id, c.Cliente, priority, image, CONCAT(LEFT(n.title, 25), '...') title diff --git a/web/global/metatags.php b/web/global/metatags.php index 2eab5d07..c32aa588 100755 --- a/web/global/metatags.php +++ b/web/global/metatags.php @@ -4,10 +4,10 @@ use Vn\Hedera\Web; if ($result = Web::$sysConn->query ('SELECT name, content FROM metatag')) { - echo ''."\n\t"; + echo ''."\n\t\t"; while ($row = $result->fetch_assoc ()) - echo ''."\n\t"; + echo ''."\n\t\t"; $result->free (); } diff --git a/web/image/dark/exit.svg b/web/image/dark/exit.svg new file mode 100644 index 00000000..3a23504b --- /dev/null +++ b/web/image/dark/exit.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/web/image/exit.svg b/web/image/exit.svg new file mode 100644 index 00000000..a071c071 --- /dev/null +++ b/web/image/exit.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/web/js/db/conn.js b/web/js/db/conn.js index ca73d908..a469457a 100755 --- a/web/js/db/conn.js +++ b/web/js/db/conn.js @@ -78,13 +78,16 @@ Db.Conn.implement if (success) try { var json = request.getJson (); - openSuccess = true /* json.data */; + openSuccess = json.data == true; } catch (e) {} if (openSuccess) + { this.connected = true; - + this.signalEmit ('openned'); + } + this.signalEmit ('loading-changed', false); if (openCallback) @@ -101,7 +104,7 @@ Db.Conn.implement this.signalEmit ('loading-changed', true); var request = new Vn.HttpRequest (); - request.addValue ({'action': 'close'}); + request.add ({'action': 'close'}); request.send ('rest.php', this.closed.bind (this, closeCallback)); } diff --git a/web/js/db/db.js b/web/js/db/db.js new file mode 100755 index 00000000..d1c3899a --- /dev/null +++ b/web/js/db/db.js @@ -0,0 +1,5 @@ +/** + * The namespace. + **/ +var Db = {}; + diff --git a/web/js/db/main.js b/web/js/db/main.js index d1c3899a..530f57a5 100755 --- a/web/js/db/main.js +++ b/web/js/db/main.js @@ -1,5 +1,17 @@ -/** - * The namespace. - **/ -var Db = {}; + +Vn.includeJs ('js/sql/main.js'); +Vn.includeLib ('db', +[ + 'db' + ,'conn' + ,'result' + ,'result-set' + ,'model' + ,'iterator' + ,'form' + ,'param' + ,'query' + ,'calc' + ,'calc-sum' +]); diff --git a/web/js/db/main.php b/web/js/db/main.php index 0a284f2c..b86348df 100755 --- a/web/js/db/main.php +++ b/web/js/db/main.php @@ -3,7 +3,7 @@ require_once ('js/sql/main.php'); Vn\Hedera\Js::includeLib ('db' - ,'main' + ,'db' ,'conn' ,'result' ,'result-set' diff --git a/web/js/hedera/app.js b/web/js/hedera/app.js new file mode 100644 index 00000000..2048ad4a --- /dev/null +++ b/web/js/hedera/app.js @@ -0,0 +1,87 @@ + +Vn.App = new Class +({ + initialize: function () + { + window.onerror = this.onWindowError.bind (this); + Vn.Hash.initialize (); + + this.conn = new Db.Conn (); + this.login = new Vn.Login ({conn: this.conn}); + } + + ,run: function () + { + if (Vn.Cookie.check ('vn_pass')) + { + this.conn.open (null, null, null, + this.onAutoLogin.bind (this)); + } + else + { + this.login.on ('login', this.onLogin, this); + this.login.show (); + } + } + + ,onAutoLogin: function (success) + { + if (!success) + { + Vn.Cookie.unset ('vn_pass'); + this.run (); + } + else + this.onLogin (); + } + + ,onLogin: function () + { + this.login.disconnectByInstance (this); + this.login.hide (); + + var gui = new Vn.Gui ({conn: this.conn}); + gui.on ('logout', this.onLogout, this); + gui.show (); + } + + ,onLogout: function (gui) + { + gui.hide (); + gui.unref (); + Vn.Cookie.unset ('vn_pass'); + this.run (); + } + + ,onWindowError: function (message, file, line) + { + var error = new Error (message); + error.fileName = file; + error.lineNumber = line; + + Htk.Toast.showError (_('InternalError')); + this.notifyError (error); + } + + ,notifyError: function (error) + { + if (error instanceof Error) + { + var httpRequest = new Vn.HttpRequest () + httpRequest.add + ({ + 'file': error.fileName + ,'line': error.lineNumber + ,'message': error.message + ,'stack': error.stack + }); + httpRequest.send ('log.php'); + } + } + + ,_destroy: function () + { + this.login.unref (); + this.conn.unref (); + } +}); diff --git a/web/js/hedera/gui.css b/web/js/hedera/gui.css new file mode 100755 index 00000000..96624ad4 --- /dev/null +++ b/web/js/hedera/gui.css @@ -0,0 +1,332 @@ + +.vn-gui +{ + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +/* Font */ + +.vn-gui .welcome, +.vn-gui .menu-title, +.vn-gui .main-menu a +{ + font-size: 1.1em; +} + +/* Header */ + +.vn-gui .top-bar, +.vn-gui .exit +{ + height: 3.9em; +} +.vn-gui .top-bar +{ + position: relative; + background-color: #009688; + width: 100%; + z-index: 1; + overflow: hidden; + box-shadow: 0 0.1em 0.1em #AAA; +} +.vn-gui .top-bar +{ + color: white; +} +.vn-gui .menu-button +{ + display: none; + float: left; + border: none; + background-color: transparent; + padding: 0 .4em; + margin: 0; + height: 100%; +} +.vn-gui .menu-button:hover +{ + background-color: rgba(0, 0, 0, .2); +} +.vn-gui .menu-button img +{ + margin-top: .2em; + height: 1.8em; +} +.vn-gui .title +{ + float: left; +} +.vn-gui .title h1 +{ + font-weight: normal; + font-size: 1.4em; + padding: .7em .6em; + margin: 0; +} +.vn-gui .actions-holder +{ + float: right; + padding: .5em 1em; + padding-left: 0; +} +.vn-gui .top-bar > .loader +{ + float: right; + margin: 1.1em; + visibility: hidden; +} +.vn-gui .exit +{ + float: right; + padding: 0 .4em; +} +.vn-gui .exit img +{ + height: 2.2em; + display: block; + margin: .8em auto; +} +.vn-gui .exit:hover +{ + background-color: rgba(0, 0, 0, .2); +} + +/* Body */ + +.vn-gui > .body +{ + position: absolute; + top: 0; + bottom: 0; + left: 15em; + right: 0; +} +.vn-gui .content +{ + position: absolute; + top: 3.9em; + bottom: 0; + left: 0; + right: 0; +} + +/* Left panel */ + +.vn-gui .menu-header +{ + height: 5.5em; + background-color: #333; +} +.vn-gui .logo +{ + width: 12em; + float: left; + margin: 1em; + margin-bottom: .2em; +} +.vn-gui .welcome +{ + float: left; + color: white; + margin: .5em 1em; +} +.vn-gui .background +{ + z-index: 10; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(10, 10, 10, 0.6); + display: none; +} +.vn-gui .left-panel, +.vn-gui .main-menu > li, +.vn-gui ul.submenu +{ + width: 15em; +} +.vn-gui .left-panel +{ + z-index: 20; + position: absolute; + left: 0; + bottom: 0; + top: 0; + background-color: white; + z-index: 20; + box-shadow: 0 0.2em 0.2em #AAA; +} +.vn-gui .menu-overflow +{ + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 4em; + overflow: auto; +} + +/* Test link */ + +.vn-gui .test-link +{ + display: block; + margin: 1em auto; + max-width: 70%; + background-color: #3f51b5; + color: white; + padding: 0 1em; + line-height: 2em; + border-radius: 0.1em; + text-align: center; +} +.vn-gui .test-link:hover +{ + background-color: #4f61c5; +} + +/* Menu */ + +.vn-gui .main-menu +{ + list-style-type: none; + padding: 0; + margin: 0; +} +.vn-gui .main-menu > li +{ + display: block; + float: left; + clear: both; + padding: 0; +} +.vn-gui .main-menu > li > a +{ + line-height: 2.8em; + width: 70%; + padding: 0 15%; +} +.vn-gui .main-menu a +{ + float: left; +} +.vn-gui .main-menu a:hover +{ + background-color: #DDD /* #AC6 */; +} +.vn-gui .main-menu a.selected +{ + background-color: #EEE; +} +.vn-gui ul.submenu +{ + display: none; + position: fixed; + border: none; + border-radius: 1px; + background-color: white; + box-shadow: 0 0.2em 0.2em #CCC; + z-index: 50; + list-style-type: none; + padding-left: 0; +} +.vn-gui ul.submenu a +{ + width: 60%; + padding: 0.7em 20%; +} + +/* Links */ + +.vn-gui .links +{ + position: absolute; + bottom: 0; + right: 0; + padding: 0.8em; +} +.vn-gui .links a +{ + padding: 0.1em; + display: block; + float: left; + max-width: 2.2em; +} +.vn-gui .links img +{ + height: 1.8em; +} + +/* Form holder */ + +.vn-gui .form-holder +{ + position: absolute; + top: 0em; + bottom: 0; + right: 0; + left: 0; + overflow: auto; +} + +/* Transitions */ + +.vn-gui > .left-panel, +.vn-gui > .body +{ + transition: left .3s; + -webkit-transition: left .3s; +} +.vn-gui .top-bar +{ + transition: background-color .3s; + -webkit-transition: background-color .3s; +} + +/* Mobile */ + +@media (max-width: 950px) +{ + .vn-gui > .body + { + left: 0; + } + .vn-gui .menu-button + { + display: block; + } + .vn-gui .left-panel + { + top: 0; + left: -15em; + box-shadow: 0 0.2em 0.2em #333; + } + .vn-gui .left-panel-show + { + left: 0; + } + .vn-gui .form-holder + { + left: 0; + } + .vn-gui ul.submenu + { + display: block; + position: relative; + border: none; + border-radius: 0; + background-color: white; + box-shadow: none; + } + .vn-gui .htk-toast + { + margin-left: -11em; + } +} + diff --git a/web/js/hedera/gui.js b/web/js/hedera/gui.js new file mode 100755 index 00000000..8f92a922 --- /dev/null +++ b/web/js/hedera/gui.js @@ -0,0 +1,526 @@ + +Vn.Gui = new Class +({ + Extends: Htk.Widget, + Properties: + { + conn: + { + set: function (x) + { + this.link ({_conn: x}, + { + 'error': this.onConnError + ,'loading-changed': this.onConnLoading + }); + + var sql = 'SELECT default_form, image_dir FROM config;' + +'SELECT production_domain, test_domain FROM config;' + +'SELECT name FROM customer_view;' + +'CALL form_list ();'; + this.conn.execQuery (sql, this.onMainQueryDone.bind (this)); + }, + get: function () + { + return this._conn; + } + } + } + + ,forms: {} + ,activeForm: null + ,activeCss: null + ,requestedForm: null + ,menuShown: false + ,menuOptions: {} + ,choosedOption: null + + ,initialize: function (props) + { + this.parent (props); + this.builderInit ('js/hedera/gui.xml'); + + this.loadingCount = 0; + this.formHolder = this.$('form-holder'); + + this.hash = Vn.Hash; + this.hashParam = new Vn.HashParam ({key: 'form'}); + this.hashParam.on ('changed', this.onFormChange, this); + + this.$('background').onclick = function () {}; + + this.$('menu-button').addEventListener ('click', function (event) + { + event.stopPropagation (); + this.showMenu (); + }.bind (this)); + + this.$('left-panel').addEventListener ('click', function (event) + { + event.stopPropagation (); + }); + + if (!Vn.Cookie.check ('hedera_cookies')) + { + Vn.Cookie.set ('hedera_cookies', true); + Htk.Toast.showWarning (_('CookiesNotification')); + } + } + + ,show: function () + { + document.body.appendChild (this.node); + } + + ,hide: function () + { + Vn.Node.remove (this.node); + } + + ,onLogoutClick: function () + { + this.conn.close (this.onConnClose.bind (this)); + } + + ,onConnClose: function () + { + this.signalEmit ('logout'); + } + + ,showBackground: function () + { + Vn.Node.show (this.$('background')); + } + + ,hideBackground: function () + { + Vn.Node.hide (this.$('background')); + } + + ,showMenu: function () + { + this.showBackground (); + Vn.Node.addClass (this.$('left-panel'), 'left-panel-show'); + this.menuShown = true; + + this.hideMenuCallback = this.hideMenu.bind (this); + document.addEventListener ('click', this.hideMenuCallback); + } + + ,hideMenu: function () + { + if (!this.menuShown) + return; + + this.hideBackground (); + Vn.Node.removeClass (this.$('left-panel'), 'left-panel-show'); + this.menuShown = false; + + document.removeEventListener ('click', this.hideMenuCallback); + this.hideMenuCallback = null; + } + + ,onMainQueryDone: function (resultSet) + { + // Retrieving configuration parameters + + var res = resultSet.fetchResult (); + var columns = res.columns; + + if (res.next ()) + for (var i = 0; i < res.columns.length; i++) + Vn.Config[columns[i].name] = res.get (columns[i].name); + + // Retrieving configuration parameters + + var res = resultSet.fetchResult (); + + if (res.next () && res.get ('test_domain')) + { + if (location.host != res.get ('production_domain')) + { + var linkText = 'ReturnToOldWebsite'; + var linkField = 'production_domain'; + } + else + { + var linkText = 'TestTheNewWebsite'; + var linkField = 'test_domain'; + } + + Vn.Node.setText (this.$('test-link'), _(linkText)); + this.$('test-link').href = '//'+ res.get (linkField); + } + else + Vn.Node.hide (this.$('test-link')); + + // Retrieving the user name + + var userName = resultSet.fetchValue (); + + if (userName) + { + var span = this.$('user-name'); + span.appendChild (document.createTextNode (userName)); + } + + // Retrieving menu sections + + var res = resultSet.fetchResult (); + var sectionMap = {}; + + if (res) + for (var i = 0; res.next (); i++) + { + var parent = res.get ('parent'); + + if (!sectionMap[parent]) + sectionMap[parent] = []; + + sectionMap[parent].push (i); + } + + this.createMenu (res, sectionMap, null, this.$('main-menu')); + + // Loading the default form + + this.onFormChange (); + } + + ,notifyError: function (error) + { + if (error instanceof Error) + { + var httpRequest = new Vn.HttpRequest () + httpRequest.add + ({ + 'file': error.fileName + ,'line': error.lineNumber + ,'message': error.message + ,'stack': error.stack + }); + httpRequest.send ('log.php'); + } + } + + ,errorHandler: function (error) + { + if (error instanceof Vn.Error) + switch (error.domain) + { + case 'Auth': + Htk.Toast.showError (_('SessionExpired')); + this.signalEmit ('logout'); + break; + case 'Version': + this.newVersion (error); + break; + case 'User': + Htk.Toast.showError (error.message); + break; + default: + console.error (error.message); + Htk.Toast.showError (_('InternalError')); + } + else + { + console.error (error); + Htk.Toast.showError (_('InternalError')); + this.notifyError (error); + } + } + + ,onConnError: function (conn, error) + { + this.errorHandler (error); + } + + ,onConnLoading: function (conn, isLoading) + { + if (isLoading) + this.loaderPush (); + else + this.loaderPop (); + } + + ,loaderPush: function () + { + this.loadingCount++; + + if (this.loadingCount == 1) + this.$('loader').style.visibility = 'visible'; + } + + ,loaderPop: function () + { + if (this.loadingCount == 0) + return; + + this.loadingCount--; + + if (this.loadingCount == 0) + this.$('loader').style.visibility = 'hidden'; + } + + ,newVersion: function (error) + { + if (this.newVersionBlock || this.skipVersion) + return; + + this.newVersionBlock = true; + + var reload; + var message = _('NewVersionAvailable') +"\n\n"+ error.message; + + if (error.code == 'criticalVersion') + { + alert (message) + reload = true; + } + else + { + reload = confirm (message); + this.skipVersion = true; + } + + if (reload) + location.reload (); + + this.newVersionBlock = false; + } + + ,createMenu: function (res, sectionMap, parent, ul) + { + var sections = sectionMap[parent]; + + for (var i = 0; i < sections.length; i++) + { + res.row = sections[i]; + + var li = document.createElement ('li'); + ul.appendChild (li); + + var a = document.createElement ('a'); + a.href = Vn.Hash.make ({'form': res.get ('path')}); + this.menuOptions[res.get ('path')] = a; + li.appendChild (a); + + var text = document.createTextNode (_(res.get ('description'))); + a.appendChild (text); + + var formId = res.get ('id'); + + if (sectionMap[formId]) + { + var submenu = document.createElement ('ul'); + submenu.className = 'submenu'; + li.appendChild (submenu); + + li.addEventListener ('mouseover', + this.onLiMouseHover.bind (this, submenu, a)); + li.addEventListener ('mouseout', + this.onLiMouseOut.bind (this)); + + this.createMenu (res, sectionMap, formId, submenu); + } + } + } + + ,onLiMouseHover: function (submenu, parent) + { + if (Vn.isMobile ()) + return; + + this.hideSubmenu (); + this.activeSubmenu = submenu; + + var rect = parent.getBoundingClientRect (); + submenu.style.display = 'inline'; + submenu.style.left = rect.right +'px'; + submenu.style.top = rect.top +'px'; + } + + ,onLiMouseOut: function () + { + this.timeout = setTimeout (this.hideSubmenu.bind (this), 160); + } + + ,hideSubmenu: function () + { + var submenu = this.activeSubmenu; + + if (submenu) + { + submenu.style.display = 'none'; + clearTimeout (this.timeout); + this.activeSubmenu = null; + this.timeout = 0; + } + } + + ,onFormChange: function () + { + var formPath = this.hashParam.value; + this.openForm (formPath ? formPath : Vn.Config['default_form'], null); + } + + ,openForm: function (formPath, callback) + { + this.hideMenu (); + this.loaderPush (); + + this.requestedForm = formPath; + + var formInfo = this.forms[formPath]; + var path = 'forms/'+ formPath; + + if (this.activeForm) + { + this.setTitle (null); + this.setActions (null); + this.activeForm.deactivate (); + this.activeForm.close (); + this.activeForm.unref (); + this.activeForm = null; + } + + if (this.activeCss) + { + Vn.excludeCss (this.activeCss +'/style.css'); + + if (Vn.isMobile ()) + Vn.excludeCss (this.activeCss +'/mobile.css'); + } + + this.activeCss = path; + + Vn.includeCss (this.activeCss +'/style.css'); + + if (Vn.isMobile ()) + Vn.includeCss (this.activeCss +'/mobile.css'); + + if (!formInfo) + { + var aux = formPath.split ('/'); + var formName = aux[aux.length - 1]; + + var klass = 'Vn.'+ formName.charAt (0).toUpperCase (); + klass += formName.substr (1).replace (/\w\-\w/g, function (token) + { + return token.charAt (0) + token.charAt (2).toUpperCase (); + }); + + formInfo = { + path: formPath + ,klass: klass + ,localeReady: false + ,jsReady: false + ,uiReady: false + ,error: false + ,ready: false + ,callbacks: [] + }; + + Vn.Locale.load (path, + this.onFormLocaleReady.bind (this, formInfo)); + Vn.includeJs (path +'/'+ formName +'.js', + this.onFormJsReady.bind (this, formInfo)); + Vn.loadXml ('forms/'+ formPath +'/ui.xml', + this.onFormUiReady.bind (this, formInfo)); + + this.forms[formPath] = formInfo; + } + + var newChoosedOption = this.menuOptions[formInfo.path]; + + if (newChoosedOption) + { + if (this.choosedOption) + this.choosedOption.className = null; + + newChoosedOption.className = 'selected'; + this.choosedOption = newChoosedOption; + } + + if (callback) + formInfo.callbacks.push (callback); + if (formInfo.ready) + this.onFormReady (formInfo); + } + + ,onFormLocaleReady: function (formInfo, success) + { + formInfo.localeReady = true; + this.onFormReady (formInfo); + } + + ,onFormJsReady: function (formInfo, success) + { + formInfo.jsReady = true; + formInfo.error = !success; + this.onFormReady (formInfo); + } + + ,onFormUiReady: function (formInfo, success) + { + formInfo.uiReady = true; + formInfo.error = !success; + this.onFormReady (formInfo); + } + + ,onFormReady: function (formInfo) + { + if (!(formInfo.localeReady && formInfo.jsReady && formInfo.uiReady)) + return; + + formInfo.ready = true; + + if (!formInfo.error) + { + if (formInfo.path == this.requestedForm) + try { + var klass = eval (formInfo.klass); + this.activeForm = new klass (this, formInfo); + this.activeForm.open (); + this.activeForm.activate (); + } + catch (e) { + formInfo.error = true; + this.errorHandler (e); + } + } + else + Htk.Toast.showError (_('ErrorLoadingForm')); + + var callbacks = formInfo.callbacks; + formInfo.callbacks = []; + + for (var i = 0; i < callbacks.length; i++) + callbacks[i] (this.activeForm); + + this.loaderPop (); + } + + ,setTitle: function (title) + { + Vn.Node.removeChilds (this.$('title')); + + if (title) + this.$('title').appendChild (title); + } + + ,setActions: function (actions) + { + Vn.Node.removeChilds (this.$('actions-holder')); + + if (actions) + this.$('actions-holder').appendChild (actions); + } + + ,_destroy: function () + { + this.hashParam.unref (); + this.parent (); + } +}); + diff --git a/web/js/hedera/gui.xml b/web/js/hedera/gui.xml new file mode 100755 index 00000000..de606756 --- /dev/null +++ b/web/js/hedera/gui.xml @@ -0,0 +1,49 @@ + +
+
+ + +
+
+
+ + + _Exit + +
+
+ +
+
+
+
+
+
+
+
+
+ diff --git a/web/js/hedera/hedera.js b/web/js/hedera/hedera.js new file mode 100644 index 00000000..665fe387 --- /dev/null +++ b/web/js/hedera/hedera.js @@ -0,0 +1,4 @@ +/** + * Namespace + **/ +var Hedera = {}; diff --git a/web/js/hedera/login.css b/web/js/hedera/login.css new file mode 100755 index 00000000..9b7c7da2 --- /dev/null +++ b/web/js/hedera/login.css @@ -0,0 +1,162 @@ + +.vn-login, +.vn-login label, +.vn-login button, +.vn-login input, +.vn-login textarea, +.vn-login p, +.vn-login a +{ + font-size: 1.2em; + font-weight: normal; + color: #333; +/* text-shadow: 0 0.2em 0.2em #AAA; */ +} + +/* Header */ + +.vn-login .header +{ + z-index: 10; + position: absolute; + background-color: #333; + width: 100%; + height: 3.5em; + +} +.vn-login .header div +{ + margin-top: 1em; + text-align: center; +} +.vn-login .header a +{ + color: white; +} + +/* Body */ + +.vn-login .body +{ + position: absolute; + top: 3.5em; + left: 0; + right: 0; + bottom: 0; +/* background-image: url("background.png"); + background-repeat: repeat; +*/ +} +.vn-login .column +{ + position: relative; + margin: 0 auto; + overflow: auto; + max-width: 40em; + height: 100%; + background-color: white; + box-shadow: 0 0.2em 0.2em #DDD; +} + +/* Login */ + +.vn-login .login +{ + position: absolute; + margin-top: -17em; + padding: 1em; + max-width: 45em; + top: 50%; + left: 0; + right: 0; + +} +.vn-login .logo img +{ + display: block; + margin: 0.5em auto; + min-width: 20em; + width: 75%; +} +.vn-login .version-code +{ + color: red; + text-align: right; + margin: 0.2em auto; + font-weight: bold; + height: 1.6em; +} +.vn-login .form-inputs +{ + margin: 0 auto; + max-width: 16em; +} +.vn-login label +{ + margin: 0; +} +.vn-login div.form-group label +{ + display: block; +} +.vn-login input +{ + border-radius: 0.1em; + box-shadow: 0 0.1em 0.1em #AAA; + margin: 0.3em; +} +.vn-login input[type=text], +.vn-login input[type=password] +{ + margin: 0.5em 0; + margin-bottom: 0.5em; + padding: 0.5em; + width: 100%; + border: 1px solid #AAA; +} +.vn-login td.entry +{ + text-align: left; +} +.vn-login input[type=submit] +{ + display: block; + margin: 0 auto; + background-color: #AD4; + border: 1px solid #8B2; + height: 2.4em; + width: 8em; + color: #250; +} +.vn-login input[type=submit]:hover +{ + background-color: #9C3; +} +.vn-login .bottom +{ + text-align: center; + padding: 1em; +} + +/* Info */ + +.vn-login .info +{ + margin-top: 2em; + text-align: center; +} +.vn-login .info p +{ + margin: 0.5em; +} +.vn-login .links +{ + margin: 0 auto; + margin-top: 2em; + text-align: center; +} +.vn-login .links img +{ + height: 1.8em; +} + diff --git a/web/js/hedera/login.js b/web/js/hedera/login.js new file mode 100755 index 00000000..60fc4aae --- /dev/null +++ b/web/js/hedera/login.js @@ -0,0 +1,74 @@ + +Vn.Login = new Class +({ + Extends: Htk.Widget + + ,initialize: function (props) + { + this.parent (props); + this.builderInit ('js/hedera/login.xml'); + + var self = this; + this.$('form').onsubmit = function () + { + self.onSubmit (); + return false; + }; + } + + ,show: function () + { + document.body.appendChild (this.node); + + if (Vn.Cookie.check ('vn_user')) + this.$('user').value = Vn.Cookie.get ('vn_user'); + + this.focusUserInput (); + } + + ,hide: function () + { + Vn.Node.remove (this.node); + } + + ,focusUserInput: function () + { + var userEntry = this.$('user'); + userEntry.focus (); + userEntry.select (); + } + + ,disableInputs: function (disabled) + { + this.$('user').disabled = disabled; + this.$('pass').disabled = disabled; + this.$('submit').disabled = disabled; + } + + ,onSubmit: function () + { + this.disableInputs (true); + this.conn.open ( + this.$('user').value, + this.$('pass').value, + this.$('remember').value, + this.onConnOpen.bind (this) + ); + } + + ,onConnOpen: function (conn, success) + { + this.$('pass').value = ''; + + if (!success) + { + Htk.Toast.showError (_('InvalidLogin')); + } + else + this.signalEmit ('login'); + + this.disableInputs (false); + this.focusUserInput (); + } +}); + diff --git a/web/js/hedera/login.xml b/web/js/hedera/login.xml new file mode 100755 index 00000000..768933f0 --- /dev/null +++ b/web/js/hedera/login.xml @@ -0,0 +1,57 @@ + + + diff --git a/web/js/hedera/main.js b/web/js/hedera/main.js new file mode 100644 index 00000000..e0083edf --- /dev/null +++ b/web/js/hedera/main.js @@ -0,0 +1,19 @@ + +Vn.includeCss ('js/hedera/style.css'); +Vn.includeCss ('js/hedera/gui.css'); +Vn.includeCss ('js/hedera/login.css'); + +Vn.loadXml ('js/hedera/login.xml'); +Vn.loadXml ('js/hedera/gui.xml'); + +Vn.includeJs ('js/htk/main.js'); +Vn.includeLib ('hedera', +[ + 'hedera' + ,'login' + ,'gui' + ,'module' + ,'app' + ,'tpv' +]); + diff --git a/web/js/hedera/module.js b/web/js/hedera/module.js new file mode 100755 index 00000000..b3bc1028 --- /dev/null +++ b/web/js/hedera/module.js @@ -0,0 +1,88 @@ + +Vn.Module = new Class +({ + Extends: Vn.Object + + ,initialize: function (gui, formInfo) + { + this.gui = gui; + this.conn = gui.conn; + this.hash = gui.hash; + this.formInfo = formInfo; + } + + /** + * Gets an object from the builder associated to this form. + * + * @param {string} objectId The object identifier + * @return {Object} The object, or %null if not found + **/ + ,$: function (objectId) + { + if (this.builder) + return this.builder.get (objectId); + + return null; + } + + /** + * Called when the form is opened. + **/ + ,open: function () + { + this.close (); + + this.builder = new Vn.Builder (); + this.builder.signalData = this; + this.builder.loadXml (Vn.getXml ('forms/'+ this.formInfo.path +'/ui.xml')); + this.node = this.builder.get ('form'); + + var models = this.builder.getObjects ('db-model'); + + for (var i = 0; i < models.length; i++) + models[i].conn = this.conn; + + var queries = this.builder.getObjects ('db-query'); + + for (var i = 0; i < queries.length; i++) + queries[i].conn = this.conn; + + this.gui.formHolder.appendChild (this.node); + this.gui.setTitle (this.builder.$('title')); + this.gui.setActions (this.builder.$('actions')); + } + + /** + * Called when the form is activated. + **/ + ,activate: function () {} + + /** + * Called when the form is deactivated. + **/ + ,deactivate: function () {} + + /** + * Called when the form is closed. + **/ + ,close: function () + { + if (this.node) + { + Vn.Node.remove (this.node); + this.node = null; + } + if (this.builder) + { + this.builder.unref (); + this.builder = null; + } + } + + ,_destroy: function () + { + this.close (); + this.parent (); + } +}); + diff --git a/web/js/hedera/style.css b/web/js/hedera/style.css new file mode 100755 index 00000000..060934ce --- /dev/null +++ b/web/js/hedera/style.css @@ -0,0 +1,382 @@ + +/* Responsive */ + +@media screen +{ + * { font-size: 12pt; } +} +@media (min-resolution: 120dpi) and (orientation: portrait) +{ + * { font-size: 11pt; } +} +@media (min-resolution: 120dpi) and (orientation: landscape) +{ + * { font-size: 11pt; } +} + +/* Global */ + +body +{ + margin: 0; +} +body, +label, +button, +input, +textarea +{ + font-size: 1em; + font-family: 'Open Sans', 'Verdana', 'Sans'; +} +iframe +{ + border: 0; +} +fieldset, +div +{ + margin: 0; +} +form +{ + padding: 0; + margin: 0; +} +table +{ + width: 100%; +} +a:link, +a:visited, +a:active +{ + color: #000; + text-decoration: none; +} +a:hover +{ + text-decoration: none; + cursor: pointer; +} +a img +{ + padding: 1px; +} +h1, h2, h3, h4, h5, h6 +{ + margin: 0; + padding: 0.2em; +} +h1 +{ + font-size: 1.5em; +} +h2 +{ + font-size: 1.3em; +} +p +{ + margin: 0.8em 0; +} + +/* Inputs */ + +input[type=text], +input[type=password], +input[type=file], +input[type=number], +textarea, +select +{ + border: 1px solid #CCD; + margin: 0.2em; + border-radius: 0.1em; + box-shadow: 0 0.1em 0.1em #CCC; +} + +input[type=text], +input[type=password], +input[type=file], +input[type=number], +textarea +{ + padding: 0.3em; +} +select +{ + background-color: white; + font-size: 1.1em; + height: 1.8em; +} +option +{ + padding: 0.3em; + border-width: 0; + font-weight: normal; + font-size: 1em; +} +select, +option +{ + cursor: pointer; +} +input[type=text], +input[type=password] +{ + height: 1.6em; +} +textarea +{ + height: 3.5em; + width: 20em; +} +input[type=text]:focus, +input[type=password]:focus, +textarea:focus +{ + background-color: #EEF; + border-color: #BBC; +} +input[type=checkbox], +input[type=radio] +{ + cursor: pointer; + margin: 0.2em; + padding: 0.3em; + width: 0.8em; + height: 0.8em; +} + +/* Buttons */ + +button, +input[type=submit], +input[type=button] +{ + border: none; + background-color: transparent; + color: white; + padding: 0.5em; + cursor: pointer; + border-radius: 0.1em; +} +button:hover, +input[type=submit]:hover, +input[type=button]:hover +{ + background-color: rgba(1, 1, 1, 0.1); +} + +/* Flat button */ + +button.flat, +input.button +{ + border: none; + border-radius: 0.1em; + box-shadow: 0 0.2em 0.2em #DDD; + background-color: #AD4; + color: black; +} +button.flat:hover, +input.button:hover +{ + background-color: #9C3; + cursor: pointer; +} +button.flat:disabled, +input.button:disabled +{ + color: gray; +} + +/* Thin button */ + +button.thin +{ + background-color: transparent; + border: none; + color: #008D77; + text-transform: uppercase; +} +button.thin:hover +{ + background-color: rgba(1,1,1,0.1); +} +button.thin:disabled +{ + color: gray; +} + +/* Image */ + +img.editable +{ + cursor: pointer; +} + +/* Button */ + +.htk-button img +{ + height: 1.5em; +} + +/* Float */ + +.clear +{ + clear: both; +} + +/* Box */ + +.box +{ + background-color: white; + margin: 0 auto; + border-radius: 0.1em; + box-shadow: 0 0.2em 0.2em #CCC; +} +.box .header +{ + padding: 0.6em 0.8em; + margin: 0; + background-color: #009688; + color: white; +} +.box .header > h1 +{ + color: white; + text-align: left; + font-size: 1.6em; + line-height: 2em; + font-weight: normal; + display: inline; +} +.box .body +{ + padding: 2em; +} + +/* Form */ + +.form +{ + margin: 0 auto; +} + +.form-group +{ + padding: 0.4em; +} +.form-group > label +{ + display: block; + margin-bottom: 0.5em; +} +.form-group > input[type=text], +.form-group > input[type=password], +.form-group > select, +.form-group > textarea +{ + margin: 0; + width: 100%; +} + +/* Action bar */ + +.action-bar +{ + float: right; + padding: 0; + margin-top: 0.3em; +} +.action-bar > * +{ + float: left; + padding: 0.4em; +} +.action-bar > button +{ + border-left: 1px solid white; +} +.action-bar > button:first-child +{ + border-left: none; +} +.action-bar > button:hover +{ + background-color: rgba(1, 1, 1, 0.2); +} +.action-bar > button > img +{ + vertical-align: middle; + margin-right: 0.4em; + height: 1.4em; +} + +/* Form */ + +table.form +{ + padding: 1em; + border-collapse: separate; + border-spacing: 0.3em; +} +table.form td.label +{ + width: 45%; + text-align: right; +} +table.form tr +{ + height: 2.8em; +} + +/* Icon */ + +img.icon +{ + height: 1.5em; +} + +/* Masonry */ + +.masonry +{ + margin: 0 auto; + text-align: left; +} +.masonry-box +{ + width: 100%; + display: inline-block; + vertical-align: top; +} +@media screen and (min-width: 1000px) and (max-width: 1399px) +{ + .masonry-box + { + width: 50%; + display: block; + float: left; + clear: left; + } + .masonry-box:nth-child(2n+0) + { + float: right; + clear: right; + } +} +@media screen and (min-width: 1400px) +{ + .masonry-box { width: 33.3%; } +} +@media screen and (min-width: 2000px) +{ + .masonry-box { width: 25%; } +} + diff --git a/web/js/hedera/tpv.js b/web/js/hedera/tpv.js new file mode 100755 index 00000000..562e6380 --- /dev/null +++ b/web/js/hedera/tpv.js @@ -0,0 +1,124 @@ + +Vn.Tpv = +{ + check: function (conn) + { + var tpvStatus = Vn.Hash.get ('tpv_status'); + + if (tpvStatus) + { + var batch = new Sql.Batch (); + batch.addValue ('transaction', Vn.Hash.get ('tpv_order')); + batch.addValue ('status', tpvStatus); + + var query = 'CALL transaction_end (#transaction, #status)'; + + conn.execQuery (query, null, batch); + } + } + + ,pay: function (conn, amount, company) + { + if (amount > 0) + { + var query = 'CALL transaction_start (#company, #amount)'; + + var batch = new Sql.Batch (); + batch.addValue ('company', company); + batch.addValue ('amount', parseInt (amount * 100)); + + conn.execQuery (query, + this._onTransactionStart.bind (this), batch); + } + else if (!isNaN (amount)) + Htk.Toast.showError (_('AmountError')); + } + + ,_onTransactionStart: function (resultSet) + { + var res = resultSet.fetchResult (); + + if (res && res.next ()) + { + var form = document.createElement ('form'); + form.method = 'post'; + form.action = res.get ('url'); + document.body.appendChild (form); + + var fieldsMap = + { + 'Ds_Merchant_Amount': 'amount' + ,'Ds_Merchant_Order': 'ds_order' + ,'Ds_Merchant_MerchantCode': 'id' + ,'Ds_Merchant_Currency': 'currency' + ,'Ds_Merchant_TransactionType': 'transaction_type' + ,'Ds_Merchant_Terminal': 'terminal' + ,'Ds_Merchant_MerchantURL': 'merchant_url' + ,'Ds_Merchant_MerchantSignature': 'signature' + ,'Ds_Merchant_UrlOK': null + ,'Ds_Merchant_UrlKO': null + }; + + for (var field in fieldsMap) + { + var input = document.createElement ('input'); + input.type = 'hidden'; + input.name = field; + form.appendChild (input); + + if (fieldsMap[field]) + input.value = res.get (fieldsMap[field]); + } + + var transactionId = res.get ('ds_order'); + form['Ds_Merchant_UrlOK'].value = this._makeUrl ('ok', transactionId); + form['Ds_Merchant_UrlKO'].value = this._makeUrl ('ko', transactionId); + + form.submit (); + } + else + Htk.Toast.showWarning (_('PayError')); + } + + ,_makeUrl: function (status, order) + { + var path = location.protocol +'//'+ location.host; + path += location.port ? ':'+ location.port : ''; + path += location.pathname; + path += location.search ? location.search : ''; + path += Vn.Hash.make ({ + 'form': 'ecomerce/orders', + 'tpv_status': status, + 'tpv_order': order + }, true); + + return path; + } +}; + +Vn.BasketChecker = +{ + check: function (conn, callback) + { + conn.execQuery ('CALL basket_check ()', + this._onBasketCheck.bind (this, callback)); + } + + ,_onBasketCheck: function (callback, resultSet) + { + var status = resultSet.fetchValue (); + + if (!status) + return; + + var isOk = status == 'UPDATED' || status == 'OK'; + + if (status == 'UPDATED') + Htk.Toast.showWarning (_('OrderItemsUpdated')); + if (callback) + callback (isOk); + if (!isOk) + Vn.Hash.set ({'form': 'ecomerce/checkout'}); + } +}; + diff --git a/web/js/htk/htk.js b/web/js/htk/htk.js index f07e8df2..63ad1fd0 100755 --- a/web/js/htk/htk.js +++ b/web/js/htk/htk.js @@ -1,36 +1,4 @@ -include ([ - 'js/db/db.js', - 'js/htk/js/htk/main', - 'js/htk/widget', - 'js/htk/popup', - 'js/htk/toast', - 'js/htk/repeater', - 'js/htk/grid', - 'js/htk/full-image', - 'js/htk/image-editor', - 'js/htk/field', - 'js/htk/field/text', - 'js/htk/field/html', - 'js/htk/field/entry', - 'js/htk/field/radio-group', - 'js/htk/field/radio', - 'js/htk/field/label', - 'js/htk/field/text-area', - 'js/htk/field/spin', - 'js/htk/field/check', - 'js/htk/field/select', - 'js/htk/field/calendar', - 'js/htk/field/date-chooser', - 'js/htk/field/image', - 'js/htk/field/button', - 'js/htk/field/table', - 'js/htk/column', - 'js/htk/column/button', - 'js/htk/column/link', - 'js/htk/column/date', - 'js/htk/column/image', - 'js/htk/column/radio', - 'js/htk/column/spin', - 'js/htk/column/text', - 'js/htk/column/check' -]); +/** + * The namespace. + **/ +var Htk = {}; diff --git a/web/js/htk/image-editor.js b/web/js/htk/image-editor.js index 9cf8269c..c7c5ea8a 100755 --- a/web/js/htk/image-editor.js +++ b/web/js/htk/image-editor.js @@ -1,11 +1,15 @@ +/** + * A form to handle the image database, it allows to add new images or replace it + **/ Htk.ImageEditor = new Class ({ Extends: Htk.Widget ,Xml: 'js/htk/image-editor.xml' - ,initialize: function () + ,initialize: function (props) { - this.builderInit (Htk.ImageEditor.Xml); + this.parent (props) + this.builderInit (this.constructor.Xml); this.$('max-size').value = 10 /* MB */ * 1048576; } @@ -21,7 +25,7 @@ Htk.ImageEditor = new Class } ,onIframeLoad: function () - { + { this.$('submit').disabled = false; this.$('loader').style.visibility = 'hidden'; diff --git a/web/js/htk/loader.css b/web/js/htk/loader.css new file mode 100644 index 00000000..d1fbb82e --- /dev/null +++ b/web/js/htk/loader.css @@ -0,0 +1,74 @@ + +.htk-loader +{ + font-size: 10px; + margin: 50px auto; + text-indent: -9999em; + width: 11em; + height: 11em; + border-radius: 50%; + background: #ffffff; + background: -moz-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: -webkit-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: -o-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: -ms-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + position: relative; + -webkit-animation: load3 1.4s infinite linear; + animation: load3 1.4s infinite linear; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +} +.htk-loader:before +{ + width: 50%; + height: 50%; + background: #ffffff; + border-radius: 100% 0 0 0; + position: absolute; + top: 0; + left: 0; + content: ''; +} +.htk-loader:after +{ + background: #0dc5c1; + width: 75%; + height: 75%; + border-radius: 50%; + content: ''; + margin: auto; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} +@-webkit-keyframes load3 +{ + 0% + { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% + { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes load3 +{ + 0% + { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% + { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + diff --git a/web/js/htk/loader.js b/web/js/htk/loader.js new file mode 100755 index 00000000..1c42f564 --- /dev/null +++ b/web/js/htk/loader.js @@ -0,0 +1,12 @@ +Htk.Loader = new Class +({ + Extends: Htk.Widget + ,Tag: 'htk-loader' + + ,initialize: function (props) + { + this.parent (props); + var loader = this.createElement ('div'); + loader.className = 'htk-loader'; + } +}); diff --git a/web/js/htk/main.js b/web/js/htk/main.js index 63ad1fd0..e28a7240 100755 --- a/web/js/htk/main.js +++ b/web/js/htk/main.js @@ -1,4 +1,42 @@ -/** - * The namespace. - **/ -var Htk = {}; + +Vn.includeCss ('js/htk/style.css'); +Vn.includeJs ('js/db/main.js'); +Vn.includeLib ('htk', +[ + 'htk' + ,'widget' + ,'popup' + ,'toast' + ,'repeater' + ,'grid' + ,'loader' + ,'full-image' + ,'image-editor' + ,'assistant' + ,'assistant-bar' + ,'field' + ,'field/text' + ,'field/html' + ,'field/entry' + ,'field/radio-group' + ,'field/radio' + ,'field/label' + ,'field/text-area' + ,'field/spin' + ,'field/check' + ,'field/select' + ,'field/calendar' + ,'field/date-chooser' + ,'field/image' + ,'field/button' + ,'field/table' + ,'column' + ,'column/button' + ,'column/link' + ,'column/date' + ,'column/image' + ,'column/radio' + ,'column/spin' + ,'column/text' + ,'column/check' +]); diff --git a/web/js/htk/main.php b/web/js/htk/main.php index f01f4c1b..25bea914 100755 --- a/web/js/htk/main.php +++ b/web/js/htk/main.php @@ -3,7 +3,7 @@ require_once ('js/db/main.php'); Vn\Hedera\Js::includeLib ('htk' - ,'main' + ,'htk' ,'widget' ,'popup' ,'toast' diff --git a/web/js/htk/style.css b/web/js/htk/style.css new file mode 100755 index 00000000..c536a860 --- /dev/null +++ b/web/js/htk/style.css @@ -0,0 +1,505 @@ + +/* Grid */ + +.htk-grid +{ + margin: auto; + border-collapse: collapse; + text-align: center; +} +.htk-grid > thead > tr, +.htk-grid > tfoot > tr +{ + background-color: #009688; + vertical-align: middle; + text-align: center; + height: 3em; +} +.htk-grid > thead th +{ + color: white; + cursor: pointer; + font-weight: normal; + padding: 0 0.4em; +} +.htk-grid > thead th:hover +{ + background-color: rgba(1, 1, 1, 0.2); +} +.htk-grid tr +{ + height: 3.5em; +} +.htk-grid > tfoot a, +.htk-grid > thead a +{ + color: black; +} +.htk-grid tr.pair-row +{ + background-color: transparent; +} +.htk-grid .message +{ + height: 5em; +} +.htk-grid .message img +{ + vertical-align: middle; + padding: 0.8em; + height: 1.8em; +} +.htk-grid > tbody tr +{ + border-top: 1px solid #DDD; +} +.htk-grid > tbody tr:first-child +{ + border-top: none; +} +.htk-grid > tbody td +{ + margin: 0; + padding: 0 0.5em; +} +.htk-grid > tbody td:first-child, +.htk-grid > thead th:first-child +{ + padding-left: 1em; +} +.htk-grid > tbody td:last-child, +.htk-grid > thead th:last-child +{ + padding-right: 1em; +} +.htk-grid .cell-spin +{ + width: 2.5em; + text-align: right; +} +.htk-grid .cell-button +{ + margin: 0; + padding: 0.5em; + border: none; + background-color: transparent; + border-radius: 0.1em; +} +.htk-grid .cell-button:hover +{ + background-color: rgba(1, 1, 1, 0.1); +} +.htk-grid .cell-button img +{ + height: 1.5em; + display: block; + margin: auto; +} +.htk-grid .cell-image > img +{ + max-width: 2.5em; + max-height: 2.5em; + display: block; + margin: auto; +} + +/* Repater */ + +.htk-repeater > .message +{ + padding: 1em 0; + text-align: center; +} +.htk-repeater > .message > * +{ + vertical-align: middle; +} +.htk-repeater > .message > img +{ + padding: 0.8em; + padding-left: 0; + height: 1.8em; +} + +/* Calendar */ + +.htk-calendar +{ + width: 20em; + background-color: white; + border: none; +} +.htk-calendar table +{ + border-collapse: collapse; +} +.htk-calendar thead tr, +.htk-calendar tfoot tr +{ + background-color: #009688; + color: white; + font-weight: normal; + vertical-align: middle; + text-align: center; + height: 3em; +} +.htk-calendar thead span +{ + color: white; +} +.htk-calendar thead tr +{ + border-bottom: none; +} +.htk-calendar tfoot tr +{ + border-top: none; +} +.htk-calendar th.button:hover +{ + cursor: pointer; + background-color: rgba(1, 1, 1, 0.2); +} +.htk-calendar col +{ + width: 14.2%; +} +.htk-calendar tr +{ + height: 2em; +} +.htk-calendar tbody td +{ + text-align: right; +} +.htk-calendar tbody td > div +{ + height: 2em; + width: 2em; + line-height: 2em; + text-align: center; + border-radius: 2em; + padding: 0.3em; + margin: 0 auto; + color: #555; +} +.htk-calendar div.disabled +{ + color: #999; +} +.htk-calendar div.today +{ + font-weight: bold; + color: black; +} +.htk-calendar div.selected +{ + color: white; + background-color: #009688; +} +.htk-calendar div.enabled:hover +{ + cursor: pointer; + background-color: #008678; + color: white; +} + +/* Date chooser */ + +.htk-date-chooser > button +{ + margin: 0.2em; + padding: 0.3em; + background-color: white; + color: black; + text-align: left; + min-width: 9em; + min-height: 2.3em; + border: 1px solid #CCD; + border-radius: 0.1em; + box-shadow: 0 0.1em 0.1em #CCC; +} + +/* Full image */ + +.htk-full-image +{ + z-index: 100; + position: fixed; + background-color: #FFF; + text-align: center; + border: 1px solid #999; + border-radius: 2px; +} +.htk-full-image-loader +{ + z-index: 110; + position: fixed; + background-color: #FFF; + border: 1px solid #999; + border-radius: 0.1em; +} +.htk-full-image-loader img +{ + padding: 1em; +} + +/* Toast */ + +.htk-toast +{ + z-index: 210; + display: block; + position: fixed; + left: 50%; + top: 4em; + width: 21em; + margin-left: -11em; + text-align: center; + overflow: auto; + max-height: 40em; +} +.htk-toast > div +{ + padding: .5em 2%; + margin: .5em 2%; + border-radius: 0.1em; + box-shadow: 0 0 0.4em #666; + width: 92%; +} +.htk-toast > .message +{ + background-color: #BFB; +} +.htk-toast > .warning +{ + background-color: #FFB; +} +.htk-toast > .error +{ + background-color: #FBB; +} + +/* Popup */ + +.htk-popup +{ + z-index: 200; + display: block; + position: fixed; + background-color: white; + border-radius: 0.1em; + box-shadow: 0 0 0.4em #666; +} +.htk-background +{ + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 190; + background-color: rgba(1, 1, 1, 0.7); +} + +/* Image editor */ + +.htk-image-editor +{ + width: 20em; + margin: 0 auto; +} +.htk-image-editor h2 +{ + color: white; + background-color: #009688; + text-align: left; + font-size: 1.3em; + line-height: 1.7em; + font-weight: normal; + padding: 0.6em 0.8em; + margin: 0; +} +.htk-image-editor iframe +{ + display: none; +} +.htk-image-editor form +{ + padding: 1.5em; +} +.htk-image-editor .form-group +{ + margin-bottom: 0.5em; +} +.htk-image-editor .form-group label +{ + display: block; + margin-bottom: 0.3em; +} +.htk-image-editor .form-group input +{ + width: 95%; + height: 1.8em; +} +.htk-image-editor .footer +{ + margin-top: 1em; + text-align: center; +} +.htk-image-editor .footer img +{ + visibility: hidden; + vertical-align: middle; + padding-right: 1em; +} +.htk-image-editor .footer input +{ + display: inline; + margin-left: 0.5em; + margin-right: 0.5em; +} + +/* Assistant */ + +.htk-assistant > div +{ + display: none; + margin-top: 1em; + margin-bottom: 4em; +} +.htk-assistant > div > h2 +{ + text-align: center; + font-style: italic; + font-weight: normal; + font-size: 1.5em; + margin: 0.5em; + margin-bottom: 1em; +} +.htk-assistant * +{ + color: #555; +} + +/* Assistant bar */ + +.htk-assistant-bar +{ + margin: 0.5em auto; + max-width: 30em; + position: relative; +} +.htk-assistant-bar img +{ + cursor: pointer; +} +.htk-assistant-bar > img +{ + position: absolute; + width: 1.8em; + top: 0; + padding: 0.3em; + border-radius: 0.1em; +} +.htk-assistant-bar > img:hover +{ + background-color: rgba(1,1,1,0.1); +} +.htk-assistant-bar > img.previous +{ + left: 0; +} +.htk-assistant-bar > img.next +{ + right: 0; +} +.htk-assistant-bar > div +{ + margin: 0 auto; + padding-top: 0.2em; +} +.htk-assistant-bar > div > img +{ + padding: 0.3em 0.2em; + width: 1.3em; +} +.htk-assistant-bar > div > img:hover +{ + opacity: .7; +} + +/* Loader */ +/* +.htk-loader +{ + margin: 0 auto; + width: 2em; + height: 2em; + text-indent: -9999em; + border-radius: 50%; + background: #FFF; + background: -moz-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: -webkit-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: -o-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: -ms-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 42%); + position: relative; + -webkit-animation: load3 1.4s infinite linear; + animation: load3 1.4s infinite linear; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +} +.htk-loader:before +{ + width: 50%; + height: 50%; + background: #FFF; + border-radius: 100% 0 0 0; + position: absolute; + top: 0; + left: 0; + content: ''; +} +.htk-loader:after +{ + background: #009688; + width: 75%; + height: 75%; + border-radius: 50%; + content: ''; + margin: auto; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} +@-webkit-keyframes load3 +{ + 0% + { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% + { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes load3 +{ + 0% + { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% + { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +*/ diff --git a/web/js/htk/widget.js b/web/js/htk/widget.js index 4ffcc3c3..c4a6a3e5 100755 --- a/web/js/htk/widget.js +++ b/web/js/htk/widget.js @@ -52,4 +52,12 @@ Htk.Widget = new Class { Vn.Node.remove (this.node); } + + ,_destroy: function () + { + if (this.builder) + this.builder.unref (); + + this.parent (); + } }); diff --git a/web/js/misc/main.js b/web/js/misc/main.js new file mode 100755 index 00000000..830eae5b --- /dev/null +++ b/web/js/misc/main.js @@ -0,0 +1,4 @@ + +Vn.includeJs ('js/misc/tinymce/tinymce.min.js'); +Vn.includeJs ('js/misc/mootools'); + diff --git a/web/js/sql/main.js b/web/js/sql/main.js index 21358f87..222171c2 100755 --- a/web/js/sql/main.js +++ b/web/js/sql/main.js @@ -1,5 +1,29 @@ -/** - * The namespace. - **/ -var Sql = {}; + +Vn.includeJs ('js/vn/main.js'); +Vn.includeLib ('sql', +[ + 'sql' + ,'object' + ,'holder' + ,'batch' + ,'list' + ,'expr' + ,'value' + ,'field' + ,'function' + ,'operation' + ,'target' + ,'table' + ,'stmt' + ,'dml' + ,'string' + ,'delete' + ,'insert' + ,'select' + ,'update' + ,'multi-stmt' + ,'filter' + ,'filter-item' + ,'search-tags' +]); diff --git a/web/js/sql/main.php b/web/js/sql/main.php index 03f69755..f0ba1789 100755 --- a/web/js/sql/main.php +++ b/web/js/sql/main.php @@ -3,7 +3,7 @@ require_once ('js/vn/main.php'); Vn\Hedera\Js::includeLib ('sql' - ,'main' + ,'sql' ,'object' ,'holder' ,'batch' diff --git a/web/js/sql/sql.js b/web/js/sql/sql.js new file mode 100755 index 00000000..21358f87 --- /dev/null +++ b/web/js/sql/sql.js @@ -0,0 +1,5 @@ +/** + * The namespace. + **/ +var Sql = {}; + diff --git a/web/js/vn/locale.js b/web/js/vn/locale.js index dd865869..17086a28 100755 --- a/web/js/vn/locale.js +++ b/web/js/vn/locale.js @@ -7,13 +7,18 @@ Vn.Locale = ,language: null - ,load: function (path, callback) + ,init: function () { if (!this.language) { var language = navigator.language.substr (0, 2); this.language = language ? language : 'es'; } + } + + ,load: function (path, callback) + { + this.init (); var file = 'locale/'+ this.language +'/'+ path +'.json' +'?'+ Vn.Cookie.get ('hedera_version'); @@ -23,6 +28,12 @@ Vn.Locale = request.onreadystatechange = this.loadDone.bind (this, request, callback); request.send (); } + + ,loadScript: function (path, callback) + { + this.init (); + Vn.includeJs ('locale/'+ this.language +'/'+ path, callback); + } ,loadDone: function (request, callback) { diff --git a/web/js/vn/main.js b/web/js/vn/main.js old mode 100755 new mode 100644 index afb42645..1a0a3e68 --- a/web/js/vn/main.js +++ b/web/js/vn/main.js @@ -1,187 +1,20 @@ -/** - * The main namespace. - **/ -var Vn = -{ - Config: {} - ,jsIncludes: {} - ,cssIncludes: {} - ,xmlIncludes: {} - ,customTags: {} - ,head: document.getElementsByTagName ('head')[0] - ,isMobileCached: null - /** - * Includes a new CSS stylesheet in the current document, if the stylesheet - * its already included, does nothing. - * - * @param {string} fileName The stylesheet file name - **/ - ,includeCss: function (fileName) - { - var cssData = this.cssIncludes[fileName]; - - if (!cssData) - { - var link = document.createElement ('link'); - link.rel = 'stylesheet'; - link.type = 'text/css'; - link.href = fileName +'?'+ Vn.Cookie.get ('hedera_version'); - this.head.appendChild (link); - - this.cssIncludes[fileName] = - { - included: true - ,link: link - }; - } - else if (!cssData.included) - { - cssData.link.disabled = false; - cssData.included = true; - } - } - - /** - * Excludes a CSS stylesheet from the current document. - * - * @param {string} fileName The stylesheet file name - **/ - ,excludeCss: function (fileName) - { - var cssData = this.cssIncludes[fileName]; - - if (cssData && cssData.included) - { - cssData.link.disabled = true; - cssData.included = false; - } - } - - /** - * Includes a new Javascript in the current document, if the script - * its already included, does nothing. - * - * @param {string} fileName The script file name - * @param {Function} callback The function to call when script is - * downloaded and included - **/ - ,includeJs: function (fileName, callback, skipVersion) - { - var includeData = this.jsIncludes[fileName]; - - if (includeData === undefined) - { - var src = fileName; - - if (!skipVersion) - src = src +'?'+ Vn.Cookie.get ('hedera_version'); - - var script = document.createElement ('script'); - script.type = 'text/javascript'; - script.src = src; - - includeData = { - script: script - ,callbacks: [] - ,loaded: false - }; - - if (callback) - includeData.callbacks.push (callback); - - script.onload = - this.jsLoaded.bind (this, includeData, true); - script.onerror = - this.jsLoaded.bind (this, includeData, false); - script.onreadystatechange = - this.jsStateChanged.bind (this, includeData); - - this.jsIncludes[fileName] = includeData; - - this.head.appendChild (script); - } - else if (callback) - { - if (includeData.loaded) - callback (); - else - includeData.callbacks.push (callback); - } - } - - ,jsStateChanged: function (includeData) - { - console.log ('js: '+ includeData.script.readyState); - - if (includeData.script.readyState == 'complete') - this.jsLoaded (includeData, true); - } - - ,jsLoaded: function (includeData, success) - { - if (includeData.loaded) - return; - - for (var i = 0; i < includeData.callbacks.length; i++) - includeData.callbacks[i] (success); - - includeData.loaded = true; - includeData.callbacks = null; - } - - ,loadXml: function (path, callback) - { - var includeData = this.xmlIncludes[path]; - - if (!includeData) - { - var request = new XMLHttpRequest (); - request.onreadystatechange = - this.onXmlReady.bind (this, request, path, callback); - request.open ('get', path +'?'+ Vn.Cookie.get ('hedera_version'), true); - request.send (); - } - else if (callback) - callback (true); - } - - ,onXmlReady: function (request, path, callback) - { - if (request.readyState != 4) - return; - - if (request.status == 200) - this.xmlIncludes[path] = request.responseXML; - - if (callback) - callback (request.status == 200); - } - - ,getXml: function (path) - { - return this.xmlIncludes[path]; - } - - /** - * Checks if user is using a mobile browser. - * - * return {boolean} %true if is mobile, %false otherwise. - **/ - ,isMobile: function () - { - if (this.isMobileCached === null) - { - var regExp = /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i; - this.isMobileCached = navigator.userAgent.match (regExp); - } - - return this.isMobileCached; - } - - ,get: function (id) - { - return document.getElementById (id); - } -}; +Vn.includeJs ('js/misc/main.js'); +Vn.includeLib ('vn', +[ + 'browser' + ,'date' + ,'value' + ,'error' + ,'url' + ,'mutators' + ,'object' + ,'param' + ,'hash-listener' + ,'hash' + ,'hash-param' + ,'node' + ,'builder' + ,'http-request' +]); diff --git a/web/js/vn/main.php b/web/js/vn/main.php index d8198cb3..aefcddb5 100755 --- a/web/js/vn/main.php +++ b/web/js/vn/main.php @@ -4,7 +4,7 @@ require_once ('js/misc/main.php'); use Vn\Hedera\Js; -Js::includeFile ('js/vn/main.js'); +Js::includeFile ('js/vn/vn.js'); Js::includeFile ('js/vn/locale.js'); if (strpos ($_SERVER['HTTP_USER_AGENT'], 'MSIE')) diff --git a/web/js/vn/vn.js b/web/js/vn/vn.js new file mode 100755 index 00000000..3ed107c8 --- /dev/null +++ b/web/js/vn/vn.js @@ -0,0 +1,229 @@ +/** + * The main namespace. + **/ +var Vn = +{ + Config: {} + ,jsIncludes: {} + ,cssIncludes: {} + ,xmlIncludes: {} + ,customTags: {} + ,head: document.getElementsByTagName ('head')[0] + ,isMobileCached: null + + ,_registerIncludedScripts: function () + { + var scripts = this.head.getElementsByTagName ('script'); + + var basePath = location.protocol +'//'+ location.host; + basePath += location.port ? ':'+ location.port : ''; + basePath += location.pathname; + console.log (basePath); + + for (var i = 0; i < scripts.length; i++) + { + var path = scripts[i].src.match (/^([\w\./:~-]+)[?#]?.*$/); + } + } + + /** + * Includes a new Javascript in the current document, if the script + * is already included, does nothing and calls the callback. + * + * @param {string} fileName The script file name + * @param {Function} callback The function to call when script is + * downloaded and included + **/ + ,includeJs: function (fileName, callback, skipVersion) + { + var includeData = this.jsIncludes[fileName]; + + if (includeData === undefined) + { + var src = fileName; + + if (!skipVersion) + src = src +'?'+ Vn.Cookie.get ('hedera_version'); + + var script = document.createElement ('script'); + script.type = 'text/javascript'; + script.async = false; + script.src = src; + + includeData = { + script: script + ,callbacks: [] + ,loaded: false + }; + + if (callback) + includeData.callbacks.push (callback); + + script.onload = + this._jsLoaded.bind (this, includeData, true); + script.onerror = + this._jsLoaded.bind (this, includeData, false); + script.onreadystatechange = + this._jsStateChanged.bind (this, includeData); + + this.jsIncludes[fileName] = includeData; + + this.head.appendChild (script); + } + else if (callback) + { + if (includeData.loaded) + callback (); + else + includeData.callbacks.push (callback); + } + } + + ,_jsStateChanged: function (includeData) + { + console.log ('js: '+ includeData.script.readyState); + + if (includeData.script.readyState == 'complete') + this._jsLoaded (includeData, true); + } + + ,_jsLoaded: function (includeData, success) + { + if (includeData.loaded) + return; + + for (var i = 0; i < includeData.callbacks.length; i++) + includeData.callbacks[i] (success); + + includeData.loaded = true; + includeData.callbacks = null; + } + + /** + * Includes an entire Javascript library including it's localized file. + * + * @param {string} libName The folder of the library + * @param {Array} files Array with every library file name + **/ + ,includeLib: function (libName, files) + { + Vn.Locale.loadScript ('js/'+ libName +'.js'); + + for (var i = 0; i < files.length; i++) + this.includeJs ('js/'+ libName +'/'+ files[i] +'.js'); + } + + /** + * Includes a new CSS stylesheet in the current document, if the stylesheet + * is already included, does nothing. + * + * @param {string} fileName The stylesheet file name + **/ + ,includeCss: function (fileName) + { + var cssData = this.cssIncludes[fileName]; + + if (!cssData) + { + var link = document.createElement ('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = fileName +'?'+ Vn.Cookie.get ('hedera_version'); + this.head.appendChild (link); + + this.cssIncludes[fileName] = + { + included: true + ,link: link + }; + } + else if (!cssData.included) + { + cssData.link.disabled = false; + cssData.included = true; + } + } + + /** + * Excludes a CSS stylesheet from the current document. + * + * @param {string} fileName The stylesheet file name + **/ + ,excludeCss: function (fileName) + { + var cssData = this.cssIncludes[fileName]; + + if (cssData && cssData.included) + { + cssData.link.disabled = true; + cssData.included = false; + } + } + + /** + * Request an XML file. + * + * @param {string} path The file path + * @param {Function} callback The function to call when file is downloaded + **/ + ,loadXml: function (path, callback) + { + var includeData = this.xmlIncludes[path]; + + if (true || !includeData) + { + var request = new XMLHttpRequest (); + request.onreadystatechange = + this._onXmlReady.bind (this, request, path, callback); + request.open ('get', path +'?'+ Vn.Cookie.get ('hedera_version'), true); + request.send (); + } + else if (callback) + callback (true); + } + + ,_onXmlReady: function (request, path, callback) + { + if (request.readyState != 4) + return; + + if (request.status == 200) + this.xmlIncludes[path] = request.responseXML; + + if (callback) + callback (request.status == 200); + } + + /** + * Gets the DOM object from an included XML file. + * + * @param {string} path The file path + * @return {Object} The DOM object + **/ + ,getXml: function (path) + { + return this.xmlIncludes[path]; + } + + /** + * Checks if user is using a mobile browser. + * + * return {boolean} %true if is mobile, %false otherwise. + **/ + ,isMobile: function () + { + if (this.isMobileCached === null) + { + var regExp = /(Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone)/i; + this.isMobileCached = navigator.userAgent.match (regExp); + } + + return this.isMobileCached; + } + + ,get: function (id) + { + return document.getElementById (id); + } +}; + diff --git a/web/locale/ca/js/hedera.js b/web/locale/ca/js/hedera.js new file mode 100755 index 00000000..5dfbe023 --- /dev/null +++ b/web/locale/ca/js/hedera.js @@ -0,0 +1,49 @@ +Vn.Locale.add +({ + "User": "Usuari" + ,"Password": "Contrasenya" + ,"Beta": "Beta" + ,"NotCloseSession": "No tancar sessió" + ,"IWantToKnowMore": "Vull saber-ne més!" + ,"Enter": "Entrar" + ,"LoginMail": "clientes@verdnatura.es" + ,"LoginPhone": "+34 607 562 391" + + ,"SessionExpired": "Has estat massa temps inactiu i la sessió ha expirat." + ,"InvalidLogin": "Usuari o contrasenya incorrectes. Recorda que s'hi distingeix entre majúscula i minúscula." + + ,"Menu": "Menú" + ,"Exit": "Sortir" + ,"TestTheNewWebsite": "Prova la nova web!" + ,"ReturnToOldWebsite": "Web antiga" + ,"ChangeLog": "Canvis recents" + + ,"ErrorLoadingForm": "Error al carregar formulari" + ,"CookiesNotification": "En utilitzar aquest lloc web acceptes l'ús de cookies per a la personalització de continguts i anàlisi." + ,"NewVersionAvailable": "Hi ha una nova actualització, la pàgina recargargará automàticament per descarregar-la" + + ,"AppName": "Verdnatura" + + ,"Home": "Inici" + ,"Orders": "Encàrrecs" + ,"Basket": "Cistella" + ,"Last orders": "Últims comandes" + ,"Invoices": "Factures" + ,"Catalog": "Catàleg" + ,"About": "Coneix-nos" + ,"About us": "Quant a" + ,"Why": "Per què?" + ,"Location": "Localització" + ,"Administration": "Administració" + ,"Control panel": "Panell de control" + ,"Users": "Usuaris" + ,"Visits": "Visites" + ,"News": "Noticies" + ,"Photos": "Fotos" + ,"Contact": "Vull ser client" + ,"Training": "Formació" + ,"Agencies": "Agències" + ,"Configuration": "Configuració" + ,"Account": "Compte" + ,"Addresses": "Direccions" +}); diff --git a/web/locale/ca/js/vn.js b/web/locale/ca/js/vn.js index 801faee8..c2eaeaf7 100755 --- a/web/locale/ca/js/vn.js +++ b/web/locale/ca/js/vn.js @@ -41,47 +41,4 @@ Vn.Locale.add ,"Oct": "Oct" ,"Nov": "Nov" ,"Dec": "Des" - - ,"AppName": "Verdnatura" - ,"Beta": "Beta" - ,"User": "Usuari" - ,"Password": "Contrasenya" - ,"Remember": "Recordar" - ,"Enter": "Entrar" - ,"Exit": "Sortir" - ,"ErrorLoadingForm": "Error al carregar formulari" - ,"YoureVisitor": "Solament estàs de visita?" - ,"NewVersionAvailable": "Hi ha una nova actualització, la pàgina recargargará automàticament per descarregar-la" - ,"ChangeLog": "Canvis recents" - ,"CookiesNotification": "En utilitzar aquest lloc web acceptes l'ús de cookies per a la personalització de continguts i anàlisi." - ,"ReturnToOldWebsite": "Web antiga" - ,"TestTheNewWebsite": "Prova la nova web!" - - ,"Menu": "Menú" - - ,"Home": "Inici" - ,"Orders": "Encàrrecs" - ,"Basket": "Cistella" - ,"Last orders": "Últims comandes" - ,"Invoices": "Factures" - ,"Catalog": "Catàleg" - ,"About": "Coneix-nos" - ,"About us": "Quant a" - ,"Why": "Per què?" - ,"Location": "Localització" - ,"Administration": "Administració" - ,"Control panel": "Panell de control" - ,"Users": "Usuaris" - ,"Visits": "Visites" - ,"News": "Noticies" - ,"Photos": "Fotos" - ,"Contact": "Vull ser client" - ,"Training": "Formació" - ,"Agencies": "Agències" - ,"Configuration": "Configuració" - ,"Account": "Compte" - ,"Addresses": "Direccions" - - ,"SessionExpired": "Has estat massa temps inactiu i la sessió ha expirat." - ,"InvalidLogin": "Usuari o contrasenya incorrectes. Recorda que s'hi distingeix entre majúscula i minúscula." }); diff --git a/web/locale/es/js/hedera.js b/web/locale/es/js/hedera.js new file mode 100755 index 00000000..baa952e8 --- /dev/null +++ b/web/locale/es/js/hedera.js @@ -0,0 +1,49 @@ +Vn.Locale.add +({ + "User": "Usuario" + ,"Password": "Contraseña" + ,"Beta": "Beta" + ,"NotCloseSession": "No cerrar sesión" + ,"IWantToKnowMore": "¡Quiero saber más!" + ,"Enter": "Entrar" + ,"LoginMail": "clientes@verdnatura.es" + ,"LoginPhone": "+34 963 242 100" + + ,"SessionExpired": "Has estado demasiado tiempo inactivo y la sesión ha expirado." + ,"InvalidLogin": "Usuario o contraseña incorrectos. Recuerda que se hace distinción entre mayúsculas y minúsculas." + + ,"Menu": "Menú" + ,"Exit": "Salir" + ,"TestTheNewWebsite": "¡Prueba la nueva web!" + ,"ReturnToOldWebsite": "Web antigua" + ,"ChangeLog": "Cambios recientes" + + ,"ErrorLoadingForm": "Error al cargar formulario" + ,"CookiesNotification": "Al utilizar este sitio web aceptas el uso de cookies para la personalización de contenidos y análisis." + ,"NewVersionAvailable": "Hay una nueva actualización, la página se recargargará automaticamente para descargarla" + + ,"AppName": "Verdnatura" + + ,"Home": "Inicio" + ,"Orders": "Pedidos" + ,"Basket": "Cesta" + ,"Last orders": "Últimos pedidos" + ,"Invoices": "Facturas" + ,"Catalog": "Catálogo" + ,"About": "Conócenos" + ,"About us": "Sobre nosotros" + ,"Why": "¿Por qué?" + ,"Location": "Localización" + ,"Administration": "Administración" + ,"Control panel": "Panel de control" + ,"Users": "Usuarios" + ,"Visits": "Visitas" + ,"News": "Noticias" + ,"Photos": "Fotos" + ,"Contact": "Quiero ser cliente" + ,"Training": "Formación" + ,"Agencies": "Agencias" + ,"Configuration": "Configuración" + ,"Account": "Cuenta" + ,"Addresses": "Direcciones" +}); diff --git a/web/locale/es/js/vn.js b/web/locale/es/js/vn.js index e0a85c0b..b6c60d59 100755 --- a/web/locale/es/js/vn.js +++ b/web/locale/es/js/vn.js @@ -41,47 +41,4 @@ Vn.Locale.add ,"Oct": "Oct" ,"Nov": "Nov" ,"Dec": "Dic" - - ,"AppName": "Verdnatura" - ,"Beta": "Beta" - ,"User": "Usuario" - ,"Password": "Contraseña" - ,"Remember": "Recordar" - ,"Enter": "Entrar" - ,"Exit": "Salir" - ,"ErrorLoadingForm": "Error al cargar formulario" - ,"YoureVisitor": "¿Solo estás de visita?" - ,"NewVersionAvailable": "Hay una nueva actualización, la página se recargargará automaticamente para descargarla" - ,"ChangeLog": "Cambios recientes" - ,"CookiesNotification": "Al utilizar este sitio web aceptas el uso de cookies para la personalización de contenidos y análisis." - ,"ReturnToOldWebsite": "Web antigua" - ,"TestTheNewWebsite": "¡Prueba la nueva web!" - - ,"Menu": "Menú" - - ,"Home": "Inicio" - ,"Orders": "Pedidos" - ,"Basket": "Cesta" - ,"Last orders": "Últimos pedidos" - ,"Invoices": "Facturas" - ,"Catalog": "Catálogo" - ,"About": "Conócenos" - ,"About us": "Sobre nosotros" - ,"Why": "¿Por qué?" - ,"Location": "Localización" - ,"Administration": "Administración" - ,"Control panel": "Panel de control" - ,"Users": "Usuarios" - ,"Visits": "Visitas" - ,"News": "Noticias" - ,"Photos": "Fotos" - ,"Contact": "Quiero ser cliente" - ,"Training": "Formación" - ,"Agencies": "Agencias" - ,"Configuration": "Configuración" - ,"Account": "Cuenta" - ,"Addresses": "Direcciones" - - ,"SessionExpired": "Has estado demasiado tiempo inactivo y la sesión ha expirado." - ,"InvalidLogin": "Usuario o contraseña incorrectos. Recuerda que se hace distinción entre mayúsculas y minúsculas." }); diff --git a/web/locale/fr/js/hedera.js b/web/locale/fr/js/hedera.js new file mode 100755 index 00000000..7220fdaa --- /dev/null +++ b/web/locale/fr/js/hedera.js @@ -0,0 +1,49 @@ +Vn.Locale.add +({ + "User": "Utilisateur" + ,"Password": "Mot de passe" + ,"Beta": "Beta" + ,"NotCloseSession": "Garder ma session active" + ,"IWantToKnowMore": "En savoir plus!" + ,"Enter": "Entrer" + ,"LoginMail": "ruben@verdnatura.es" + ,"LoginPhone": "+33 781 533 900" + + ,"SessionExpired": "Il a eu le temps de trop paresseux et votre session a expiré." + ,"InvalidLogin": "Utilisateur ou mot de passe incorrect. N'oubliez pas de distinction entre majuscules et minuscules." + + ,"Menu": "Menu" + ,"Exit": "Laisser" + ,"TestTheNewWebsite": "Testez le nouveau site!" + ,"ReturnToOldWebsite": "Ancien site web" + ,"ChangeLog": "Modifications récentes" + + ,"ErrorLoadingForm": "Forme erreur de chargement" + ,"CookiesNotification": "En utilisant ce site, vous acceptez l'utilisation de cookies pour personnaliser le contenu et l'analyse." + ,"NewVersionAvailable": "Il ya une nouvelle mise à jour, la page sera automatiquement recargargará pour télécharger" + + ,"AppName": "Verdnatura" + + ,"Home": "Accueil" + ,"Orders": "Commandes" + ,"Basket": "Panier" + ,"Last orders": "Dernières commandes" + ,"Invoices": "Facturas" + ,"Catalog": "Catalogue" + ,"About": "Nous" + ,"About us": "A propos de nous" + ,"Why": "Pourquoi?" + ,"Location": "Emplacement" + ,"Administration": "Administration" + ,"Control panel": "Panneau de contrôle" + ,"Users": "Utilisateurs" + ,"Visits": "Visites" + ,"News": "Nouvelles" + ,"Photos": "Photos" + ,"Contact": "Je veux être client" + ,"Training": "Formation" + ,"Agencies": "Agences" + ,"Configuration": "Configuration" + ,"Account": "Compte" + ,"Addresses": "Adresses" +}); diff --git a/web/locale/fr/js/vn.js b/web/locale/fr/js/vn.js index aa43f38d..c3afdaa2 100755 --- a/web/locale/fr/js/vn.js +++ b/web/locale/fr/js/vn.js @@ -41,47 +41,4 @@ Vn.Locale.add ,"Oct": "Oct" ,"Nov": "Nov" ,"Dec": "Déc" - - ,"AppName": "Verdnatura" - ,"Beta": "Beta" - ,"User": "Utilisateur" - ,"Password": "Mot de passe" - ,"Remember": "Rappeler" - ,"Enter": "entrer" - ,"Exit": "Laisser" - ,"ErrorLoadingForm": "Forme erreur de chargement" - ,"YoureVisitor": "¿Solo estás de visita?" - ,"NewVersionAvailable": "Il ya une nouvelle mise à jour, la page sera automatiquement recargargará pour télécharger" - ,"ChangeLog": "Modifications récentes" - ,"CookiesNotification": "En utilisant ce site, vous acceptez l'utilisation de cookies pour personnaliser le contenu et l'analyse." - ,"ReturnToOldWebsite": "Ancien site web" - ,"TestTheNewWebsite": "Testez le nouveau site!" - - ,"Menu": "Menu" - - ,"Home": "Accueil" - ,"Orders": "Commandes" - ,"Basket": "Panier" - ,"Last orders": "Dernières commandes" - ,"Invoices": "Facturas" - ,"Catalog": "Catalogue" - ,"About": "Nous" - ,"About us": "A propos de nous" - ,"Why": "Pourquoi?" - ,"Location": "Emplacement" - ,"Administration": "Administration" - ,"Control panel": "Panneau de contrôle" - ,"Users": "Utilisateurs" - ,"Visits": "Visites" - ,"News": "Nouvelles" - ,"Photos": "Photos" - ,"Contact": "Je veux être client" - ,"Training": "Formation" - ,"Agencies": "Agences" - ,"Configuration": "Configuration" - ,"Account": "Compte" - ,"Addresses": "Adresses" - - ,"SessionExpired": "Il a eu le temps de trop paresseux et votre session a expiré." - ,"InvalidLogin": "Utilisateur ou mot de passe incorrect. N'oubliez pas de distinction entre majuscules et minuscules." }); diff --git a/web/pages/login/login.js b/web/pages/login/login.js index 42eff70a..01a96306 100755 --- a/web/pages/login/login.js +++ b/web/pages/login/login.js @@ -1,10 +1,13 @@ -window.addEventListener ('load', - function () { Vn.Login.initialize (); }); +window.addEventListener ('load', function () { + var web = new Vn.Login (); +}); -Vn.Login = -{ - initialize: function () +Vn.Login = new Class +({ + Extends: Vn.Object + + ,initialize: function () { Vn.Hash.initialize (); @@ -26,5 +29,5 @@ Vn.Login = userEntry.focus (); userEntry.select (); } -}; +}); diff --git a/web/pages/main/head.php b/web/pages/main/head.php new file mode 100755 index 00000000..5a33cec7 --- /dev/null +++ b/web/pages/main/head.php @@ -0,0 +1,13 @@ + diff --git a/web/pages/main/html.php b/web/pages/main/html.php new file mode 100755 index 00000000..e4a8a53a --- /dev/null +++ b/web/pages/main/html.php @@ -0,0 +1,15 @@ + + + + + + + + + + + + Verdnatura + + + diff --git a/web/pages/main/main.js b/web/pages/main/main.js new file mode 100755 index 00000000..dd2d4c99 --- /dev/null +++ b/web/pages/main/main.js @@ -0,0 +1,13 @@ + +Vn.includeJs ('js/misc/main.js'); +Vn.includeJs ('js/vn/locale.js'); +Vn.includeJs ('js/vn/main.js'); +Vn.includeJs ('js/sql/main.js'); +Vn.includeJs ('js/db/main.js'); +Vn.includeJs ('js/htk/main.js'); +Vn.includeJs ('js/hedera/main.js'); + +window.addEventListener ('load', function () { + var app = new Vn.App (); + app.run (); +}); diff --git a/web/pages/main/opensans.ttf b/web/pages/main/opensans.ttf new file mode 100755 index 0000000000000000000000000000000000000000..db433349b7047f72f40072630c1bc110620bf09e GIT binary patch literal 217360 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 !}#gv~NV!5|5YF|kE)J0y^zWbk4>=%|6F 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 literal 0 HcmV?d00001 diff --git a/web/pages/main/style.css b/web/pages/main/style.css new file mode 100755 index 00000000..fcbd6f1c --- /dev/null +++ b/web/pages/main/style.css @@ -0,0 +1,17 @@ + +@font-face +{ + font-family: 'Open Sans'; + src: url('opensans.ttf') format('truetype'); +} + +body +{ + position: absolute; + margin: 0; + height: 100%; + width: 100%; + z-index: -2; + background-color: #EEE; +} + diff --git a/web/pages/version-menu/style.css b/web/pages/version-menu/style.css index 0aa06615..6410c894 100755 --- a/web/pages/version-menu/style.css +++ b/web/pages/version-menu/style.css @@ -1,18 +1,9 @@ -/* -@media - (min-resolution: 120dpi) and (min-width: 800px), - (max-resolution: 119dpi) and (max-width: 800px) -{ - -} -*/ -@media - (min-resolution: 120dpi) and (orientation: portrait) + +@media (min-resolution: 120dpi) and (orientation: portrait) { * { font-size: 18pt; } } -@media - (min-resolution: 120dpi) and (orientation: landscape) +@media (min-resolution: 120dpi) and (orientation: landscape) { * { font-size: 10pt; } } diff --git a/web/pages/web/html.php b/web/pages/web/html.php index d702b1b4..ce1554d2 100755 --- a/web/pages/web/html.php +++ b/web/pages/web/html.php @@ -2,12 +2,14 @@ - + - - + + Verdnatura + +
@@ -115,7 +115,7 @@ - + diff --git a/web/image/dark/info.svg b/web/image/dark/info.svg index 54837200..97a12573 100644 --- a/web/image/dark/info.svg +++ b/web/image/dark/info.svg @@ -1,5 +1,6 @@ - + - - - - image/svg+xml - - Gnome Symbolic Icon Theme - - - - image/svg+xml - - - Gnome Symbolic Icon Theme - - - - - - - - - - - - + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1016" + id="namedview5" + showgrid="false" + inkscape:zoom="51.6875" + inkscape:cx="7.2631221" + inkscape:cy="7.9613059" + inkscape:window-x="1920" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> \ No newline at end of file diff --git a/web/image/info.svg b/web/image/info.svg index f9ffc299..c0803073 100644 --- a/web/image/info.svg +++ b/web/image/info.svg @@ -1,5 +1,6 @@ - + - - - - image/svg+xml - - Gnome Symbolic Icon Theme - - - - image/svg+xml - - - Gnome Symbolic Icon Theme - - - - - - - - - - - - + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1016" + id="namedview5" + showgrid="false" + inkscape:zoom="51.6875" + inkscape:cx="7.2631221" + inkscape:cy="7.9613059" + inkscape:window-x="1920" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> \ No newline at end of file diff --git a/web/image/unknown.svg b/web/image/unknown.svg new file mode 100644 index 00000000..f9ffc299 --- /dev/null +++ b/web/image/unknown.svg @@ -0,0 +1,123 @@ + + + + + + + + image/svg+xml + + Gnome Symbolic Icon Theme + + + + + + + Gnome Symbolic Icon Theme + + + + + + + + + + + + diff --git a/web/js/hedera/app.js b/web/js/hedera/app.js index 0d64ff29..1681cf96 100644 --- a/web/js/hedera/app.js +++ b/web/js/hedera/app.js @@ -61,7 +61,7 @@ Vn.App = new Class error.fileName = file; error.lineNumber = line; - Htk.Toast.showError (_('InternalError')); + Htk.Toast.showError (_('There was an internal error')); this.notifyError (error); } diff --git a/web/js/hedera/form.js b/web/js/hedera/form.js index 6399d153..790786be 100755 --- a/web/js/hedera/form.js +++ b/web/js/hedera/form.js @@ -34,6 +34,7 @@ Vn.Form = new Class var builder = new Vn.Builder (); builder.signalData = this; + builder.add ('conn', this.conn); builder.loadXml ('forms/'+ this.formInfo.path +'/ui.xml'); var res = this.builder = builder.load (); diff --git a/web/js/hedera/gui.css b/web/js/hedera/gui.css index ded5209c..3338aa6f 100755 --- a/web/js/hedera/gui.css +++ b/web/js/hedera/gui.css @@ -65,14 +65,13 @@ font-weight: normal; font-size: 1.4em; padding: .7em .6em; + padding-right: 0; margin: 0; } -.vn-gui .top-bar > .loader +.vn-gui .top-bar > .htk-spinner { - float: right; - margin: 5% 1em; - visibility: hidden; - height: 90%; + float: left; + margin: 1.05em .8em; } .vn-gui .exit { @@ -110,7 +109,6 @@ { float: left; padding: 0; - margin: 1.3em .5em; } .vn-gui .action-bar button { diff --git a/web/js/hedera/gui.js b/web/js/hedera/gui.js index 65b25f94..dbc0a588 100755 --- a/web/js/hedera/gui.js +++ b/web/js/hedera/gui.js @@ -253,7 +253,7 @@ Vn.Gui = new Class this.loadingCount++; if (this.loadingCount == 1) - this.$('loader').style.visibility = 'visible'; + this.$('loader').start (); } ,loaderPop: function () @@ -264,7 +264,7 @@ Vn.Gui = new Class this.loadingCount--; if (this.loadingCount == 0) - this.$('loader').style.visibility = 'hidden'; + this.$('loader').stop (); } ,newVersion: function (error) diff --git a/web/js/hedera/gui.xml b/web/js/hedera/gui.xml index e152d7ed..630171f8 100755 --- a/web/js/hedera/gui.xml +++ b/web/js/hedera/gui.xml @@ -35,10 +35,8 @@ _Exit
-
- -
+
diff --git a/web/js/hedera/report.js b/web/js/hedera/report.js index 0853b69c..e49035a5 100755 --- a/web/js/hedera/report.js +++ b/web/js/hedera/report.js @@ -28,33 +28,7 @@ Vn.Report = new Class ,open: function (batch) { this.batch = batch; - this.createWindow (this._onWindowLoad.bind (this)); - } - - ,_onWindowLoad: function () - { - this.doc = this.window.document - - var path = this.info.path; - - this.includeCss ('reports/'+ path +'/style.css'); - - var printButton = this.doc.createElement ('button'); - printButton.className = 'print-button'; - printButton.appendChild (this.doc.createTextNode (_('Print'))); - printButton.addEventListener ('click', this.print.bind (this)); - this.doc.body.appendChild (printButton); - - var builder = new Vn.Builder (); - builder.signalData = this; - builder.add ('batch', this.batch); - builder.add ('conn', this.conn); - builder.loadXml ('reports/'+ path +'/ui.xml'); - - var res = this.builderResult = builder.load (); - res.link (); - - this.doc.body.appendChild (res.$('report')); + this.createWindow (); } ,print: function () @@ -78,21 +52,58 @@ Vn.Report = new Class head.appendChild (link); } - ,createWindow: function (callback) + ,createWindow: function () { - var reportWindow = window.open ('js/hedera/report.html', '_blank'/*this.info.path*/, - 'resizable=yes,height=900,width=900,scrollbars=yes,menubar=false'); + var reportWindow = window.open ( + 'js/hedera/report.html', '_blank', + 'height=950, width=950, resizable=yes, fullscreen=no,'+ + 'titlebar=no, menubar=no, toolbar=no, location=no, scrollbars=yes' + ); if (!reportWindow) { Htk.Toast.showError ( _('Please unlock popups and try again')); - return null; + + if (callback) + callback (null); + + return false; } - reportWindow.addEventListener ('load', callback); + reportWindow.addEventListener ('load', + this._onWindowLoad.bind (this)); this.window = reportWindow; - return reportWindow; + return true; + } + + ,_onWindowLoad: function () + { + this.doc = this.window.document + + this.includeCss ('reports/'+ this.info.path +'/style.css'); + + var printButton = this.doc.createElement ('button'); + printButton.className = 'print-button'; + printButton.appendChild (this.doc.createTextNode (_('Print'))); + printButton.addEventListener ('click', this.print.bind (this)); + this.doc.body.appendChild (printButton); + + this.onWindowCreate (); + } + + ,onWindowCreate: function () + { + var builder = new Vn.Builder (); + builder.signalData = this; + builder.add ('batch', this.batch); + builder.add ('conn', this.conn); + builder.loadXml ('reports/'+ this.info.path +'/ui.xml'); + + var res = this.builderResult = builder.load (); + res.link (); + + this.doc.body.appendChild (res.$('report')); } }); diff --git a/web/js/htk/field.js b/web/js/htk/field.js index 498da991..3332de35 100755 --- a/web/js/htk/field.js +++ b/web/js/htk/field.js @@ -56,7 +56,7 @@ Htk.Field = new Class }, form: { - type: Vn.Object // Db.Iterator + type: Db.Iterator ,set: function (x) { this._form = x; diff --git a/web/js/htk/field/search-entry.js b/web/js/htk/field/search-entry.js new file mode 100755 index 00000000..d4e8fa51 --- /dev/null +++ b/web/js/htk/field/search-entry.js @@ -0,0 +1,52 @@ + +Htk.SearchEntry = new Class +({ + Extends: Htk.Field + ,Tag: 'htk-search-entry' + + ,initialize: function (props) + { + var div = this.createElement ('div'); + div.className = 'htk-search-entry'; + + var img = document.createElement ('img'); + img.alt = _('Search'); + img.src = 'image/search.svg'; + div.appendChild (img); + + var input = document.createElement ('input'); + input.className = 'entry'; + input.type = 'text'; + input.placeholder = _('Search'); + input.addEventListener ('change', this._onChange.bind (this)); + div.appendChild (input); + + this._input = input; + this.parent (props); + } + + ,_onChange: function (event) + { + var newValue; + + if (this._input.value === '') + newValue = undefined; + else + newValue = this._input.value; + + this.valueChanged (newValue); + } + + ,putValue: function (value) + { + if (!value) + this._input.value = ''; + else + this._input.value = value; + } + + ,setEditable: function (editable) + { + this.node.readOnly = !editable; + } +}); diff --git a/web/js/htk/field/select.js b/web/js/htk/field/select.js index 5a4944af..5658e48e 100755 --- a/web/js/htk/field/select.js +++ b/web/js/htk/field/select.js @@ -13,8 +13,8 @@ Htk.Select = new Class type: Db.Model ,set: function (x) { - this.link ({_model: x}, {'status-changed': this.onModelChange}); - this.onModelChange (); + this.link ({_model: x}, {'status-changed': this._onModelChange}); + this._onModelChange (); } ,get: function () { @@ -64,7 +64,7 @@ Htk.Select = new Class type: Boolean ,get: function () { - return this._ready; + return this._model && this._model.ready; } }, /** @@ -196,7 +196,7 @@ Htk.Select = new Class this._placeholderNode = option; } - ,onModelChange: function () + ,_onModelChange: function () { var placeholder = null; var model = this._model; diff --git a/web/js/htk/grid.js b/web/js/htk/grid.js index 36a3d81a..bc3f566e 100755 --- a/web/js/htk/grid.js +++ b/web/js/htk/grid.js @@ -6,6 +6,9 @@ Htk.Grid = new Class ,Child: 'model' ,Properties: { + /** + * The source data model. + **/ model: { type: Db.Model @@ -31,11 +34,17 @@ Htk.Grid = new Class return this._model; } }, + /** + * Message that should be displayed when source model is not ready. + **/ emptyMessage: { type: String ,value: _('NoData') }, + /** + * Wether to display the header with column titles. + **/ showHeader: { type: Boolean @@ -200,7 +209,7 @@ Htk.Grid = new Class break; } case Db.Model.Status.LOADING: - this.showMessage (_('Loading'), 'loader-black.gif'); + this.showMessage (_('Loading'), null); break; case Db.Model.Status.CLEAN: this.showMessage (this.emptyMessage, 'refresh.svg'); @@ -232,10 +241,19 @@ Htk.Grid = new Class td.colSpan = this.columns.length; tr.appendChild (td); - var img = document.createElement ('img'); - img.alt = ''; - img.src = 'image/'+ src; - td.appendChild (img); + if (src) + { + var img = document.createElement ('img'); + img.alt = ''; + img.src = 'image/'+ src; + td.appendChild (img); + } + else + { + var spinner = new Htk.Spinner (); + spinner.start (); + td.appendChild (spinner.getNode ()); + } var message = document.createTextNode (message); td.appendChild (message); diff --git a/web/js/htk/loader.css b/web/js/htk/loader.css deleted file mode 100644 index d1fbb82e..00000000 --- a/web/js/htk/loader.css +++ /dev/null @@ -1,74 +0,0 @@ - -.htk-loader -{ - font-size: 10px; - margin: 50px auto; - text-indent: -9999em; - width: 11em; - height: 11em; - border-radius: 50%; - background: #ffffff; - background: -moz-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); - background: -webkit-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); - background: -o-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); - background: -ms-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 42%); - background: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 42%); - position: relative; - -webkit-animation: load3 1.4s infinite linear; - animation: load3 1.4s infinite linear; - -webkit-transform: translateZ(0); - -ms-transform: translateZ(0); - transform: translateZ(0); -} -.htk-loader:before -{ - width: 50%; - height: 50%; - background: #ffffff; - border-radius: 100% 0 0 0; - position: absolute; - top: 0; - left: 0; - content: ''; -} -.htk-loader:after -{ - background: #0dc5c1; - width: 75%; - height: 75%; - border-radius: 50%; - content: ''; - margin: auto; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; -} -@-webkit-keyframes load3 -{ - 0% - { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% - { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -@keyframes load3 -{ - 0% - { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% - { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - diff --git a/web/js/htk/loader.js b/web/js/htk/loader.js deleted file mode 100755 index f2c26e9d..00000000 --- a/web/js/htk/loader.js +++ /dev/null @@ -1,13 +0,0 @@ -Htk.Loader = new Class -({ - Extends: Htk.Widget - ,Tag: 'htk-loader' - - ,initialize: function (props) - { - var loader = this.createElement ('div'); - loader.className = 'htk-loader'; - - this.parent (props); - } -}); diff --git a/web/js/htk/main.js b/web/js/htk/main.js index 64ea8fca..37f8eb6c 100755 --- a/web/js/htk/main.js +++ b/web/js/htk/main.js @@ -9,7 +9,7 @@ Vn.includeLib ('htk', ,'toast' ,'repeater' ,'grid' - ,'loader' + ,'spinner' ,'full-image' ,'image-editor' ,'assistant' @@ -30,6 +30,7 @@ Vn.includeLib ('htk', ,'field/image' ,'field/button' ,'field/table' + ,'field/search-entry' ,'column' ,'column/button' ,'column/link' diff --git a/web/js/htk/repeater.js b/web/js/htk/repeater.js index 91f312e0..bc78e34c 100755 --- a/web/js/htk/repeater.js +++ b/web/js/htk/repeater.js @@ -5,6 +5,9 @@ Htk.Repeater = new Class ,Child: 'model' ,Properties: { + /** + * The source data model. + **/ model: { type: Db.Model @@ -25,6 +28,9 @@ Htk.Repeater = new Class this._model; } } + /** + * The identifier for internal iterator. + **/ ,formId: { type: String @@ -37,6 +43,10 @@ Htk.Repeater = new Class this._formId; } } + /** + * {Function (Vn.BuilderResult, Db.Form)} Function to call after every + * box rendering. + **/ ,renderer: { type: Function @@ -49,6 +59,9 @@ Htk.Repeater = new Class this._renderer; } } + /** + * Message that should be displayed when source model is not ready. + **/ ,emptyMessage: { type: String @@ -140,7 +153,7 @@ Htk.Repeater = new Class break; } case Db.Model.Status.LOADING: - this._showMessage (_('Loading'), 'loader-black.gif'); + this._showMessage (_('Loading'), null); break; case Db.Model.Status.CLEAN: this._showMessage (this.emptyMessage, 'refresh.svg'); @@ -149,7 +162,7 @@ Htk.Repeater = new Class this._showMessage (_('ErrorLoadingData'), 'error.svg'); break; } - + this.node.appendChild (this._container); this.signalEmit ('change'); } @@ -166,10 +179,19 @@ Htk.Repeater = new Class div.className = 'message'; this._container.appendChild (div); - var img = document.createElement ('img'); - img.alt = ''; - img.src = 'image/'+ src; - div.appendChild (img); + if (src) + { + var img = document.createElement ('img'); + img.alt = ''; + img.src = 'image/'+ src; + div.appendChild (img); + } + else + { + var spinner = new Htk.Spinner (); + spinner.start (); + div.appendChild (spinner.getNode ()); + } div.appendChild (document.createTextNode (message)); } diff --git a/web/js/htk/spinner.js b/web/js/htk/spinner.js new file mode 100755 index 00000000..2ebc5d5f --- /dev/null +++ b/web/js/htk/spinner.js @@ -0,0 +1,27 @@ +Htk.Spinner = new Class +({ + Extends: Htk.Widget + ,Tag: 'htk-spinner' + + ,initialize: function (props) + { + var loader = this.createElement ('div'); + loader.className = 'htk-spinner'; + + var spin = document.createElement ('div'); + loader.appendChild (spin); + + this.spin = spin; + this.parent (props); + } + + ,start: function () + { + Vn.Node.addClass (this.spin, 'spinner'); + } + + ,stop: function () + { + Vn.Node.removeClass (this.spin, 'spinner'); + } +}); diff --git a/web/js/htk/style.css b/web/js/htk/style.css index 255f9ec7..00a10fa6 100755 --- a/web/js/htk/style.css +++ b/web/js/htk/style.css @@ -41,12 +41,14 @@ } .htk-grid .message { - height: 5em; + padding: 1.5em; } -.htk-grid .message img +.htk-grid .message > img, +.htk-grid .message > .htk-spinner { + display: inline-block; vertical-align: middle; - padding: 0.8em; + padding-right: 0.8em; height: 1.8em; } .htk-grid > tbody tr @@ -121,17 +123,18 @@ .htk-repeater > .message { - padding: 1em; + padding: 1.5em; text-align: center; } .htk-repeater > .message > * { vertical-align: middle; } -.htk-repeater > .message > img +.htk-repeater > .message > img, +.htk-repeater > .message > .htk-spinner { - padding: 0.8em; - padding-left: 0; + display: inline-block; + padding-right: .8em; height: 1.8em; } @@ -438,3 +441,74 @@ opacity: .7; } +/* Search entry */ + +.htk-search-entry +{ + background-color: white; + height: 2.2em; +} +.htk-search-entry > img +{ + margin: 0; + height: 1.5em; + margin-left: .4em; + vertical-align: middle; +} +.htk-search-entry > .entry +{ + margin: 0; + border: none; + width: 8em; + box-shadow: none; +} +.htk-search-entry > .entry:focus +{ + background-color: initial; +} + +/* Loader */ + +.htk-spinner +{ + position: relative; + display: inline-block; + box-sizing: border-box; +} +.htk-spinner > .spinner +{ + width: 1.8em; + height: 1.8em; +} +.htk-spinner > .spinner:before +{ + content: 'Loading…'; + position: absolute; + left: 0; + width: 1.2em; + height: 1.2em; +} +.htk-spinner > .spinner:not(:required):before +{ + content: ''; + border-radius: 50%; + border: .3em solid transparent; + border-top-color: #666; + border-left-color: #666; + animation: spinner 1s linear infinite; + -webkit-animation: spinner 1s linear infinite; +} +.htk-spinner.dark > .spinner:not(:required):before +{ + border-top-color: white; + border-left-color: white; +} +@keyframes spinner +{ + to {transform: rotate(360deg);} +} +@-webkit-keyframes spinner +{ + to {-webkit-transform: rotate(360deg);} +} + diff --git a/web/js/sql/batch.js b/web/js/sql/batch.js index 31225ec7..d3dcf170 100755 --- a/web/js/sql/batch.js +++ b/web/js/sql/batch.js @@ -91,6 +91,16 @@ Sql.Batch = new Class new Sql.Value ({param: param})); } + ,getValue: function (id) + { + var object = this.objects[id]; + + if (object instanceof Sql.Value) + return object.value; + + return null; + } + ,addParams: function (params) { for (var id in params) diff --git a/web/js/sql/filter-item.js b/web/js/sql/filter-item.js index 6867de68..c7dba4e0 100755 --- a/web/js/sql/filter-item.js +++ b/web/js/sql/filter-item.js @@ -18,9 +18,15 @@ Sql.FilterItem = new Class { return this._disabled; } + }, + primary: + { + type: Boolean } } + ,primary: true + ,isReady: function () { if (this._disabled) diff --git a/web/js/sql/filter.js b/web/js/sql/filter.js index de12f74d..d308465d 100755 --- a/web/js/sql/filter.js +++ b/web/js/sql/filter.js @@ -20,7 +20,7 @@ Sql.Filter = new Class var e = this.exprs.getArray (); for (var i = 0; i < e.length; i++) - if (e[i].isReady ()) + if (e[i].isReady () && e[i].primary) return true; return false; diff --git a/web/js/vn/builder.js b/web/js/vn/builder.js index ab0f8f9f..fa44974e 100755 --- a/web/js/vn/builder.js +++ b/web/js/vn/builder.js @@ -275,7 +275,6 @@ Vn.Builder = new Class var objectProps = {}; var childs = []; var events = {}; - var handler; var context = { klass: klass, @@ -293,9 +292,12 @@ Vn.Builder = new Class var attribute = a[i].nodeName; var value = a[i].nodeValue; - if (handler = this._getEventHandler (attribute, value)) + if (this._isEvent (attribute)) { - events[attribute.substr (3)] = handler; + var handler = this._getMethod (value) + + if (handler) + events[attribute.substr (3)] = handler; } else if (!/^(id|property)$/.test (attribute)) { @@ -432,8 +434,13 @@ Vn.Builder = new Class var attribute = a[i].nodeName; var value = a[i].nodeValue; - if (handler = this._getEventHandler (attribute, value)) - events[attribute.substr (3)] = handler; + if (this._isEvent (attribute)) + { + var handler = this._getMethod (value); + + if (handler) + events[attribute.substr (3)] = handler; + } else if (attribute !== 'id') attributes[attribute] = this._translateValue (value); } @@ -528,21 +535,18 @@ Vn.Builder = new Class } catch (e) { - method = null; + method = undefined; } - if (method === null) + if (method === undefined) this._showError ('Function \'%s\' not found', value); return method; } - ,_getEventHandler: function (attribute, value) - { - if (!(/^on-\w+/.test (attribute))) - return null; - - return this._getMethod (value); + ,_isEvent: function (attribute) + { + return /^on-\w+/.test (attribute); } ,_replaceFunc: function (token) diff --git a/web/js/vn/locale.js b/web/js/vn/locale.js index 19ffb550..ce298c3a 100755 --- a/web/js/vn/locale.js +++ b/web/js/vn/locale.js @@ -12,7 +12,7 @@ Vn.Locale = if (!this.language) { var language = navigator.language.substr (0, 2); - this.language = language ? language : 'es'; + this.language = language ? language : 'en'; } } diff --git a/web/locale/ca/forms/ecomerce/catalog.json b/web/locale/ca/forms/ecomerce/catalog.json index d976227e..9eaf8238 100755 --- a/web/locale/ca/forms/ecomerce/catalog.json +++ b/web/locale/ca/forms/ecomerce/catalog.json @@ -3,7 +3,7 @@ ,"SearchResults": "Resultats de cerca" ,"SelectFamily": "Selecciona una família" - ,"SelectSubtype": "Selecciona un subtipus en el menú de la dreta" + ,"Select filter from right menu": "Selecciona un filtre en el menú de la dreta" ,"ArticleNotFound": "Artcle no trobat" ,"ArticleNotAvailable": "Article no disponible" diff --git a/web/locale/ca/forms/ecomerce/ticket.json b/web/locale/ca/forms/ecomerce/ticket.json index 20681739..38507c12 100755 --- a/web/locale/ca/forms/ecomerce/ticket.json +++ b/web/locale/ca/forms/ecomerce/ticket.json @@ -1,7 +1,7 @@ { "OrderDetail": "Detall de l'encarrec" - ,"Print": "Imprimir albarà" + ,"Print delivery note": "Imprimir albarà" ,"TicketNumber:": "N ticket:" ,"DateExit:": "Data d'enviament:" diff --git a/web/locale/ca/js/htk.js b/web/locale/ca/js/htk.js index ac9f9338..5103c94b 100755 --- a/web/locale/ca/js/htk.js +++ b/web/locale/ca/js/htk.js @@ -26,4 +26,6 @@ Vn.Locale.add ,"Close": "Tancar" ,"Previous": "Anterior" ,"Next": "Següent" + ,"Search": "Cercar" + ,"Search...": "Cercar..." }); diff --git a/web/locale/en/forms/ecomerce/catalog.json b/web/locale/en/forms/ecomerce/catalog.json index 5b624961..d83185ae 100755 --- a/web/locale/en/forms/ecomerce/catalog.json +++ b/web/locale/en/forms/ecomerce/catalog.json @@ -3,7 +3,7 @@ ,"SearchResults": "Search results" ,"SelectFamily": "Select family" - ,"SelectSubtype": "Select a filter from the right menu" + ,"Select filter from right menu": "Select a filter from the right menu" ,"ArticleNotFound": "Item not found" ,"ArticleNotAvailable": "Item not available" diff --git a/web/locale/en/forms/ecomerce/confirm.json b/web/locale/en/forms/ecomerce/confirm.json index 04a7f490..29034f59 100755 --- a/web/locale/en/forms/ecomerce/confirm.json +++ b/web/locale/en/forms/ecomerce/confirm.json @@ -18,7 +18,7 @@ ,"Modify": "Modify" ,"Confirm": "Confirm" - ,"OrderPlacedSuccessfully": "Your order has been successfully completed" + ,"OrderPlacedSuccessfully": "Your order has been confirmed successfully" ,"OrderReserved": "We've booked your order but it seems that there have been problems with payment. Contact your sales." ,"Accept": "Accept" ,"PayNow": "Pay now" diff --git a/web/locale/en/forms/ecomerce/ticket.json b/web/locale/en/forms/ecomerce/ticket.json index 11ed2c30..a0937941 100755 --- a/web/locale/en/forms/ecomerce/ticket.json +++ b/web/locale/en/forms/ecomerce/ticket.json @@ -1,7 +1,7 @@ { "OrderDetail": "Order detail" - ,"Print": "Print delivery note" + ,"Print delivery note": "Print delivery note" ,"TicketNumber:": "Ticket number:" ,"DateExit:": "Delivery date:" diff --git a/web/locale/en/js/hedera.js b/web/locale/en/js/hedera.js index 23afb66c..8473f770 100755 --- a/web/locale/en/js/hedera.js +++ b/web/locale/en/js/hedera.js @@ -9,8 +9,8 @@ Vn.Locale.add ,"Login mail": "clientes@verdnatura.es" ,"Login phone": "+34 607 562 391" - ,"You've been too idle": "You've been too idle and session time has expired." - ,"Invalid login": "Username or password incorrect. Remember that case-sensitive." + ,"You've been too idle": "You have been idle too long and your session has expired." + ,"Invalid login": "Username or password incorrect. Remember that it is case-sensitive." ,"There was an internal error": "There was an internal error" ,"Menu": "Menu" diff --git a/web/locale/en/js/htk.js b/web/locale/en/js/htk.js index a40e636b..d468f283 100755 --- a/web/locale/en/js/htk.js +++ b/web/locale/en/js/htk.js @@ -26,4 +26,6 @@ Vn.Locale.add ,"Close": "Close" ,"Previous": "Previous" ,"Next": "Next" + ,"Search": "Search" + ,"Search...": "Search..." }); diff --git a/web/locale/es/forms/ecomerce/catalog.json b/web/locale/es/forms/ecomerce/catalog.json index 73dc56fb..8180d5fa 100755 --- a/web/locale/es/forms/ecomerce/catalog.json +++ b/web/locale/es/forms/ecomerce/catalog.json @@ -3,7 +3,7 @@ ,"SearchResults": "Resultados de búsqueda" ,"SelectFamily": "Selecciona una familia" - ,"SelectSubtype": "Selecciona un subtipo en el menú de la derecha" + ,"Select filter from right menu": "Selecciona un filtro en el menú de la derecha" ,"ArticleNotFound": "Artículo no encontrado" ,"ArticleNotAvailable": "Artículo no disponible" diff --git a/web/locale/es/forms/ecomerce/ticket.json b/web/locale/es/forms/ecomerce/ticket.json index f57b72fc..555129e8 100755 --- a/web/locale/es/forms/ecomerce/ticket.json +++ b/web/locale/es/forms/ecomerce/ticket.json @@ -1,7 +1,7 @@ { "OrderDetail": "Detalle del pedido" - ,"Print": "Imprimir albarán" + ,"Print delivery note": "Imprimir albarán" ,"TicketNumber:": "Nº ticket:" ,"DateExit:": "Fecha de envío:" diff --git a/web/locale/es/js/htk.js b/web/locale/es/js/htk.js index fad8c3a5..83d56af6 100755 --- a/web/locale/es/js/htk.js +++ b/web/locale/es/js/htk.js @@ -26,4 +26,6 @@ Vn.Locale.add ,"Close": "Cerrar" ,"Previous": "Anterior" ,"Next": "Siguiente" + ,"Search": "Buscar" + ,"Search...": "Buscar..." }); diff --git a/web/locale/fr/forms/ecomerce/catalog.json b/web/locale/fr/forms/ecomerce/catalog.json index 95e7adc9..86712ffb 100755 --- a/web/locale/fr/forms/ecomerce/catalog.json +++ b/web/locale/fr/forms/ecomerce/catalog.json @@ -3,7 +3,7 @@ ,"SearchResults": "Résultats de la recherche" ,"SelectFamily": "Choisissez une famille" - ,"SelectSubtype": "Sélectionnez le sous-menu sur la droite" + ,"Select filter from right menu": "Sélectionnez un filtre dans le menu de droite" ,"ArticleNotFound": "Article non trouvé" ,"ArticleNotAvailable": "Article non disponible" diff --git a/web/locale/fr/forms/ecomerce/ticket.json b/web/locale/fr/forms/ecomerce/ticket.json index 94114d44..e0692039 100755 --- a/web/locale/fr/forms/ecomerce/ticket.json +++ b/web/locale/fr/forms/ecomerce/ticket.json @@ -1,7 +1,7 @@ { "OrderDetail": "Détails de la commande" - ,"Print": "Imprimer bulletin de livraison" + ,"Print delivery note": "Imprimer bulletin de livraison" ,"TicketNumber:": "Num ticket:" ,"DateExit:": "Date d'envoi:" diff --git a/web/locale/fr/js/htk.js b/web/locale/fr/js/htk.js index 88d614b6..9b871c88 100755 --- a/web/locale/fr/js/htk.js +++ b/web/locale/fr/js/htk.js @@ -26,4 +26,6 @@ Vn.Locale.add ,"Close": "Croche" ,"Previous": "Précédent" ,"Next": "Suivant" + ,"Search": "Recherche" + ,"Search...": "Recherche..." }); diff --git a/web/locale/mn/forms/ecomerce/catalog.json b/web/locale/mn/forms/ecomerce/catalog.json index 5b624961..1b372742 100755 --- a/web/locale/mn/forms/ecomerce/catalog.json +++ b/web/locale/mn/forms/ecomerce/catalog.json @@ -3,7 +3,7 @@ ,"SearchResults": "Search results" ,"SelectFamily": "Select family" - ,"SelectSubtype": "Select a filter from the right menu" + ,"Select filter from right menu": "Зөв цэс нь шүүлтүүр сонгоно уу" ,"ArticleNotFound": "Item not found" ,"ArticleNotAvailable": "Item not available" diff --git a/web/locale/mn/forms/ecomerce/ticket.json b/web/locale/mn/forms/ecomerce/ticket.json index 11ed2c30..a0937941 100755 --- a/web/locale/mn/forms/ecomerce/ticket.json +++ b/web/locale/mn/forms/ecomerce/ticket.json @@ -1,7 +1,7 @@ { "OrderDetail": "Order detail" - ,"Print": "Print delivery note" + ,"Print delivery note": "Print delivery note" ,"TicketNumber:": "Ticket number:" ,"DateExit:": "Delivery date:" diff --git a/web/locale/mn/js/htk.js b/web/locale/mn/js/htk.js index a40e636b..a3a262fd 100755 --- a/web/locale/mn/js/htk.js +++ b/web/locale/mn/js/htk.js @@ -26,4 +26,6 @@ Vn.Locale.add ,"Close": "Close" ,"Previous": "Previous" ,"Next": "Next" + ,"Search": "хайх" + ,"Search...": "хайх..." }); diff --git a/web/reports/delivery-note/delivery-note.js b/web/reports/delivery-note/delivery-note.js new file mode 100755 index 00000000..ac2279a0 --- /dev/null +++ b/web/reports/delivery-note/delivery-note.js @@ -0,0 +1,21 @@ + +Vn.DeliveryNote = new Class +({ + Extends: Vn.Report + + ,subtotalRenderer: function (column, form) + { + column.value = this.subtotal (form); + } + + ,subtotal: function (form) + { + var price = form.get ('price'); + var discount = form.get ('discount'); + + if (price && form.get ('fixed')) + return form.get ('amount') * price * ((100 - discount) / 100); + else + return null; + } +}); diff --git a/web/reports/delivery-note/style.css b/web/reports/delivery-note/style.css new file mode 100644 index 00000000..08419bfb --- /dev/null +++ b/web/reports/delivery-note/style.css @@ -0,0 +1,45 @@ +* +{ + font-size: 4mm; +} +.sheet +{ + height: auto; +} +h1 +{ + font-weight: normal; + font-size: 200%; + text-align: center; + margin: 0 auto; + margin-bottom: 8mm; +} +.htk-grid +{ + border-collapse: collapse; + width: 100%; + margin: 0 auto; + padding: 0; +} +thead > tr +{ + border-bottom: 1px solid #333; + height: 10mm; +} +th +{ + font-weight: normal; +} +td +{ + padding-left: 2mm; +} +tbody > tr +{ + height: 18mm; +} +.cell-image > img +{ + width: 15mm; +} + diff --git a/web/reports/delivery-note/ui.xml b/web/reports/delivery-note/ui.xml new file mode 100755 index 00000000..bde2c553 --- /dev/null +++ b/web/reports/delivery-note/ui.xml @@ -0,0 +1,97 @@ + + + + + + SELECT t.id, date, a.Agencia, note, p.name province, + zip_code, city, c.name, consignee, invoice + FROM ticket_view t + JOIN address_view c ON t.address_id = c.id + JOIN vn2008.Agencias a ON t.agency_id = a.Id_Agencia + JOIN vn2008.province p ON c.province_id = p.province_id + WHERE t.id = #ticket + + + + +
+
- +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + + +
+ + + + + + + + + + + SELECT m.item_id, amount, concept, Categoria, Medida, Tallos, Color, + Abreviatura, IF(fixed != FALSE, price, NULL) price, fixed, discount + FROM ticket_row_view m + INNER JOIN vn2008.Articles a + ON m.item_id = a.Id_Article AND ticket_id = #ticket + LEFT JOIN vn2008.Origen o + ON a.id_origen = o.id + ORDER BY concept + + + + + + + + + + + + + + +
+ diff --git a/web/reports/shelves-report/shelves-report.js b/web/reports/shelves-report/shelves-report.js index 5344cde6..8ca24635 100755 --- a/web/reports/shelves-report/shelves-report.js +++ b/web/reports/shelves-report/shelves-report.js @@ -2,4 +2,364 @@ Vn.ShelvesReport = new Class ({ Extends: Vn.Report + + ,nItem: -1 + ,nColors: 5 + + ,open: function (batch) + { + this.batch = batch; + this.title = batch.getValue ('title'); + this.maxAmount = batch.getValue ('max-amount'); + this.showPacking = batch.getValue ('show-packing'); + this.stack = batch.getValue ('stack'); + + var query = + 'SELECT id, name, width, height, depth, max_height, tray_height, '+ + 'first_tray_elevation, tray_density, vspacing, hspacing '+ + 'FROM shelf WHERE id = #shelf; '+ + 'CALL item_organizer (#wh, #date, #family, #filter)'; + + this.conn.execQuery (query, this.onQueryExec.bind (this), this.batch); + } + + ,onQueryExec: function (resultSet) + { + // Fetch query data + + var res = resultSet.fetchResult (); + res.next (); + + var maxWidth = 170; + var maxHeight = 200; + + var scale = maxWidth / res.get ('width'); + + if (res.get ('max_height') * scale > maxHeight) + scale = maxHeight / res.get ('max_height'); + + var shelf = this.shelf = + { + width: res.get ('width') * scale + ,height: res.get ('height') * scale + ,depth: res.get ('depth') * scale + ,maxHeight: res.get ('max_height') * scale + ,trayHeight: res.get ('tray_height') * scale + ,firstTrayElevation: res.get ('first_tray_elevation') * scale + ,trayDensity: res.get ('tray_density') * scale + ,vspacing: res.get ('vspacing') * scale + ,hspacing: res.get ('hspacing') * scale + }; + + var items = this.items = []; + var remainings = this.remainings = []; + var res = resultSet.fetchResult (); + + if (res.data.length == 0) + { + Htk.Toast.showError (_('No items found, check that all fields are correct')); + return; + } + + var boxScale = scale * 10; + + while (res.next ()) + if (!this.maxAmount || res.get ('etiquetas') <= this.maxAmount) + { + items.push ({ + id: res.get ('Id_Article') + ,name: res.get ('Article') + ,packing: res.get ('packing') + ,amount: res.get ('etiquetas') + ,boxHeight: res.get ('z') * boxScale + ,boxWidth: res.get ('x') * boxScale + ,boxDepth: res.get ('y') * boxScale + }); + } + else + { + remainings.push ({ + id: res.get ('Id_Article') + ,name: res.get ('Article') + ,packing: res.get ('packing') + ,amount: res.get ('etiquetas') + }); + } + + // Intializes the allocator + + alloc = this.alloc = new Vn.Allocator (); + alloc.items = items; + alloc.shelfFunc = this.drawShelf.bind (this); + alloc.boxFunc = this.drawBox.bind (this); + alloc.stack = this.stack; + alloc.nTrays = Math.ceil ( + (shelf.height - shelf.firstTrayElevation) / + (shelf.trayHeight + shelf.trayDensity) + ); + alloc.width = shelf.width - shelf.hspacing * 2; + alloc.depth = shelf.depth; + alloc.trayHeight = shelf.trayHeight - shelf.vspacing; + alloc.topTrayHeight = shelf.maxHeight - shelf.vspacing + - shelf.firstTrayElevation - (alloc.nTrays - 1) * shelf.trayHeight; + + // Opens the report + + this.createWindow (); + } + + ,onWindowCreate: function () + { + // Remaining amount + + var remainings = this.remainings; + + if (remainings.length > 0) + { + var sheet = this.doc.createElement ('div'); + sheet.className = 'sheet'; + this.doc.body.appendChild (sheet); + + var title = this.doc.createElement ('h1'); + title.className = 'title'; + title.appendChild (this.doc.createTextNode (this.title)); + sheet.appendChild (title); + + var subtitle = this.doc.createElement ('h2'); + subtitle.className = 'subtitle'; + subtitle.appendChild (this.doc.createTextNode (_('Pallets'))); + sheet.appendChild (subtitle); + + var ul = this.doc.createElement ('ul'); + sheet.appendChild (ul); + + for (var i = 0; i < remainings.length; i++) + { + var li = this.doc.createElement ('li'); + ul.appendChild (li); + + var span = this.doc.createElement ('span'); + span.className = 'item-id'; + span.appendChild (this.doc.createTextNode (remainings[i].id.toLocaleString ())); + li.appendChild (span); + + var span = this.doc.createElement ('span'); + span.className = 'item'; + span.appendChild (this.doc.createTextNode (remainings[i].name)); + li.appendChild (span); + + if (this.showPacking) + span.appendChild (this.doc.createTextNode (' '+ remainings[i].packing)); + + var span = this.doc.createElement ('span'); + span.className = 'amount'; + span.appendChild (this.doc.createTextNode (remainings[i].amount)); + li.appendChild (span); + } + } + + // Draws the shelves + + this.alloc.run (); + this.drawShelfEnding (); + } + + ,drawShelf: function (allocator, item) + { + var shelf = this.shelf; + + var sheet = this.doc.createElement ('div'); + sheet.className = 'sheet'; + this.doc.body.appendChild (sheet); + + // Draws the title + + var pageNumber = this.doc.createElement ('h1'); + pageNumber.className = 'page-number'; + pageNumber.appendChild (this.doc.createTextNode (allocator.currentShelf + 1)); + sheet.appendChild (pageNumber); + + var title = this.doc.createElement ('h1'); + title.className = 'title'; + title.appendChild (this.doc.createTextNode (this.title)); + sheet.appendChild (title); + + var subtitle = this.doc.createElement ('h2'); + subtitle.className = 'subtitle'; + subtitle.appendChild (this.doc.createTextNode (item.id.toLocaleString ())); + sheet.appendChild (subtitle); + + this.drawShelfEnding (); + this.lastSubtitle = subtitle; + + // Draws the shelf + + var shelfDiv = this.shelfDiv = this.doc.createElement ('div'); + shelfDiv.className = 'shelf'; + shelfDiv.style.width = this.mm (shelf.width); + shelfDiv.style.height = this.mm (shelf.maxHeight); + sheet.appendChild (shelfDiv); + + // Draws trays + + var lastTrayY = shelf.firstTrayElevation; + + if (shelf.trayHeight > 0) + while (lastTrayY + shelf.trayDensity < shelf.height) + { + var tray = this.doc.createElement ('div'); + tray.className = 'tray'; + tray.style.width = this.mm (shelf.width); + tray.style.height = this.mm (shelf.trayDensity); + tray.style.bottom = this.mm (lastTrayY); + shelfDiv.appendChild (tray); + + lastTrayY += shelf.trayHeight + shelf.trayDensity; + } + } + + ,drawShelfEnding: function () + { + if (this.lastSubtitle) + this.lastSubtitle.appendChild ( + this.doc.createTextNode (' - '+ this.lastItem.id.toLocaleString ())); + } + + ,mm: function (size) + { + return size.toFixed (2) +'mm'; + } + + ,drawBox: function (allocator, item, amount) + { + if (item.boxWidth == 0 || item.boxHeight == 0) + return; + + var shelf = this.shelf; + + var x = allocator.trayX + shelf.hspacing; + var y = allocator.trayY + + shelf.firstTrayElevation + shelf.trayDensity + + allocator.currentTray * (shelf.trayHeight + shelf.trayDensity); + + var box = this.doc.createElement ('div'); + box.className = 'box'; + this.shelfDiv.appendChild (box); + + box.style.left = this.mm (x); + box.style.bottom = this.mm (y); + box.style.width = this.mm (item.boxWidth); + box.style.height = this.mm (item.boxHeight); + + if (amount == 0) + this.nItem++; + + var nColor = this.nItem % this.nColors; + Vn.Node.addClass (box, 'color'+ nColor); + + if (amount == 0 || allocator.firstShelfBox) + { + var fontSize = item.boxWidth / 5.2; + + if (fontSize > item.boxHeight - 1) + fontSize = item.boxHeight - 1; + + var boxLabel = this.doc.createElement ('div'); + boxLabel.className = 'box-label'; + boxLabel.style.fontSize = this.mm (fontSize); + boxLabel.appendChild (this.doc.createTextNode (item.id.toLocaleString ())); + box.appendChild (boxLabel); + } + + this.lastItem = item; + } +}); + +Vn.Allocator = new Class +({ + addShelf: function (item) + { + this.currentShelf++; + this.firstShelfBox = true; + + if (this.shelfFunc) + this.shelfFunc (this, item); + } + + ,addTray: function (item) + { + if (this.currentTray <= 0) + { + this.addShelf (item); + this.currentTray = this.nTrays - 1; + } + else + this.currentTray--; + + this.trayX = 0; + } + + ,addColumn: function (item) + { + if (this.trayX + this.columnWidth + item.boxWidth > this.width + || this.currentTray == -1) + this.addTray (item); + else + this.trayX += this.columnWidth; + + this.trayY = 0; + this.columnWidth = item.boxWidth; + this.lastBoxWidth = item.boxWidth; + } + + ,addBox: function (item, amount) + { + var trayHeight = this.trayHeight; + + if (this.currentTray == this.nTrays - 1) + trayHeight = this.topTrayHeight; + + if (this.trayY + item.boxHeight > trayHeight + || item.boxWidth > this.lastBoxWidth + || (!this.stack && amount == 0)) + this.addColumn (item); + + if (this.boxFunc) + this.boxFunc (this, item, amount); + + this.trayY += item.boxHeight; + + if (item.boxWidth < this.lastBoxWidth) + this.lastBoxWidth = item.boxWidth; + } + + ,run: function () + { + this.firstShelfBox = false; + this.currentShelf = -1; + this.currentTray = -1; + this.columnWidth = 0; + this.lastBoxWidth = 0; + this.trayX = 0; + this.trayY = 0; + this.remaining = false; + + for (var i = 0; i < this.items.length; i++) + { + var item = this.items[i]; + var boxIncrement = Math.floor (this.depth / item.boxDepth); + + if (boxIncrement < 1) + boxIncrement = 1; + + for (var amount = 0; amount < item.amount; amount += boxIncrement) + { + this.addBox (item, amount); + this.firstShelfBox = false; + } + } + + return this.currentShelf + 1; + } + }); From 32e2cd9d8d929cd677fd1033c248a3625edc19c4 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Thu, 26 Nov 2015 13:30:04 +0100 Subject: [PATCH 21/39] =?UTF-8?q?Traducci=C3=B3n=20a=20portugues,=20Htk.Co?= =?UTF-8?q?lum=20ahora=20soporta=20clases=20css,=20Htk.Column=20es=20ahora?= =?UTF-8?q?=20el=20encargado=20de=20crear=20la=20cabecera=20del=20grid=20(?= =?UTF-8?q?renderHeader),=20estilo=20de=20informes=20actualizado,=20formul?= =?UTF-8?q?ario=20tickets=20actualizado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/forms/ecomerce/basket/ui.xml | 8 +- web/forms/ecomerce/catalog/style.css | 14 +- web/forms/ecomerce/orders/orders.js | 8 +- web/forms/ecomerce/orders/style.css | 23 +-- web/forms/ecomerce/orders/ui.xml | 26 ++- web/forms/ecomerce/ticket/style.css | 49 +++++- web/forms/ecomerce/ticket/ticket.js | 5 + web/forms/ecomerce/ticket/ui.xml | 161 +++++++++--------- web/forms/news/new/ui.xml | 28 ++- web/forms/news/news/ui.xml | 14 +- web/js/hedera/gui.css | 10 +- web/js/hedera/report.css | 62 ++++++- web/js/hedera/report.html | 6 +- web/js/hedera/report.js | 8 +- web/js/htk/column.js | 26 ++- web/js/htk/column/button.js | 7 +- web/js/htk/column/check.js | 7 +- web/js/htk/column/date.js | 7 +- web/js/htk/column/image.js | 20 +-- web/js/htk/column/link.js | 1 - web/js/htk/column/radio.js | 3 +- web/js/htk/column/spin.js | 15 +- web/js/htk/column/text.js | 8 +- web/js/htk/grid.js | 8 +- web/js/htk/style.css | 76 ++++++--- web/locale/ca/forms/ecomerce/orders.json | 4 +- web/locale/en/forms/ecomerce/orders.json | 4 +- web/locale/es/forms/ecomerce/orders.json | 4 +- web/locale/fr/forms/ecomerce/orders.json | 4 +- web/locale/mn/forms/ecomerce/orders.json | 4 +- web/locale/pt/forms/account/address-list.json | 11 ++ web/locale/pt/forms/account/address.json | 15 ++ web/locale/pt/forms/account/conf.json | 19 +++ web/locale/pt/forms/admin/access-log.json | 15 ++ web/locale/pt/forms/admin/items.json | 9 + web/locale/pt/forms/admin/links.json | 6 + web/locale/pt/forms/admin/photos.json | 12 ++ web/locale/pt/forms/admin/shelves.json | 21 +++ web/locale/pt/forms/admin/users.json | 12 ++ web/locale/pt/forms/admin/visits.json | 31 ++++ web/locale/pt/forms/agencies/packages.json | 9 + web/locale/pt/forms/agencies/provinces.json | 10 ++ web/locale/pt/forms/cms/about.json | 47 +++++ web/locale/pt/forms/cms/contact.json | 20 +++ web/locale/pt/forms/cms/home.json | 13 ++ web/locale/pt/forms/cms/location.json | 3 + web/locale/pt/forms/cms/training.json | 1 + web/locale/pt/forms/cms/why.json | 25 +++ web/locale/pt/forms/ecomerce/basket.json | 29 ++++ web/locale/pt/forms/ecomerce/catalog.json | 49 ++++++ web/locale/pt/forms/ecomerce/checkout.json | 31 ++++ web/locale/pt/forms/ecomerce/confirm.json | 25 +++ web/locale/pt/forms/ecomerce/invoices.json | 8 + web/locale/pt/forms/ecomerce/orders.json | 36 ++++ web/locale/pt/forms/ecomerce/ticket.json | 30 ++++ web/locale/pt/forms/news/new.json | 12 ++ web/locale/pt/forms/news/news.json | 12 ++ web/locale/pt/js/db.js | 8 + web/locale/pt/js/hedera.js | 57 +++++++ web/locale/pt/js/htk.js | 31 ++++ web/locale/pt/js/vn.js | 44 +++++ web/locale/pt/pages/tpv.json | 4 + web/locale/pt/pages/update-browser.json | 4 + web/locale/pt/pages/version-menu.json | 8 + web/locale/pt/rest/query.json | 5 + web/reports/delivery-note/style.css | 42 ++--- web/reports/delivery-note/ui.xml | 88 ++++------ 67 files changed, 1108 insertions(+), 314 deletions(-) create mode 100644 web/locale/pt/forms/account/address-list.json create mode 100644 web/locale/pt/forms/account/address.json create mode 100644 web/locale/pt/forms/account/conf.json create mode 100644 web/locale/pt/forms/admin/access-log.json create mode 100644 web/locale/pt/forms/admin/items.json create mode 100644 web/locale/pt/forms/admin/links.json create mode 100644 web/locale/pt/forms/admin/photos.json create mode 100644 web/locale/pt/forms/admin/shelves.json create mode 100644 web/locale/pt/forms/admin/users.json create mode 100644 web/locale/pt/forms/admin/visits.json create mode 100644 web/locale/pt/forms/agencies/packages.json create mode 100644 web/locale/pt/forms/agencies/provinces.json create mode 100644 web/locale/pt/forms/cms/about.json create mode 100644 web/locale/pt/forms/cms/contact.json create mode 100644 web/locale/pt/forms/cms/home.json create mode 100644 web/locale/pt/forms/cms/location.json create mode 100644 web/locale/pt/forms/cms/training.json create mode 100644 web/locale/pt/forms/cms/why.json create mode 100644 web/locale/pt/forms/ecomerce/basket.json create mode 100644 web/locale/pt/forms/ecomerce/catalog.json create mode 100644 web/locale/pt/forms/ecomerce/checkout.json create mode 100644 web/locale/pt/forms/ecomerce/confirm.json create mode 100644 web/locale/pt/forms/ecomerce/invoices.json create mode 100644 web/locale/pt/forms/ecomerce/orders.json create mode 100644 web/locale/pt/forms/ecomerce/ticket.json create mode 100644 web/locale/pt/forms/news/new.json create mode 100644 web/locale/pt/forms/news/news.json create mode 100644 web/locale/pt/js/db.js create mode 100644 web/locale/pt/js/hedera.js create mode 100644 web/locale/pt/js/htk.js create mode 100644 web/locale/pt/js/vn.js create mode 100644 web/locale/pt/pages/tpv.json create mode 100644 web/locale/pt/pages/update-browser.json create mode 100644 web/locale/pt/pages/version-menu.json create mode 100644 web/locale/pt/rest/query.json diff --git a/web/forms/ecomerce/basket/ui.xml b/web/forms/ecomerce/basket/ui.xml index ac891399..5f0e4c26 100755 --- a/web/forms/ecomerce/basket/ui.xml +++ b/web/forms/ecomerce/basket/ui.xml @@ -7,17 +7,17 @@ image="image/dark/preferences.svg" tip="_ConfigureOrder" on-click="onConfigureClick" - showText="true"/> + show-text="true"/> + show-text="true"/> + show-text="true"/>
@@ -48,7 +48,7 @@

OrderTotal - +

diff --git a/web/forms/ecomerce/catalog/style.css b/web/forms/ecomerce/catalog/style.css index 391d48e0..1405c631 100755 --- a/web/forms/ecomerce/catalog/style.css +++ b/web/forms/ecomerce/catalog/style.css @@ -253,10 +253,10 @@ td.third-category } .item-box { + display: inline-block; text-align: left; position: relative; width: 22em; - display: inline-block; padding: .8em; margin: .4em; margin-bottom: .1em; @@ -311,13 +311,6 @@ td.third-category float: right; } -/* Transitions */ - -.right-panel -{ - transition: right .3s; -} - /* Mobile */ .catalog-actions > button.menu @@ -340,10 +333,13 @@ td.third-category top: 0; right: -17em; z-index: 20; + transition: 200ms ease-out all; + -webkit-transition: 200ms ease-out all; } .right-panel.show { - right: 0; + transform: translateZ(0) translateX(-17em); + -webkit-transform: translateZ(0) translateX(-17em); } .catalog div.center { diff --git a/web/forms/ecomerce/orders/orders.js b/web/forms/ecomerce/orders/orders.js index 46729a5b..fc181f98 100755 --- a/web/forms/ecomerce/orders/orders.js +++ b/web/forms/ecomerce/orders/orders.js @@ -25,14 +25,10 @@ Vn.Orders = new Class ,balanceConditionalFunc: function (field, value) { - var className = 'balance-amount '; - if (value > 0) - className += 'positive-balance'; + Vn.Node.removeClass (this.$('balance'), 'negative'); else - className += 'negative-balance'; - - field.node.className = className; + Vn.Node.addClass (this.$('balance'), 'negative'); } ,onPayButtonClick: function () diff --git a/web/forms/ecomerce/orders/style.css b/web/forms/ecomerce/orders/style.css index 4807abbf..5b4038f2 100755 --- a/web/forms/ecomerce/orders/style.css +++ b/web/forms/ecomerce/orders/style.css @@ -40,32 +40,33 @@ /* Balance */ -.balance img +.balance +{ + margin-top: 1.2em; + margin-right: .5em; +} +.balance > * { vertical-align: middle; - padding-left: 0.3em; - cursor: pointer; } -.balance-amount +.balance > .amount { color: white; padding: 0.3em; } -.balance-info +.balance > .info { - height: 1em; + display: inline; + cursor: pointer; + height: 1.2em; cursor: pointer; } -.positive-balance +.balance > .negative { background-color: #EF5350; border-radius: 0.1em; box-shadow: 0 0 0.4em #666; } -.negative-balance -{ - color: white; -} .balance-popup { width: 25em; diff --git a/web/forms/ecomerce/orders/ui.xml b/web/forms/ecomerce/orders/ui.xml index 89764dce..d5c6b0f1 100755 --- a/web/forms/ecomerce/orders/ui.xml +++ b/web/forms/ecomerce/orders/ui.xml @@ -12,12 +12,26 @@

LastOrders

-
- PendingBalance: - - - - Info +
+ + Balance: + + + + + + + Info
div +{ + padding-bottom: .8em; +} +.ticket .head p +{ + margin: .2em; +} +.ticket .head p.important +{ + font-size: 1.4em; +} +.ticket .total +{ + text-align: right; +} + +/* Lines */ + +.ticket .line +{ + padding: .5em 0; +} +.ticket .line p +{ + margin: .1em 0; +} +.ticket .amount +{ + float: left; +} +.ticket .subtotal +{ + float: right; } diff --git a/web/forms/ecomerce/ticket/ticket.js b/web/forms/ecomerce/ticket/ticket.js index 979b126c..e677e41a 100755 --- a/web/forms/ecomerce/ticket/ticket.js +++ b/web/forms/ecomerce/ticket/ticket.js @@ -14,6 +14,11 @@ Vn.Ticket = new Class { column.value = this.subtotal (form); } + + ,repeaterFunc: function (res, form) + { + res.$('subtotal').value = this.subtotal (form); + } ,subtotal: function (form) { diff --git a/web/forms/ecomerce/ticket/ui.xml b/web/forms/ecomerce/ticket/ui.xml index 28367139..24327ea8 100755 --- a/web/forms/ecomerce/ticket/ui.xml +++ b/web/forms/ecomerce/ticket/ui.xml @@ -29,95 +29,86 @@ image="image/dark/print.svg" tip="_Print delivery note" on-click="onPrintClick" - showText="true"/> + show-text="true"/>
-
- - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - -
- - - - - -
- - - - - - - - - - - SELECT m.item_id, amount, concept, Categoria, Medida, Tallos, Color, - Abreviatura, IF(fixed != FALSE, price, NULL) price, fixed, discount - FROM ticket_row_view m - INNER JOIN vn2008.Articles a - ON m.item_id = a.Id_Article AND ticket_id = #ticket - LEFT JOIN vn2008.Origen o - ON a.id_origen = o.id - ORDER BY concept - - - - - - - - - - - - - - - - - - - +
+
+

+ +

+
+
+

+ Delivery +

+

+ +

+

+ +

+

+ + + () +

+
+
+

+ Total + + + +

+
+ + + + SELECT m.item_id, amount, concept, Categoria, Medida, Tallos, Color, + Abreviatura, IF(fixed != FALSE, price, NULL) price, fixed, discount + FROM ticket_row_view m + INNER JOIN vn2008.Articles a + ON m.item_id = a.Id_Article AND ticket_id = #ticket + LEFT JOIN vn2008.Origen o + ON a.id_origen = o.id + ORDER BY concept + + + + + + + + +
+

+ + + +

+

+ x + +

+

+ +

+
+
+ +
diff --git a/web/forms/news/new/ui.xml b/web/forms/news/new/ui.xml index ff7017c5..d73fc03c 100755 --- a/web/forms/news/new/ui.xml +++ b/web/forms/news/new/ui.xml @@ -4,15 +4,23 @@ - - - SELECT id, title, text, tag - FROM news WHERE id = #new + + + SELECT id, title, text, tag + FROM news WHERE id = #new + - + + + +

AddEditNew

@@ -34,14 +42,16 @@
- +
- + - SELECT name, description FROM news_tag - ORDER BY description + + SELECT name, description FROM news_tag + ORDER BY description +
diff --git a/web/forms/news/news/ui.xml b/web/forms/news/news/ui.xml index a02e21c3..b1694923 100755 --- a/web/forms/news/news/ui.xml +++ b/web/forms/news/news/ui.xml @@ -12,12 +12,14 @@
- - SELECT n.id, c.Cliente, priority, image, - CONCAT(LEFT(n.title, 25), '...') title - FROM news n - JOIN vn2008.Clientes c ON n.user_id = c.Id_Cliente - ORDER BY priority, n.date_time DESC + + + SELECT n.id, c.Cliente, priority, image, + CONCAT(LEFT(n.title, 25), '...') title + FROM news n + JOIN vn2008.Clientes c ON n.user_id = c.Id_Cliente + ORDER BY priority, n.date_time DESC + .left-panel, .vn-gui > .body { transition-property: left, right; - transition-duration: .3s; + transition-duration: 200ms; } .vn-gui .top-bar { - transition: background-color .3s; + transition: background-color 300ms; } /* Desktop */ @@ -354,10 +353,13 @@ top: 0; left: -15em; box-shadow: 0 0.2em 0.2em #333; + transition: 200ms ease-out all; + -webkit-transition: 200ms ease-out all; } .vn-gui .left-panel.show { - left: 0; + transform: translateZ(0) translateX(15em); + -webkit-transform: translateZ(0) translateX(15em); } .vn-gui .form-holder { diff --git a/web/js/hedera/report.css b/web/js/hedera/report.css index 973d54ef..1c39b968 100755 --- a/web/js/hedera/report.css +++ b/web/js/hedera/report.css @@ -15,7 +15,7 @@ width: 100%; page-break-after: always; } - .print-button + #topbar { display: none; } @@ -25,6 +25,7 @@ body { background-color: #EEE; + padding-top: 3.9em; } .sheet { @@ -35,24 +36,33 @@ box-shadow: 0 1mm 1mm #CCC; padding: 20mm; } - .print-button + #topbar { position: fixed; - top: 1.5em; - right: 1.5em; - border-radius: 2px; + top: 0; + left: 0; + right: 0; + height: 4em; background-color: #009688; + z-index: 100; + box-shadow: 0 .1em .1em #AAA; + } + #topbar > button + { + float: right; + background-color: transparent; color: white; padding: .4em; z-index: 100; border: none; cursor: pointer; - box-shadow: 0 .1em .1em #AAA; - font-size: 1.4em; + font-size: 1.15em; + height: 100%; + padding: 0 1em; } - .print-button:hover + #topbar > button:hover { - background-color: #00796B; + background-color: rgba(1, 1, 1, 0.2); } } * @@ -74,3 +84,37 @@ body /* page-break-after: always;*/ } +/* Widgets */ + +.htk-grid +{ + border-collapse: collapse; + width: 100%; + margin: 0 auto; + padding: 0; +} +.htk-grid > thead > tr +{ + border-bottom: 1px solid #333; + height: 10mm; +} +.htk-grid > thead th +{ + text-align: left; + font-weight: normal; +} +.htk-grid tr +{ + height: 2em; +} +.htk-grid > thead th, +.htk-grid td +{ + padding-left: 3mm; +} +.htk-grid .cell-spin +{ + text-align: right; +} + + diff --git a/web/js/hedera/report.html b/web/js/hedera/report.html index 951db928..908c81fd 100755 --- a/web/js/hedera/report.html +++ b/web/js/hedera/report.html @@ -10,5 +10,9 @@ Report - + +
+ +
+ diff --git a/web/js/hedera/report.js b/web/js/hedera/report.js index e49035a5..4f881da8 100755 --- a/web/js/hedera/report.js +++ b/web/js/hedera/report.js @@ -56,7 +56,7 @@ Vn.Report = new Class { var reportWindow = window.open ( 'js/hedera/report.html', '_blank', - 'height=950, width=950, resizable=yes, fullscreen=no,'+ + 'height=650, width=950, resizable=yes, fullscreen=no,'+ 'titlebar=no, menubar=no, toolbar=no, location=no, scrollbars=yes' ); @@ -83,11 +83,9 @@ Vn.Report = new Class this.includeCss ('reports/'+ this.info.path +'/style.css'); - var printButton = this.doc.createElement ('button'); - printButton.className = 'print-button'; - printButton.appendChild (this.doc.createTextNode (_('Print'))); + var printButton = this.doc.getElementById ('print'); printButton.addEventListener ('click', this.print.bind (this)); - this.doc.body.appendChild (printButton); + Vn.Node.setText (printButton, _('Print')); this.onWindowCreate (); } diff --git a/web/js/htk/column.js b/web/js/htk/column.js index 16dc2d87..d57ca6f5 100755 --- a/web/js/htk/column.js +++ b/web/js/htk/column.js @@ -43,14 +43,22 @@ Htk.Column = new Class type: String ,set: function (x) { - this._class = x; + this._userCssClass = x; + + if (this._cssClass) + this._cssClass = x +' '+ this._cssClass; + else + this._cssClass = x; } ,get: function () { - return this._class; + return this._userCssClass; } } } + + ,_cssClass: null + ,_userCssClass: null /** * Initializes the column. @@ -60,6 +68,16 @@ Htk.Column = new Class this.td = document.createElement ('td'); this.parent (props); } + + ,renderHeader: function () + { + var th = document.createElement ('th'); + + if (this.title) + th.appendChild (document.createTextNode (this.title)); + + return th; + } /** * Draws the cell and returns its associated td. @@ -71,8 +89,8 @@ Htk.Column = new Class { var td = this.td.cloneNode (true); - if (this._class) - td.className = this._class; + if (this._cssClass) + td.className = this._cssClass; return td; } diff --git a/web/js/htk/column/button.js b/web/js/htk/column/button.js index 49842f4f..8f79b127 100755 --- a/web/js/htk/column/button.js +++ b/web/js/htk/column/button.js @@ -15,13 +15,18 @@ Htk.ColumnButton = new Class ,value: null } } + + ,initialize: function (props) + { + this._cssClass = 'cell-button'; + this.parent (props); + } ,render: function (tr) { var td = this.parent (tr); var button = document.createElement ('button'); - button.className = 'cell-button'; button.addEventListener ('click', this.buttonClicked.bind (this, this.value, tr, button)); td.appendChild (button); diff --git a/web/js/htk/column/check.js b/web/js/htk/column/check.js index e772dcf7..446a5bd0 100755 --- a/web/js/htk/column/check.js +++ b/web/js/htk/column/check.js @@ -3,6 +3,12 @@ Htk.ColumnCheck = new Class Extends: Htk.Column ,Tag: 'htk-column-check' + ,initialize: function (props) + { + this._cssClass = 'cell-check'; + this.parent (props); + } + ,render: function (tr) { var checkButton = document.createElement ('input'); @@ -16,7 +22,6 @@ Htk.ColumnCheck = new Class checkButton.disabled = true; var td = this.parent (tr); - td.style.textAlign = 'center'; td.appendChild (checkButton); return td; } diff --git a/web/js/htk/column/date.js b/web/js/htk/column/date.js index 9f45e121..67660b3a 100755 --- a/web/js/htk/column/date.js +++ b/web/js/htk/column/date.js @@ -22,13 +22,18 @@ Htk.ColumnDate = new Class } ,_format: _('%a, %e %b %Y') + + ,initialize: function (props) + { + this._cssClass = 'cell-date'; + this.parent (props); + } ,render: function (tr) { var text = Vn.Date.strftime (this.value, this._format); var td = this.parent (tr); - td.style.textAlign = 'left'; td.appendChild (document.createTextNode (text)); return td; diff --git a/web/js/htk/column/image.js b/web/js/htk/column/image.js index 25a95d29..1742ac48 100755 --- a/web/js/htk/column/image.js +++ b/web/js/htk/column/image.js @@ -13,7 +13,7 @@ Htk.ColumnImage = new Class ,set: function (x) { this._directory = x; - this.basedir = Vn.Config['image_dir'] +'/'+ x; + this._basedir = Vn.Config['image_dir'] +'/'+ x; } ,get: function () { @@ -54,24 +54,18 @@ Htk.ColumnImage = new Class } ,_directory: null - ,basedir: null + ,_basedir: null ,initialize: function (props) { + this._cssClass = 'cell-image'; + this._fullImage = new Htk.FullImage (); this.parent (props); - this.fullImage = new Htk.FullImage (); } ,render: function (tr) { var td = this.parent (tr); - - var className = 'cell-image'; - - if (td.className) - className = td.className +' '+ className; - - td.className = className; var img = document.createElement ('img'); img.alt = '' @@ -107,7 +101,7 @@ Htk.ColumnImage = new Class { if (cell.value) { - var url = this.basedir +'/'; + var url = this._basedir +'/'; if (this.subdir) url += this.subdir +'/'; @@ -141,12 +135,12 @@ Htk.ColumnImage = new Class src += '?'+ cell.stamp; if (!cell.error) - this.fullImage.show (this.basedir +'/'+ src); + this._fullImage.show (this._basedir +'/'+ src); } ,onMouseOut: function () { - this.fullImage.hide (); + this._fullImage.hide (); } ,onDoubleClick: function (cell) diff --git a/web/js/htk/column/link.js b/web/js/htk/column/link.js index 827fe6e2..aa753eb9 100755 --- a/web/js/htk/column/link.js +++ b/web/js/htk/column/link.js @@ -33,7 +33,6 @@ Htk.ColumnLink = new Class link.target = this.target; var td = this.parent (tr); - td.style.textAlign = 'left'; td.appendChild (link); return td; } diff --git a/web/js/htk/column/radio.js b/web/js/htk/column/radio.js index 9f9b9306..055bd267 100755 --- a/web/js/htk/column/radio.js +++ b/web/js/htk/column/radio.js @@ -16,8 +16,9 @@ Htk.ColumnRadio = new Class ,initialize: function (props) { - this.parent (props); + this._cssClass = 'cell-radio'; this.radioGroup = new Htk.RadioGroup (); + this.parent (props); } ,render: function (tr) diff --git a/web/js/htk/column/spin.js b/web/js/htk/column/spin.js index 790d686a..c9a17207 100755 --- a/web/js/htk/column/spin.js +++ b/web/js/htk/column/spin.js @@ -20,11 +20,23 @@ Htk.ColumnSpin = new Class ,value: 0 } } + + ,initialize: function (props) + { + this._cssClass = 'cell-spin'; + this.parent (props); + } + + ,renderHeader: function () + { + var th = this.parent (); + th.className = 'cell-spin'; + return th; + } ,render: function (tr) { var td = this.parent (tr); - td.style.textAlign = 'right'; var valueString = null; @@ -35,7 +47,6 @@ Htk.ColumnSpin = new Class { var entry = document.createElement ('input'); entry.type = 'text'; - entry.className = 'cell-spin'; entry.addEventListener ('change', this.inputChanged.bind (this, tr, entry)); td.appendChild (entry); diff --git a/web/js/htk/column/text.js b/web/js/htk/column/text.js index c8a8e92c..5c69e26f 100755 --- a/web/js/htk/column/text.js +++ b/web/js/htk/column/text.js @@ -23,6 +23,12 @@ Htk.ColumnText = new Class ,_format: null + ,initialize: function (props) + { + this._cssClass = 'cell-text'; + this.parent (props); + } + ,render: function (tr) { var node; @@ -33,7 +39,6 @@ Htk.ColumnText = new Class node = document.createElement ('input'); node.type = 'text'; - node.className = 'cell-text'; node.value = value; node.addEventListener ('changed', this.inputChanged.bind (this, tr, node)); @@ -43,7 +48,6 @@ Htk.ColumnText = new Class Vn.Value.format (this.value, this._format)); var td = this.parent (tr); - td.style.textAlign = 'left'; td.appendChild (node); return td; } diff --git a/web/js/htk/grid.js b/web/js/htk/grid.js index bc3f566e..36827778 100755 --- a/web/js/htk/grid.js +++ b/web/js/htk/grid.js @@ -302,7 +302,7 @@ Htk.Grid = new Class ,addColumn: function (pos, column) { - var header = document.createElement ('th'); + var header = column.renderHeader (); if (pos == -1 || pos >= this.columns.length) { @@ -318,12 +318,6 @@ Htk.Grid = new Class header.addEventListener ('click', this.sortModel.bind (this, column)); header.title = _('Sort'); - - if (column.title) - { - var title = document.createTextNode (column.title); - header.appendChild (title); - } column.on ('changed', this.columnChanged, this); diff --git a/web/js/htk/style.css b/web/js/htk/style.css index 00a10fa6..163feba0 100755 --- a/web/js/htk/style.css +++ b/web/js/htk/style.css @@ -5,24 +5,22 @@ { margin: auto; border-collapse: collapse; - text-align: center; } .htk-grid > thead > tr, .htk-grid > tfoot > tr { background-color: #009688; vertical-align: middle; - text-align: center; height: 3em; } -.htk-grid > thead th +.htk-grid th { color: white; cursor: pointer; font-weight: normal; padding: 0 0.4em; } -.htk-grid > thead th:hover +.htk-grid th:hover { background-color: rgba(1, 1, 1, 0.2); } @@ -39,18 +37,6 @@ { background-color: transparent; } -.htk-grid .message -{ - padding: 1.5em; -} -.htk-grid .message > img, -.htk-grid .message > .htk-spinner -{ - display: inline-block; - vertical-align: middle; - padding-right: 0.8em; - height: 1.8em; -} .htk-grid > tbody tr { border-top: 1px solid #DDD; @@ -64,22 +50,58 @@ margin: 0; padding: 0 0.5em; } -.htk-grid > tbody td:first-child, -.htk-grid > thead th:first-child +.htk-grid th, +.htk-grid td +{ + text-align: left; +} +.htk-grid td:first-child, +.htk-grid th:first-child { padding-left: 1em; } -.htk-grid > tbody td:last-child, -.htk-grid > thead th:last-child +.htk-grid td:last-child, +.htk-grid th:last-child { padding-right: 1em; } -.htk-grid .cell-spin +.htk-grid .message +{ + padding: 1.5em; + text-align: center; +} +.htk-grid .message > * +{ + display: inline-block; + vertical-align: middle; + padding-right: 0.8em; +} +.htk-grid .message > img +{ + height: 1.8em; +} + +/* Grid cells */ + +th.cell-spin +{ + text-align: right; +} +td.cell-spin { width: 2.5em; text-align: right; } -.htk-grid .cell-button +th.cell-check, +th.cell-radio +{ + text-align: center; +} +td.cell-button +{ + text-align: center; +} +td.cell-button > button { margin: 0; padding: 0.5em; @@ -87,17 +109,21 @@ background-color: transparent; border-radius: 0.1em; } -.htk-grid .cell-button:hover +td.cell-button > button:hover { background-color: rgba(1, 1, 1, 0.1); } -.htk-grid .cell-button img +td.cell-button img { height: 1.5em; display: block; margin: auto; } -.htk-grid .cell-image > img +td.cell-image +{ + text-align: center; +} +td.cell-image img { max-width: 2.5em; max-height: 2.5em; diff --git a/web/locale/ca/forms/ecomerce/orders.json b/web/locale/ca/forms/ecomerce/orders.json index 1732efab..d4ed015a 100755 --- a/web/locale/ca/forms/ecomerce/orders.json +++ b/web/locale/ca/forms/ecomerce/orders.json @@ -10,8 +10,8 @@ ,"LastOrders": "Últimes comandes" - ,"PendingBalance:": "Saldo pendent:" - ,"PaymentInfo": "Per realitzar una entrega a compte fes clic al botó de la dreta i fes el pagament a l'empresa corresponent. La quantitat que apareix és el saldo pendent a dia d'avui, no té en compte comandes del futur. Pots realitzar un lliurament a compte de la quantitat que desitgis. Si vols pagar una comanda en concret pots prémer directament el botó de pagament de la comanda." + ,"Balance:": "Saldo:" + ,"PaymentInfo": "La quantitat que mostrada és el teu saldo pendent (negatiu) o favorable a dia d'avui, no té en compte comandes del futur. Perquè la teva comanda sigui enviat, aquesta quantitat ha de ser igual o més gran que 0. Si vols fer un lliurament a compte, esborra la quantitat suggerida i introdueix la quantitat que vulguis." ,"MakePayment": "Realitzar pagament" ,"Company": "Empresa" ,"Pending": "Pendent" diff --git a/web/locale/en/forms/ecomerce/orders.json b/web/locale/en/forms/ecomerce/orders.json index 42d609a5..35edbefa 100755 --- a/web/locale/en/forms/ecomerce/orders.json +++ b/web/locale/en/forms/ecomerce/orders.json @@ -10,8 +10,8 @@ ,"LastOrders": "Last orders" - ,"PendingBalance:": "Pending balance:" - ,"PaymentInfo": "To make a down payment click the right button and make the payment on the relevant company. The amount shown is the outstanding balance today, it does not take into account future orders. You can make a down payment on the amount you want." + ,"Balance:": "Balance:" + ,"PaymentInfo": "The amount shown is your slope (negative) or favorable balance today, it disregards future orders. For get your order shipped, this amount must be equal to or greater than 0. If you want to make a down payment, delete the suggested amount and enter the amount you want." ,"MakePayment": "Make payment" ,"Company": "Company" ,"Pending": "Pending" diff --git a/web/locale/es/forms/ecomerce/orders.json b/web/locale/es/forms/ecomerce/orders.json index cf543ce0..100fc70c 100755 --- a/web/locale/es/forms/ecomerce/orders.json +++ b/web/locale/es/forms/ecomerce/orders.json @@ -10,8 +10,8 @@ ,"LastOrders": "Últimos pedidos" - ,"PendingBalance:": "Saldo pendiente:" - ,"PaymentInfo": "Para realizar una entrega a cuenta pulsa en el botón de la derecha y haz el pago en la empresa correspondiente. La cantidad que aparece es el saldo pendiente a día de hoy, no tiene en cuenta pedidos del futuro. Puedes realizar una entrega a cuenta de la cantidad que desees." + ,"Balance:": "Saldo:" + ,"PaymentInfo": "La cantidad que mostrada es tu saldo pendiente (negativa) o favorable a día de hoy, no tiene en cuenta pedidos del futuro. Para que tu pedido sea enviado, esta cantidad debe ser igual o mayor que 0. Si quieres realizar una entrega a cuenta, borra la cantidad sugerida e introduce la cantidad que desees." ,"MakePayment": "Realizar pago" ,"Company": "Empresa" ,"Pending": "Pendiente" diff --git a/web/locale/fr/forms/ecomerce/orders.json b/web/locale/fr/forms/ecomerce/orders.json index bcac297a..730fe83f 100755 --- a/web/locale/fr/forms/ecomerce/orders.json +++ b/web/locale/fr/forms/ecomerce/orders.json @@ -10,8 +10,8 @@ ,"LastOrders": "Les dernières commandes" - ,"PendingBalance:": "Balance:" - ,"PaymentInfo": "Pour effectuer un paiement vers le bas, cliquez sur le bouton à droite et effectuer le paiement par la société. Le montant indiqué est le solde aujourd'hui, ne prend pas en compte les commandes futures. Vous pouvez faire un acompte sur le montant que vous voulez. Si vous voulez payer un ordre spécifique, vous pouvez cliquer directement sur le bouton de paiement Ordre." + ,"Balance:": "Balance:" + ,"PaymentInfo": "Le montant indiqué est votre pente (négative) ou balance favorable aujourd'hui, ne tient pas compte pour les commandes futures. Obtenir votre commande est expédiée, ce montant doit être égal ou supérieur à 0. Si vous voulez faire un versement, le montant suggéré effacé et entrez le montant que vous souhaitez." ,"MakePayment": "Effectuer un paiement" ,"Company": "Entreprise" ,"Pending": "Pente" diff --git a/web/locale/mn/forms/ecomerce/orders.json b/web/locale/mn/forms/ecomerce/orders.json index 42d609a5..ceb7d1a4 100755 --- a/web/locale/mn/forms/ecomerce/orders.json +++ b/web/locale/mn/forms/ecomerce/orders.json @@ -10,8 +10,8 @@ ,"LastOrders": "Last orders" - ,"PendingBalance:": "Pending balance:" - ,"PaymentInfo": "To make a down payment click the right button and make the payment on the relevant company. The amount shown is the outstanding balance today, it does not take into account future orders. You can make a down payment on the amount you want." + ,"Balance:": "Balance:" + ,"PaymentInfo": "Үзүүлсэн хэмжээ цаашид захиалга эзэлж биш, таны налуу (сөрөг), эсвэл тааламжтай тэнцвэр нь өнөөдөр юм. Хэрэв та дүн арилгаж гэж хэлж байсан нь доош нь төлбөр хийж, өөрийн хүссэн хэмжээгээр орж хүсэж байгаа бол таны захиалга ирдэг бол авах, энэ хэмжээ тэнцүү буюу 0-ээс их байх ёстой." ,"MakePayment": "Make payment" ,"Company": "Company" ,"Pending": "Pending" diff --git a/web/locale/pt/forms/account/address-list.json b/web/locale/pt/forms/account/address-list.json new file mode 100644 index 00000000..a9afe09e --- /dev/null +++ b/web/locale/pt/forms/account/address-list.json @@ -0,0 +1,11 @@ +{ + "Addresses": "Endereços + + ,"Return": "Voltar" + ,"AddAddress": "Adicionar Endereço" + + ,"SetAsDefault": "Selecionar como pre-determinado" + ,"RemoveAddress": "Eliminar Endereço" + ,"EditAddress": "Modificar Endereço" + ,"AreYouSureDeleteAddress": "Tens certeza que queres eliminar este endereço?" +} diff --git a/web/locale/pt/forms/account/address.json b/web/locale/pt/forms/account/address.json new file mode 100644 index 00000000..21246fc6 --- /dev/null +++ b/web/locale/pt/forms/account/address.json @@ -0,0 +1,15 @@ +{ + "AddEditAddress": "Adicionar ou modificar endereço" + + ,"Name": "Consignatario" + ,"Address": "Endereço" + ,"City": "Municipio" + ,"ZipCode": "Código postal" + ,"Country": "País" + ,"Province": "Distrito" + + ,"Return": "Voltar" + ,"Accept": "Aceitar" + + ,"AddressChangedSuccessfully": "Endereço modificado corretamente" +} diff --git a/web/locale/pt/forms/account/conf.json b/web/locale/pt/forms/account/conf.json new file mode 100644 index 00000000..73a6ecef --- /dev/null +++ b/web/locale/pt/forms/account/conf.json @@ -0,0 +1,19 @@ +{ + "Configuration": "Configuração" + + ,"UserNumber": "Nº usuario" + ,"UserName": "Nome de usuario" + ,"Password": "Palavra-Passe" + ,"Email": "E-Mail" + ,"Billing": "Facturação" + ,"ReceiveInvoicesByEmail": "Receber facturas por e-mail" + + ,"NewPassword": "Nova Palavra-Passe" + ,"RepeatPassword": "Repetir Palavra-Passe" + + ,"MustReloginIfChange": "Para modificar seu nome de usario deves voltar a inicar sessão" + ,"PasswordsChanged": "Palavra-Passe Modificada!" + ,"PasswordsDoesntMatch": "As Palavras-Passe não coincidem!" + + ,"Addresses": "Endereços" +} diff --git a/web/locale/pt/forms/admin/access-log.json b/web/locale/pt/forms/admin/access-log.json new file mode 100644 index 00000000..0cc3ee47 --- /dev/null +++ b/web/locale/pt/forms/admin/access-log.json @@ -0,0 +1,15 @@ +{ + "AccessLog": "Registro de acessos" + + ,"UserNumber:": "Nº usuario:" + ,"User:": "Usuario:" + ,"Phone:": "Telefone:" + ,"Mobile:": "Telemóvel:" + + ,"Access": "Acceso" + ,"OS": "OS" + ,"Browser": "Navegador" + ,"Version": "Versão" + ,"Javascript": "Javascript" + ,"Cookies": "Cookies" +} diff --git a/web/locale/pt/forms/admin/items.json b/web/locale/pt/forms/admin/items.json new file mode 100644 index 00000000..8bf6f7f2 --- /dev/null +++ b/web/locale/pt/forms/admin/items.json @@ -0,0 +1,9 @@ +{ + "Item list": "Lista de Ítens" + + ,"Store": "Armazém" + ,"Realm": "Reino" + ,"Rate": "Tarifa" + + ,"Preview": "Mostrar" +} diff --git a/web/locale/pt/forms/admin/links.json b/web/locale/pt/forms/admin/links.json new file mode 100644 index 00000000..a72be2e0 --- /dev/null +++ b/web/locale/pt/forms/admin/links.json @@ -0,0 +1,6 @@ +{ + "ControlPanel": "Painel de controle" + + ,"Module": "Módulo" + ,"Description": "Descrição" +} diff --git a/web/locale/pt/forms/admin/photos.json b/web/locale/pt/forms/admin/photos.json new file mode 100644 index 00000000..8d0e1eb7 --- /dev/null +++ b/web/locale/pt/forms/admin/photos.json @@ -0,0 +1,12 @@ +{ + "Photos": "Fotos" + + ,"Schema": "Esquema" + ,"ImageName": "Nome da imagem" + ,"Id": "Id" + ,"ImageFile": "Arquivo de imagem" + + ,"Upload": "Enviar" + + ,"ImageUploaded": "Imagem subida correctamente" +} diff --git a/web/locale/pt/forms/admin/shelves.json b/web/locale/pt/forms/admin/shelves.json new file mode 100644 index 00000000..791de63d --- /dev/null +++ b/web/locale/pt/forms/admin/shelves.json @@ -0,0 +1,21 @@ +{ + "Configuration": "Configuração" + ,"Select config": "Selecione a configuração" + ,"Reign": "Reino" + ,"Family": "Familia" + ,"Store": "Armazém" + ,"Date": "Data" + ,"Shelf": "Pratilheira" + ,"Name prefix": "Prefixo do nome" + ,"Limit amount per item": "Limíte de quantidade por ítem" + ,"Title": "Título" + ,"Show packing": "Mostrar unidades por caixa" + ,"Stack different items": "Empilhar ítens diferentes" + + ,"Preview": "Mostrar" + + ,"Pallets": "Palets" + + ,"No items found, check that all fields are correct": + "Nenhum ítem encontrado, comprove que todos os campos estão corretos" +} diff --git a/web/locale/pt/forms/admin/users.json b/web/locale/pt/forms/admin/users.json new file mode 100644 index 00000000..d716ced1 --- /dev/null +++ b/web/locale/pt/forms/admin/users.json @@ -0,0 +1,12 @@ +{ + "UserManagement": "Gestão de usuarios" + + ,"UserName:": "Nome de usuario:" + + ,"UserNumber": "Nº usuario" + ,"UserName": "Nome de usuario" + ,"Alias": "Alias" + + ,"AccessAsUser": "Suplantar usuario" + ,"AccessLog": "Registro de acessos" +} diff --git a/web/locale/pt/forms/admin/visits.json b/web/locale/pt/forms/admin/visits.json new file mode 100644 index 00000000..519e2919 --- /dev/null +++ b/web/locale/pt/forms/admin/visits.json @@ -0,0 +1,31 @@ +{ + "Visits": "Visitas" + ,"VisitsManagement": "Gestão de visitas" + + ,"ActiveSessions": "Usuarios conectados" + ,"VisitsQuery": "Consulta de visitas" + ,"Refresh": "Actualizar" + + ,"ActiveSessions:": "Usuarios conectados:" + ,"NewVisitsTotal:": "Novas visitas:" + + ,"SessionNumber": "Nº sessão" + ,"User": "Usuario" + ,"Login": "Hora de acceso" + ,"LastActivity": "Última atividade" + ,"SO": "Sistema Operativo" + ,"Version": "Versão" + ,"NewVisit": "Nova visita" + + ,"SelectDateInterval": "Selecciona un intérvalo de datas" + ,"FromDate:": "Desde o día:" + ,"ToDate:": "Até o día:" + ,"VisitsTotal:": "Total visitas:" + + ,"Browser": "Navegador" + ,"MinVersion": "Versão mínima" + ,"MaxVersion": "Versão máxima" + ,"LastVisit": "Última visita" + ,"NewVisits": "Novas visitas" + ,"%a, %e %b %Y at %T": "%a, %e %b %Y a las %T" +} diff --git a/web/locale/pt/forms/agencies/packages.json b/web/locale/pt/forms/agencies/packages.json new file mode 100644 index 00000000..9cc4da5c --- /dev/null +++ b/web/locale/pt/forms/agencies/packages.json @@ -0,0 +1,9 @@ +{ + "ListByAgency": "Bultos por agencia" + + ,"ShowByProvince": "Mostrar desglosse por Distrito" + ,"Agency": "Agencia" + ,"Exps": "Exps." + ,"Bundles": "Bultos" + ,"Prevision": "Prev." +} diff --git a/web/locale/pt/forms/agencies/provinces.json b/web/locale/pt/forms/agencies/provinces.json new file mode 100644 index 00000000..7518cbed --- /dev/null +++ b/web/locale/pt/forms/agencies/provinces.json @@ -0,0 +1,10 @@ +{ + "ByProvince": "Desglosse por Distritos" + + ,"Return": "Voltar" + + ,"SelectAgency": "Seleccione uma agência" + ,"Province": "Distrito" + ,"Expeditions": "Exps." + ,"Left": "Faltam" +} diff --git a/web/locale/pt/forms/cms/about.json b/web/locale/pt/forms/cms/about.json new file mode 100644 index 00000000..3368992c --- /dev/null +++ b/web/locale/pt/forms/cms/about.json @@ -0,0 +1,47 @@ +{ + "QualityAndVariety": "Qualidade, variedade e serviço" + + ,"MaximumFreshness": "Verdnatura lhe ofrece um produto com a máxima frescura garantida, graças a suas recepções diárias de flor e planta procedentes de Holanda, América do Sul, ou desde o mesmo produtor." + ,"SquareMeters": "Mais de 13.000m de instalações" + ,"AboutRealms": "Com flor cortada, verdes, artificial e complementos" + ,"AboutLocation": "Asentados em Valencia, Madrid, Barcelona, Holanda e França, oferecemos venta direta em nossas instalações e Entregamos a toda Espanha mediante serviço proprio ou agência." + ,"PurchaseThroughWeb": "Compra a través de nossa web e receba o pedido cômodamente em sua florista." + + ,"WhatMakeUsDifferent": "O Que nos faz diferentes?" + + ,"DesignVariety": "A variedade no desenho, a qualidade dos materiais utilizados e nosso serviço de entrega, te garantizam uma amostra de produto dinámico, sempre fresco e atrativo." + ,"AdaptToYourNeeds": "Verdnatura se adapta às necessidades de cada cliente oferecendo-te um amplo leque de produtos, garantido sempre." + ,"TheBestQuality": "A melhor qualidade ao melhor preço. Sen esquecer nunca do desenho." + + ,"AtYourService": "Estamos a seu serviço" + + ,"BuyersAndTraders": "9 compradores especializados e nossos 20 comerciais te asessorarão em tudo o que necessites." + + ,"Training": "Verdnatura formação" + + ,"GoodTraining": "Em Verdnatura sabemos que uma boa formação é imprescindível para o desenvolvimento ótimo de qualqer atividade, e como não, também a de florista." + ,"SpecialTrainingPrices": "Para que o orçamento de uma escola não repercuta na qualidade da sua formação, colaboramos com uma política de preços especiais para todas aquelas escolas que solicitem realizar cursos em nossas instalações de Verdnatura Silla." + ,"YoutubeChannel": "E não perdas os vídeos do Canal Verdnatura em Youtube. Onde vas a encontrar um montão de conselhos muito interessantes sobre o manuseio da flor." + + ,"HowWeWork": "Como Trabalhamos?" + + ,"FirstQualityControl": "1º controle de qualidade" + ,"SecondQualityControl": "2º controle de qualidade" + ,"ThirdQualityControl": "3º controle de qualidade" + ,"FourthQualityControl": "4º controle de qualidade" + + ,"AalsmeerAuction": "Às 5:00h, nossos responsáveis de compras adquirem, no leilão de Aalsmeer e Noaldwijk, o material que o produtor colheu no dia día anterior." + ,"BeforeAuction": "Após sua compra, este material entra rápidamente em Verdnatura Holland BV, nossa empresa de Flora Holland, em Aalsmeer." + ,"DirectlyFromProviders": "Além de comprar a través do leilão Holandes, também compramos diretamente a produtores de Colombia, Equador, Thailandia, Malasia, África e Australia. Estes productos são supervisados diretamente por nossos delegados de compra ubicados em cada zona. Esta mercadoria viajará a Amsterdam, submetida a um proceso de Vaacum e em menos de duas horas desde sua aterrizagem, estará em nossas instalações de Aalsmeer." + ,"GoodsDischarge": "Às 7:00h nossos companheiros de Aalsmeer começam a receber a mercadoria comprada, passando um primeiro controle de qualidade, e registrando-a em nosso estoque. Já está disponivel para nossos clientes em nossa pagina online." + ,"GoodsTravel": "A mercadoria viaja durante um día e meio em camiões com compartimentos herméticos com temperaturas diferentes, de maneira que não se interrompa a cadeia de frío e viaje nas melhores condições." + ,"GoodsReception": "Na recepção da mercadoria o responsável da compra revisa o estado em que chega, aceitándo-la ou recuzando-a segundo o caso, se descarrega em frío e rápidamente entra em nossa câmara." + ,"CustomerOrders": "Nossos clientes podem fazer seus pedidos a través da pagina web, por telefone ou vindo diretamente a nossas instalações. Temos uma equipa de comerciais especializados que lhe vai a asesorar em sua compra e lhe informará das novidades e ítens que possam ser de seu interesse, de forma que sua compra se ajuste às suas necessidades, e fique totalmente satisfeito." + ,"AfterOrder": "Uma vez realizado o pedido, passa ao departamento de produção. Durante a preparação deste, se realiza um novo controle de qualidade (o terceiro), no qual se eliminará a mercadoria deficiente." + ,"BuyerControl": "Quando se finaliza a preparação, se realiza um novo controle (o quarto) onde um especialista conta e revisa o estado dos produtos. Em caso de que estes não cumpram com o estandard de qualidade exigidos os recusa e os substitue pelos adequados." + ,"EmbeddedSection": "Seguidamente se leva à sessão de encaixado, onde o pedido é acondicionado para sua correta entrega. Cada tipo de entrega requer un método de encaixado adequado para que o produto viaje protegido e chegue ao cliente em perfeitas condições." + ,"AfterEmbedAgency": "Quando producto já foi encaixado se armazena de novo na câmara até sua saída por agência ou pelo nosso transporte proprio, recibiéndolo el cliente, em 24h no caso de agência ou no mesmo dia no caso de nosso transporte, cômodamente em sua morada." + ,"FreshnessGuaranteed": "Esta forma de trabalho garante a maior frescura pela rapidez dos processos e pela manutenção da cadeia de frio desde a compra até sua recepção por nosso cliente." + + ,"AboutSummary": "75 pessoas divididas por quase todo o mundo para que nosso cliente tenha o mais amplo catálogo do sector, a flor mais fresca, a planta mais novedosa, os complementos mais actuais e o serviço mais rápido possível." +} diff --git a/web/locale/pt/forms/cms/contact.json b/web/locale/pt/forms/cms/contact.json new file mode 100644 index 00000000..c6addc5a --- /dev/null +++ b/web/locale/pt/forms/cms/contact.json @@ -0,0 +1,20 @@ +{ + "IWantCustomer": "Quero ser cliente!" + + ,"FillFormData": "Preencha o formulário com seus dados e em breve nos colocaremos em contacto contigo." + ,"OrCallUs": "Ou se preferes ligue-nos ao +34 963 242 100." + ,"AllFieldsMandatory": "* Todos os campos são obrigatorios." + + ,"Name": "Nome" + ,"Surname": "Apelidos" + ,"EMail": "E-Mail" + ,"Message": "Menssagem" + ,"Address": "Endereço" + ,"PC": "Código postal" + ,"City": "Município" + ,"Phone": "Telefone" + ,"Send": "Enviar dados" + + ,"DataSentSuccess": "Seus dados foram enviados corretamente.Em breve nos colocaremos em contacto contigo." + ,"ErrorSendingData": "Erro ao enviar os dados. Por favor, comprove que há preenchido todos os campos e que há introduzido o código anti-spam corretamente." +} diff --git a/web/locale/pt/forms/cms/home.json b/web/locale/pt/forms/cms/home.json new file mode 100644 index 00000000..8849ee17 --- /dev/null +++ b/web/locale/pt/forms/cms/home.json @@ -0,0 +1,13 @@ +{ + "Sent": "Enviado" + ,"Author": "Autor" + ,"votes": "votos" + ,"NoAnswerSelected": "Não seleccionou nenhuma resposta" + ,"ThanksForVote": "Obrigado por seu voto!" + ,"Vote": "Votar" + ,"Total": "Total" + ,"BrownserRecommend": + "Verdnatura recomenda utilizar o navegador web Mozilla Firefox para obter toda a funcionalidade de nossa página web." + ,"PressHere": "Pulse aquí para baixar Firefox" +} + diff --git a/web/locale/pt/forms/cms/location.json b/web/locale/pt/forms/cms/location.json new file mode 100644 index 00000000..2cf84827 --- /dev/null +++ b/web/locale/pt/forms/cms/location.json @@ -0,0 +1,3 @@ +{ + "ShowMap": "Mostrar mapa" +} diff --git a/web/locale/pt/forms/cms/training.json b/web/locale/pt/forms/cms/training.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/web/locale/pt/forms/cms/training.json @@ -0,0 +1 @@ +{} diff --git a/web/locale/pt/forms/cms/why.json b/web/locale/pt/forms/cms/why.json new file mode 100644 index 00000000..6e186006 --- /dev/null +++ b/web/locale/pt/forms/cms/why.json @@ -0,0 +1,25 @@ +{ + "AboutCompany": "Por quê Verdnatura?" + ,"StorePhoto": "Foto armazém" + + ,"BecauseOurBigCatalog": "Porque temos o maior catálogo do sector, renovado diariamente." + ,"BecauseThisWeb": "Por este site, com estoque em tempo real sempre à sua disposição." + ,"BecauseOurShoppingDep": "Por nosso departamento de compras com 9 compradores especializados." + ,"BecauseOrderIsEasy": "Porque é muito fácil fazer pedidos por internet, aplicativo ou telefone." + ,"BecauseOurPlant": "Por nossas instalações, venha e visite-nos. Vas a adorar." + ,"BecauseOurSalesDep": "Por nosso departamento comercial, com profissionais que sempre encontrarão uma solução para suas necessidades." + ,"BecauseOurWorkShop": "Porque temos uma oficina de confecção para ajudar-te." + ,"BecauseWeHaveWhatYouNeed": "Porque temos o que necessitas quando necessitas." + + ,"AboutDesc": + "Somos uma empresa dedicada à venta grossista e distribuição de uma ampla gama de complementos, verdes e flores naturaise a floristas ou outros grossistas." + + ,"AboutService": + "Contamos com serviço de entrega a domicilio com nossos veículos por toda a provincia de Valencia e áreas limitadas de Castellón, Alicante, Murcia, Albacete e Madrid enviamos ao resto da península mediante agencias de transporte com serviço 24/48 horas (MRW, Zeleris, Viaexpress). Também realizamos venta directa a floristas em qualquer de nossas instalações." + + ,"AboutDisp": + "Nossa empresa tem mais de 50 trabalhadores e varias sucursais. A principal se encontra situada em Valencia e conta com mais de 8.000m2." + + ,"AboutOrder": + "Podes realizar seus pedidos e reservas por telefone ligando ao +34 96 324 21 00, por Internet a través de nossa página web, por nosso aplicativo para Android, ou diretamente em nossas instalações." +} diff --git a/web/locale/pt/forms/ecomerce/basket.json b/web/locale/pt/forms/ecomerce/basket.json new file mode 100644 index 00000000..1933e5f8 --- /dev/null +++ b/web/locale/pt/forms/ecomerce/basket.json @@ -0,0 +1,29 @@ +{ + "ShoppingBasket": "Cesta da compra" + + ,"Delete": "Eliminar pedido" + ,"GoToCatalog": "Ir ao catálogo" + ,"ConfigureOrder": "Configurar pedido" + ,"Checkout": "Finalizar pedido" + + ,"OrderNumber": "Nº pedido" + ,"DateExit": "Data de saída" + ,"Warehouse": "Armazém" + ,"OrderTotal": "Total" + + ,"Amount": "Quantidade" + ,"Pack": "Pack" + ,"Stems": "Talos" + ,"Avail": "Disp" + ,"Item": "Item" + ,"Cat": "Cat" + ,"S1": "Med" + ,"Color": "Cor" + ,"Origin": "Origem" + ,"Price": "Preço" + ,"Disc": "Desc" + ,"Subtotal": "Sub-total" + + ,"OrderItemsUpdated": "Seu pedido leva muito tiempo aberto foi atualizado, os preços ou quantidades de seus ítens podem haver modificado" + ,"RememberReconfiguringImpact": "Lembre-se que si voltas a configurar o pedido os preços ou quantidades de ítens poderíam modificar" +} diff --git a/web/locale/pt/forms/ecomerce/catalog.json b/web/locale/pt/forms/ecomerce/catalog.json new file mode 100644 index 00000000..3a26c213 --- /dev/null +++ b/web/locale/pt/forms/ecomerce/catalog.json @@ -0,0 +1,49 @@ +{ + "Catalog": "Catálogo" + ,"SearchResults": "Resultados de busca" + + ,"SelectFamily": "Seleccione uma família" + ,"Select filter from right menu": "Seleccione um filtro no menú da direita" + ,"ArticleNotFound": "Ítem não encontrado" + ,"ArticleNotAvailable": "Ítem não disponível" + + ,"Switch view": "Modificar vista" + ,"StartOrder": "Iniciar pedido" + ,"ShoppingBasket": "Cesta da compra" + + ,"Search": "Buscar" + ,"Order by": "Organizar" + ,"Available": "Disponível" + ,"Size": "Medida" + ,"Realm": "Reino" + ,"Family": "Família" + ,"Color": "Cor" + ,"Producer": "Produtor" + ,"Origin": "Orígem" + ,"Category": "Categoria" + ,"Remove filters": "Eliminar filtros" + + ,"Amount": "Qtde" + ,"Aval": "Disp" + ,"Name": "Nome" + ,"S1": "Med" + ,"S2": "S2" + ,"Stems": "Talos" + ,"Cat": "Cat" + ,"Pack": "Pack" + ,"Origin": "Orígem" + ,"Price": "Preço" + ,"%.0d Units": "%.0d Unidades " + + ,"from": "desde" + ,"from %.2d€": "desde %.2d€" + ,"AddToBasket": "Adicionar à Cesta" + ,"Add": "Adicionar" + ,"Erase": "Eliminar" + ,"Confirm": "Confirmar" + + ,"IndicativePhotos": "* As Fotos São Orientativas" + + ,"Added%dOf%s": "Adicionados %d de %s" + ,"NoMoreAmountAvailable": "Não há mais quantidade disponível" +} diff --git a/web/locale/pt/forms/ecomerce/checkout.json b/web/locale/pt/forms/ecomerce/checkout.json new file mode 100644 index 00000000..12997f03 --- /dev/null +++ b/web/locale/pt/forms/ecomerce/checkout.json @@ -0,0 +1,31 @@ +{ + "ConfigureOrder": "Configurar pedido" + + ,"Cancel": "Cancelar" + ,"Next": "Seguir" + + ,"DeliveryOrPickupQuestion": "Queres receber ou recolher o pedido?" + ,"ReceiveThroughtAgency": "Receber por agência" + ,"ReceiveThroughtRoute": "Transporte Verdnatura" + ,"PickupInStore": "Recolher no armazém" + + ,"OrderDateDeliveryQuestion": "Que dia queres receber o pedido?" + ,"OrderDatePickupQuestion": "Que dia queres recolher o pedido?" + ,"AddressQuestion": "Onde queres receber o pedido?" + ,"AgencyQuestion": "Por que agência queres receber o pedido?" + ,"PickupWarehouseQuestion": "Em que armazém queres recolher o pedido?" + + ,"ConfirmToAccessCatalog": "Confirme os dados para entrar no catálogo" + ,"Arrival": "Chegada" + ,"Pickup": "Recolhida" + ,"%A, %e of %B": "%A, %e de %B" + ,"Agency": "Agência" + ,"Warehouse": "Armazém" + ,"Confirm": "Confirmar" + + ,"OrderStarted": "Pedido iniciado" + ,"OrderUpdated": "Pedido atualizado" + + ,"NoAgeciesAvailableForDate": "Não há agências disponíveis para a data e o consignatario seleccionado, modifique a data de envío do pedido" + ,"NoWarehousesAvailableForDate": "Não há armazéns disponíveis pa a data seleccionada, modifique a data de recolhida do pedido" +} diff --git a/web/locale/pt/forms/ecomerce/confirm.json b/web/locale/pt/forms/ecomerce/confirm.json new file mode 100644 index 00000000..d06a0230 --- /dev/null +++ b/web/locale/pt/forms/ecomerce/confirm.json @@ -0,0 +1,25 @@ +{ + "Checkout": "Finalizar pedido" + + ,"OrderSummary": "Resumo do pedido" + ,"Arrival": "Chegada" + ,"%A, %e of %B": "%A, %e de %B" + ,"Agency": "Agência" + ,"Warehouse": "Armazém" + + ,"DeliveryAddress": "Endereço de envío" + + ,"Import": "Importe" + ,"TaxBase": "Base tributável" + ,"VAT": "IVA" + ,"Total": "Total" + + ,"Cancel": "Cancelar" + ,"Modify": "Modificar" + ,"Confirm": "Confirmar" + + ,"OrderPlacedSuccessfully": "Seu pedido foi realizado com êxito" + ,"OrderReserved": "Seu pedido foi reservado mas parece que houve um problema com o pagamento. Contacte com seu comercial." + ,"Accept": "Aceitar" + ,"PayNow": "Pagar agora" +} diff --git a/web/locale/pt/forms/ecomerce/invoices.json b/web/locale/pt/forms/ecomerce/invoices.json new file mode 100644 index 00000000..1d17d79b --- /dev/null +++ b/web/locale/pt/forms/ecomerce/invoices.json @@ -0,0 +1,8 @@ +{ + "Invoices": "Factura" + + ,"Serial": "Serie" + ,"Date": "Data" + ,"Import": "Importe" + ,"Download PDF": "Descarregar PDF" +} diff --git a/web/locale/pt/forms/ecomerce/orders.json b/web/locale/pt/forms/ecomerce/orders.json new file mode 100644 index 00000000..cc645f6e --- /dev/null +++ b/web/locale/pt/forms/ecomerce/orders.json @@ -0,0 +1,36 @@ +{ + "OpenOrders": "Pedidos abertos" + + ,"StartOrder": "Iniciar pedido" + ,"ContinueOrder": "Continuar pedido" + ,"OrderNumber": "Nº pedido" + ,"DateMake": "Data de criação" + ,"DateExit": "Data de saída" + ,"SendMethod": "Forma de envío" + + ,"LastOrders": "Últimos pedidos" + + ,"Balance:": "Saldo:" + ,"PaymentInfo": "A quantidade mostrada é seu saldo pendente (negativo) ou favorável a dia de hoje, não se vincula a pedidos futuros. Para que seu pedido seja enviado, esta quantidade deve ser igual ou superior a 0. Se queres realizar um depósito à conta, apague a quantidade sugerida e introduza a quantidade que deseje." + ,"MakePayment": "Realizar pagamento" + ,"Company": "Empresa" + ,"Pending": "Pendente" + ,"Pay": "Pagar" + ,"Basket": "Cesta" + ,"ShoppingBasket": "Cesta da compra" + + ,"SeeOrder": "Mostrar detalhe do pedido" + ,"TicketNumber": "Nº ticket" + ,"SentAddress": "Endereço de envío" + ,"Consignee": "Consignatario" + ,"Boxes": "Bultos" + ,"TotalWithVAT": "Total com IVA" + ,"Pending": "Pendente" + ,"PayOrder": "Pagar pedido" + + ,"AmountToPay:": "Quantidade a pagar (€):" + ,"AmountError": "A quantidade deve ser um número positivo e inferior ou igual ao importe pendiente" + ,"PayError": "Erro ao realizar o pagamento" + + ,"%A, %e of %B": "%A, %e de %B" +} diff --git a/web/locale/pt/forms/ecomerce/ticket.json b/web/locale/pt/forms/ecomerce/ticket.json new file mode 100644 index 00000000..3d1e5a76 --- /dev/null +++ b/web/locale/pt/forms/ecomerce/ticket.json @@ -0,0 +1,30 @@ +{ + "OrderDetail": "Detalhe do pedido" + + ,"Print delivery note": "Imprimir guía de remessa" + + ,"TicketNumber:": "Nº ticket:" + ,"DateExit:": "Data de envío:" + ,"SendMethod:": "Forma de envío:" + ,"Notes:": "Notas:" + ,"TicketTotal:": "Total pedido:" + ,"(VATIncluded)": "(IVA incluído)" + + ,"PC": "Código postal" + ,"City": "Município" + ,"Province": "Distrito" + ,"Address": "Endereço" + ,"Consignee": "Consignatario" + + ,"ItemNumber": "Nº artículo" + ,"Amount": "Qtde" + ,"Item": "Ítem" + ,"Category": "Categoría" + ,"S1": "Med" + ,"Stems": "Talos" + ,"Color": "Cor" + ,"Origin": "Orígem" + ,"Price": "Preço" + ,"Disc": "Desc" + ,"Subtotal": "Sub-total" +} diff --git a/web/locale/pt/forms/news/new.json b/web/locale/pt/forms/news/new.json new file mode 100644 index 00000000..8dc040d1 --- /dev/null +++ b/web/locale/pt/forms/news/new.json @@ -0,0 +1,12 @@ +{ + "AddEditNew": "Adicionar ou editar notícia" + + ,"Title": "Título" + ,"NewBody": "Corpo" + ,"Tag": "Etiqueta" + + ,"Return": "Voltar" + ,"Accept": "Aceitar" + + ,"NewChangedSuccessfully": "Noticia modificada corretamente" +} diff --git a/web/locale/pt/forms/news/news.json b/web/locale/pt/forms/news/news.json new file mode 100644 index 00000000..4f7c611a --- /dev/null +++ b/web/locale/pt/forms/news/news.json @@ -0,0 +1,12 @@ +{ + "NewsManagement": "Gestão de noticias" + + ,"AddNew": "Adicionar noticia" + ,"EditNew": "Editar noticia" + + ,"NewNum": "Nº noticia" + ,"Date": "Data" + ,"Author": "Autor" + ,"Title": "Título" + ,"Priority": "Prioridade" +} diff --git a/web/locale/pt/js/db.js b/web/locale/pt/js/db.js new file mode 100644 index 00000000..4769fd36 --- /dev/null +++ b/web/locale/pt/js/db.js @@ -0,0 +1,8 @@ +Vn.Locale.add +({ + "ConnError": "Erro de conexão" + ,"BadServerReply": "Resposta do servidor incorreta" + ,"ModelNotUpdatable": "Este modelo não é actualizável" + ,"RowNotExists": "O Registro não existe ou foi apagado" + ,"ColNotExists": "A Coluna não existe" +}); diff --git a/web/locale/pt/js/hedera.js b/web/locale/pt/js/hedera.js new file mode 100644 index 00000000..de6c3f61 --- /dev/null +++ b/web/locale/pt/js/hedera.js @@ -0,0 +1,57 @@ +Vn.Locale.add +({ + "User": "Usuario" + ,"Password": "Palavra-Passe" + ,"Beta": "Beta" + ,"Do not sign out": "Não finalizar Sessão" + ,"I want to know more": "Quero saber mais..." + ,"Enter": "Entrar" + ,"Login mail": "clientes@verdnatura.es" + ,"Login phone": "+34 963 242 100" + + ,"You've been too idle": "Muito tempo de inatividade, a sessão foi finalizada" + ,"Invalid login": "Usuário ou Palavra-Passe incorreto. Lembre-se de diferenciar maiusculas e minusculas." + ,"There was an internal error": "Houve um erro interno" + + ,"Menu": "Menú" + ,"Exit": "Sair" + ,"Test the new website": "Prove a nova pagina web" + ,"Old website": "Web antiga" + ,"Recent changes": "Modificações recentes" + + ,"Print": "Imprimir" + ,"Please unlock popups and try again": + "Por favor, desbloqueie os pop-ups e volte a tentar" + + ,"Error loading form": "Erro ao carregar formulario" + ,"Error loading report": "Erro ao carregar o informe" + ,"By using this site you accept cookies": "Ao utilizar esta pagina web, aceitar o uso de cookies para a personalização de conteúdos e análise." + ,"New version available": "Existe uma nova atualização, a página se atualizará automaticamente para descarregar-la" + + ,"AppName": "VerdNatura" + + ,"Home": "Principio" + ,"Orders": "Pedidos" + ,"Basket": "Cesta" + ,"Last orders": "Últimos pedidos" + ,"Invoices": "Facturas" + ,"Catalog": "Catálogo" + ,"About": "Conheça-nos" + ,"About us": "Sobre a gente" + ,"Why": "Por quê?" + ,"Location": "Localização" + ,"Administration": "Administração" + ,"Control panel": "Painel de controle" + ,"Users": "Usuarios" + ,"Visits": "Visitas" + ,"News": "Noticias" + ,"Photos": "Fotos" + ,"Shelves": "Estantes" + ,"Items list": "Lista de Itens" + ,"Contact": "Quero ser cliente" + ,"Training": "Formação" + ,"Agencies": "Agências" + ,"Configuration": "Configuração" + ,"Account": "Conta" + ,"Addresses": "Endereços" +}); diff --git a/web/locale/pt/js/htk.js b/web/locale/pt/js/htk.js new file mode 100644 index 00000000..c0e2329b --- /dev/null +++ b/web/locale/pt/js/htk.js @@ -0,0 +1,31 @@ +Vn.Locale.add +({ + "True": "Sim" + ,"False": "Não" + ,"Null": "Nulo" + ,"ChangeDate": "Modificar Data" + ,"Sort": "Organizar" + ,"At": "às" + ,"Of": "de" + ,"OfThe": "de" + ,"Remove": "Eliminar" + ,"Loading": "Carregando" + ,"Loading...": "Carregando..." + ,"ReallyDelete": "Tens certeza que queres apagar esta linha?" + ,"YouMustBeLoggedIn": "Deves estar registrado como usuario" + ,"EmptyList": "Lista vazia" + ,"NoData": "Sem dados" + ,"ErrorLoadingData": "Erro" + ,"Error": "Erro" + ,"Image": "Imagem" + ,"File": "Arquivo" + ,"FileName": "Nome" + ,"UpdateImage": "Adicionar ou atualizar imagem" + ,"UploadFile": "Subir arquivo" + ,"ImageAdded": "Imagen adicionada corretamente" + ,"Close": "Fechar" + ,"Previous": "Anterior" + ,"Next": "Seguinte" + ,"Search": "Procurar" + ,"Search...": "Procurar..." +}); diff --git a/web/locale/pt/js/vn.js b/web/locale/pt/js/vn.js new file mode 100644 index 00000000..be30e2a6 --- /dev/null +++ b/web/locale/pt/js/vn.js @@ -0,0 +1,44 @@ +Vn.Locale.add +({ + "Sunday": "Domingo" + ,"Monday": "Segunda-Feira" + ,"Tuesday": "Terça-Feira" + ,"Wednesday": "Quarta-Feira" + ,"Thursday": "Quinta-Feira" + ,"Friday": "Sexta-Feira" + ,"Saturday": "Sábado" + + ,"Su": "Do" + ,"Mo": "Seg" + ,"Tu": "Ter" + ,"We": "Qua" + ,"Th": "Qui" + ,"Fr": "Sex" + ,"Sa": "Sab" + + ,"January": "Janeiro" + ,"February": "Fevereiro" + ,"March": "Março" + ,"April": "Abril" + ,"May": "Maio" + ,"June": "Junho" + ,"July": "Julho" + ,"August": "Agosto" + ,"September": "Septembro" + ,"October": "Outubro" + ,"November": "Novembro" + ,"December": "Dezembro" + + ,"Jan": "Jan" + ,"Feb": "Fev" + ,"Mar": "Mar" + ,"Apr": "Abr" + ,"May": "Mai" + ,"Jun": "Jun" + ,"Jul": "Jul" + ,"Ago": "Ago" + ,"Sep": "Set" + ,"Oct": "Out" + ,"Nov": "Nov" + ,"Dec": "Dez" +}); diff --git a/web/locale/pt/pages/tpv.json b/web/locale/pt/pages/tpv.json new file mode 100644 index 00000000..621bd916 --- /dev/null +++ b/web/locale/pt/pages/tpv.json @@ -0,0 +1,4 @@ +{ + "PaymentComplete": "Pagamento terminado, já podes voltar a nossa página web." + ,"ReturnToWeb": "Voltar a Verdnatura" +} diff --git a/web/locale/pt/pages/update-browser.json b/web/locale/pt/pages/update-browser.json new file mode 100644 index 00000000..2a3501f5 --- /dev/null +++ b/web/locale/pt/pages/update-browser.json @@ -0,0 +1,4 @@ +{ + "UpdateYourBrowser": "Atualiza seu navegador" + ,"ContinueAnyway": "Continuar de todas maneiras" +} diff --git a/web/locale/pt/pages/version-menu.json b/web/locale/pt/pages/version-menu.json new file mode 100644 index 00000000..a40e0c6b --- /dev/null +++ b/web/locale/pt/pages/version-menu.json @@ -0,0 +1,8 @@ +{ + "Welcome to Verdnatura, where are you going?": "Bem-Vindo a VerdNatura, onde queres ir?" + + ,"New website": "Nova Web" + ,"(Fantastic)": "(Fantástica)" + ,"Old website": "Antiga web" + ,"(Best choose new)": "(Melhor escolher a nova)" +} diff --git a/web/locale/pt/rest/query.json b/web/locale/pt/rest/query.json new file mode 100644 index 00000000..90823f48 --- /dev/null +++ b/web/locale/pt/rest/query.json @@ -0,0 +1,5 @@ +{ + "InvalidAction": "Ação Inválida" + + ,"EmptyQuery": "Consulta vazía" +} diff --git a/web/reports/delivery-note/style.css b/web/reports/delivery-note/style.css index 08419bfb..3c96c9af 100644 --- a/web/reports/delivery-note/style.css +++ b/web/reports/delivery-note/style.css @@ -6,40 +6,28 @@ { height: auto; } -h1 +h2 { - font-weight: normal; - font-size: 200%; - text-align: center; - margin: 0 auto; + font-size: 1.2em; margin-bottom: 8mm; + font-weight: bold; } -.htk-grid +.header { - border-collapse: collapse; - width: 100%; - margin: 0 auto; - padding: 0; + margin-bottom: 2em; } -thead > tr +.header > p { - border-bottom: 1px solid #333; - height: 10mm; + text-align: right; + margin: .1em 0; } -th +.footer { - font-weight: normal; -} -td -{ - padding-left: 2mm; -} -tbody > tr -{ - height: 18mm; -} -.cell-image > img -{ - width: 15mm; + font-size: 1.2em; + font-weight: bold; + margin-top: .2em; + border-top: 1px solid #333; + padding-top: .3em; + text-align: right; } diff --git a/web/reports/delivery-note/ui.xml b/web/reports/delivery-note/ui.xml index bde2c553..5b5ae0f8 100755 --- a/web/reports/delivery-note/ui.xml +++ b/web/reports/delivery-note/ui.xml @@ -15,59 +15,28 @@
- - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - -
- - - - - -
- - - - - - - +

+ +

+
+

+ +

+

+ +

+

+ +

+

+ + + () +

+

+ Delivery +

+
@@ -81,17 +50,18 @@ ORDER BY concept - + - - - - + - +
From c21a0dae60e594cdd00ce7fa83388da0a839b50c Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Nov 2015 17:46:24 +0100 Subject: [PATCH 22/39] Suplantacion de usuarios mejorada, estilo responsive en varios formularios que usaban tablas --- web/forms/admin/users/style.css | 27 +++++++-- web/forms/admin/users/ui.xml | 77 +++++++++++++------------ web/forms/admin/users/users.js | 17 +++--- web/forms/ecomerce/basket/basket.js | 44 ++------------- web/forms/ecomerce/basket/style.css | 32 ++++++++++- web/forms/ecomerce/basket/ui.xml | 47 ++++++++++----- web/forms/ecomerce/orders/orders.js | 6 +- web/forms/ecomerce/orders/style.css | 54 ++++++++---------- web/forms/ecomerce/orders/ui.xml | 48 ++++++++++------ web/forms/ecomerce/ticket/ui.xml | 11 +--- web/image/gnome.svg | 88 +++++++++++++++++++++++++++++ web/js/hedera/gui.css | 26 ++++++--- web/js/hedera/gui.js | 49 +++++++++++++++- web/js/hedera/gui.xml | 10 +++- web/js/htk/full-image.js | 12 ++-- web/js/htk/style.css | 23 +++++--- 16 files changed, 380 insertions(+), 191 deletions(-) create mode 100644 web/image/gnome.svg diff --git a/web/forms/admin/users/style.css b/web/forms/admin/users/style.css index d4dd41d4..25ec92c8 100755 --- a/web/forms/admin/users/style.css +++ b/web/forms/admin/users/style.css @@ -1,15 +1,34 @@ .users { padding: 1em; - min-width: 35em; } .users .box { - max-width: 50em; + max-width: 30em; margin: 0 auto; } -.users tbody tr +.users-box { - height: 3.4em; + padding: 1em; + border-bottom: 1px solid #DDD; +} +.users-box > button +{ + float: right; +} +.users-box > p +{ + margin: .2em 0; +} +.users-box > p.important +{ + font-size: 1.2em; +} + +/* Topbar */ + +.action-bar .htk-search-entry +{ + margin: .8em .6em; } diff --git a/web/forms/admin/users/ui.xml b/web/forms/admin/users/ui.xml index b74743b1..17c75a60 100755 --- a/web/forms/admin/users/ui.xml +++ b/web/forms/admin/users/ui.xml @@ -1,26 +1,20 @@ + + + +

UserManagement

+
+ +
- - - - - - - -
- - - - - -
-
- - + + + SELECT u.id, u.name, c.Cliente FROM account.user u INNER JOIN vn2008.Clientes c ON u.id = c.Id_Cliente @@ -28,25 +22,38 @@ OR c.Cliente LIKE CONCAT('%', #user, '%') OR u.id = #user ORDER BY u.name LIMIT 200 - + + + - - - - - - - - -
+ + + + +
+ + +

+ +

+

+ - + +

+
+
+ +
diff --git a/web/forms/admin/users/users.js b/web/forms/admin/users/users.js index 88c535f1..42996354 100755 --- a/web/forms/admin/users/users.js +++ b/web/forms/admin/users/users.js @@ -3,15 +3,6 @@ Vn.Users = new Class ({ Extends: Vn.Form - ,onChangeUserClick: function (column, value) - { - var batch = new Sql.Batch (); - batch.addValue ('user', value); - - var query = 'UPDATE user_session_view SET user_id = #user'; - this.conn.execQuery (query, this.userChanged.bind (this), batch); - } - ,onAccessLogClick: function (column, value) { this.hash.set ({ @@ -19,8 +10,14 @@ Vn.Users = new Class ,'user': value }); } + + ,onChangeUserClick: function (button, form) + { + this.gui.supplantUser (form.get ('id'), + this.onUserSupplant.bind (this)); + } - ,userChanged: function () + ,onUserSupplant: function (userName) { this.hash.set ({'form': 'ecomerce/orders'}); } diff --git a/web/forms/ecomerce/basket/basket.js b/web/forms/ecomerce/basket/basket.js index 7171d5f5..bf99b7e2 100755 --- a/web/forms/ecomerce/basket/basket.js +++ b/web/forms/ecomerce/basket/basket.js @@ -40,55 +40,21 @@ Vn.Basket = new Class this.hash.set ({'form': 'ecomerce/confirm'}); } - ,amountRender: function (renderer, form) + ,repeaterFunc: function (res, form) { - var amount = form.get ('amount'); - var grouping = form.get ('grouping'); - - if (amount && grouping) - renderer.value = amount / grouping; - else - renderer.value = null; + res.$('subtotal').value = this.subtotal (form); } - ,onAmountChange: function (renderer, row, newValue) + ,onDeleteClick: function (button, form) { - var model = this.$('items'); - model.set (row, 'amount', newValue * model.get (row, 'grouping')); - } - - ,featuresRender: function (renderer, form) - { - renderer.value = form.get ('Medida') +' '+ form.get ('Categoria') +' '+ form.get ('Color'); - } - - ,stemsRender: function (renderer, form) - { - renderer.value = Vn.Value.format (form.get ('price'), '%.2d€') +' x '+ form.get ('amount'); - - if (form.get ('amount') > form.get ('available')) - renderer.td.className = 'available-exceeded'; - else - renderer.td.className = ''; - } - - ,subtotalRender: function (renderer, form) - { - renderer.value = this.subtotal (form); + if (confirm (_('ReallyDelete'))) + form.deleteRow (); } ,subtotal: function (form) { return form.get ('amount') * form.get ('price'); } - - ,availableRender: function (renderer, form) - { - if (form.get ('amount') > form.get ('avail')) - renderer.value = 'unavailable'; - else - renderer.value = 'invisible'; - } }); diff --git a/web/forms/ecomerce/basket/style.css b/web/forms/ecomerce/basket/style.css index b78411a2..f563b956 100755 --- a/web/forms/ecomerce/basket/style.css +++ b/web/forms/ecomerce/basket/style.css @@ -1,11 +1,10 @@ .basket { padding: 1em; - min-width: 25em; } .basket .box { - max-width: 45em; + max-width: 30em; margin: 0 auto; } .basket .form @@ -37,3 +36,32 @@ border-radius: 50%; } +/* Lines */ + +.basket-line +{ + padding: 1em; + border-bottom: 1px solid #DDD; +} +.basket-line > .delete +{ + margin-top: .3em; + margin-right: .5em; + float: left; +} +.basket-line > .photo +{ + margin-right: 1em; + float: left; + border-radius: 50%; +} +.basket-line > p +{ + margin: .1em 0; + margin-left: 7.5em; +} +.basket-line .subtotal +{ + float: right; +} + diff --git a/web/forms/ecomerce/basket/ui.xml b/web/forms/ecomerce/basket/ui.xml index 5f0e4c26..d1fa0d76 100755 --- a/web/forms/ecomerce/basket/ui.xml +++ b/web/forms/ecomerce/basket/ui.xml @@ -22,7 +22,7 @@
- + SELECT i.id, i.amount, i.price, a.Article, a.Categoria, @@ -32,18 +32,39 @@ LEFT JOIN vn2008.Origen o ON a.id_origen = o.id - - - - - - + +
+ + +

+ + + +

+

+ x + + + + +

+
+
+ +

OrderTotal diff --git a/web/forms/ecomerce/orders/orders.js b/web/forms/ecomerce/orders/orders.js index fc181f98..c5630a75 100755 --- a/web/forms/ecomerce/orders/orders.js +++ b/web/forms/ecomerce/orders/orders.js @@ -13,11 +13,11 @@ Vn.Orders = new Class this.hash.set ({'form': 'ecomerce/basket'}); } - ,onShowClick: function (column, ticketId) + ,onShowClick: function (button, form) { this.hash.set ({ 'form': 'ecomerce/ticket', - 'ticket': ticketId + 'ticket': form.get ('ticket_id') }); } @@ -25,7 +25,7 @@ Vn.Orders = new Class ,balanceConditionalFunc: function (field, value) { - if (value > 0) + if (value >= 0) Vn.Node.removeClass (this.$('balance'), 'negative'); else Vn.Node.addClass (this.$('balance'), 'negative'); diff --git a/web/forms/ecomerce/orders/style.css b/web/forms/ecomerce/orders/style.css index 5b4038f2..ba771a9a 100755 --- a/web/forms/ecomerce/orders/style.css +++ b/web/forms/ecomerce/orders/style.css @@ -4,38 +4,7 @@ } .orders .box { - max-width: 45em; -} -.orders .box .header, -.balance-grid > thead > tr -{ - background-color: #3F51B6; -} -.orders .htk-grid tbody tr -{ - height: 5em; -} - -/* Info box */ - -.orders .info -{ - padding: 0.4em; - background-color: #FFC; - border-radius: 0.1em; -} -.orders .info > img -{ - vertical-align: middle; - margin: 0.7em; - height: 1.5em; -} - -/* Buttons */ - -.orders td.hide -{ - display: none; + max-width: 30em; } /* Balance */ @@ -77,3 +46,24 @@ margin: auto; } +/* List */ + +.order-box +{ + padding: 1em; + border-bottom: 1px solid #DDD; +} +.order-box > p +{ + margin: .1em 0; +} +.order-box > p.important +{ + font-size: 1.2em; +} +.order-box > .show-order +{ + margin: 1.6em .5em; + float: right; +} + diff --git a/web/forms/ecomerce/orders/ui.xml b/web/forms/ecomerce/orders/ui.xml index d5c6b0f1..93ba8ca4 100755 --- a/web/forms/ecomerce/orders/ui.xml +++ b/web/forms/ecomerce/orders/ui.xml @@ -45,23 +45,37 @@

-
- - - - CALL ticket_list (); - - - - - - - -
+ + + + CALL ticket_list (); + + + +
+ +

+ +

+

+ Delivery +

+

+ +

+

+ +

+
+
+ +
diff --git a/web/forms/ecomerce/ticket/ui.xml b/web/forms/ecomerce/ticket/ui.xml index 24327ea8..11b8a6eb 100755 --- a/web/forms/ecomerce/ticket/ui.xml +++ b/web/forms/ecomerce/ticket/ui.xml @@ -64,16 +64,7 @@

- + SELECT m.item_id, amount, concept, Categoria, Medida, Tallos, Color, diff --git a/web/image/gnome.svg b/web/image/gnome.svg new file mode 100644 index 00000000..0f0c6b6a --- /dev/null +++ b/web/image/gnome.svg @@ -0,0 +1,88 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/web/js/hedera/gui.css b/web/js/hedera/gui.css index 6dcf9e1d..73c462a0 100755 --- a/web/js/hedera/gui.css +++ b/web/js/hedera/gui.css @@ -148,21 +148,33 @@ .vn-gui .menu-header { - height: 5.5em; background-color: #333; + color: white; + padding: 1em; } .vn-gui .logo { + display: block; width: 12em; - float: left; - margin: 1em; - margin-bottom: .2em; + margin-bottom: .6em; } .vn-gui .welcome { - float: left; - color: white; - margin: .5em 1em; + display: block; +} +.vn-gui .supplant +{ + margin-top: .2em; + display: none; +} +.vn-gui .supplant > span +{ + font-size: 1.1em; +} +.vn-gui .supplant > button +{ + float: right; + padding: .2em; } .vn-gui .background { diff --git a/web/js/hedera/gui.js b/web/js/hedera/gui.js index dbc0a588..f609cd02 100755 --- a/web/js/hedera/gui.js +++ b/web/js/hedera/gui.js @@ -20,7 +20,7 @@ Vn.Gui = new Class var sql = 'SELECT default_form, image_dir, image_host FROM config;' +'SELECT production_domain, test_domain FROM config;' - +'SELECT name FROM customer_view;' + +'SELECT name FROM customer_account;' +'CALL form_list ();'; this.conn.execQuery (sql, this.onMainQueryDone.bind (this)); }, @@ -481,6 +481,53 @@ Vn.Gui = new Class var report = new module.klass (module, this); report.open (batch); } + + ,supplantUser: function (userId, callback) + { + var batch = new Sql.Batch (); + batch.addValue ('user', userId); + + var query = 'UPDATE user_session_view SET user_id = #user;'+ + 'SELECT Cliente FROM vn2008.Clientes WHERE Id_cliente = #user'; + this.conn.execQuery (query, + this._onUserSupplant.bind (this, userId, callback), batch); + } + + ,_onUserSupplant: function (userId, callback, resultSet) + { + this._supplantClear (); + this._supplanted = userId; + + resultSet.fetchResult (); + var userName = resultSet.fetchValue (); + + Vn.Node.setText (this.$('supplanted'), userName); + Vn.Node.show (this.$('supplant')); + + if (callback) + callback (); + } + + ,_supplantClear: function () + { + if (this._supplanted) + { + Vn.Node.hide (this.$('supplant')); + this._supplanted = null; + } + } + + ,onSupplantExitClick: function () + { + var query = 'UPDATE user_session_view SET user_id = account.user_get_id ()' + this.conn.execQuery (query, this.supplantExit.bind (this)); + } + + ,supplantExit: function () + { + this._supplantClear (); + this._onFormChange (); + } ,_destroy: function () { diff --git a/web/js/hedera/gui.xml b/web/js/hedera/gui.xml index 630171f8..c7536824 100755 --- a/web/js/hedera/gui.xml +++ b/web/js/hedera/gui.xml @@ -2,10 +2,14 @@