General improvements #92
|
@ -7,12 +7,12 @@ Hedera is the main web page for Verdnatura.
|
||||||
Required dependencies.
|
Required dependencies.
|
||||||
|
|
||||||
- PHP >= 7.0
|
- PHP >= 7.0
|
||||||
- Node.js >= 8.0
|
- Node.js >= 18.0
|
||||||
|
|
||||||
Launch application for development.
|
Launch application for development.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npm run dev
|
$ quasar dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Launch project backend.
|
Launch project backend.
|
||||||
|
|
|
@ -12,9 +12,20 @@ module.exports = defineConfig({
|
||||||
numTestsKeptInMemory: 0,
|
numTestsKeptInMemory: 0,
|
||||||
video: false,
|
video: false,
|
||||||
screenshotOnRunFailure: false,
|
screenshotOnRunFailure: false,
|
||||||
|
reporter: 'cypress-mochawesome-reporter',
|
||||||
|
reporterOptions: {
|
||||||
|
charts: true,
|
||||||
|
reportPageTitle: 'Hedera-Web E2E Reporter',
|
||||||
|
embeddedScreenshots: true,
|
||||||
|
reportDir: 'src/test/cypress/reports',
|
||||||
|
inlineAssets: true
|
||||||
|
},
|
||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
|
require('cypress-mochawesome-reporter/plugin')(on);
|
||||||
on('after:spec', (spec, results) => {
|
on('after:spec', (spec, results) => {
|
||||||
console.log('Finished running', spec.relative);
|
console.log('Finished running', spec.relative);
|
||||||
|
console.log('❌spec:', results.stats.failures);
|
||||||
|
console.log('✅spec:', results.stats.passes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
hedera-web (22.48.2) stable; urgency=low
|
|
||||||
|
|
||||||
* Initial Release.
|
|
||||||
|
|
||||||
-- Juan Ferrer Toribio <juan@verdnatura.es> Wed, 19 Aug 2015 12:00:00 +0200
|
|
|
@ -1 +0,0 @@
|
||||||
10
|
|
|
@ -1,18 +0,0 @@
|
||||||
Source: hedera-web
|
|
||||||
Priority: optional
|
|
||||||
Maintainer: Juan Ferrer Toribio <juan@verdnatura.es>
|
|
||||||
Build-Depends: build-essential, debhelper, nodejs
|
|
||||||
Standards-Version: 3.9.3
|
|
||||||
Section: misc
|
|
||||||
Homepage: https://verdnatura.es
|
|
||||||
Vcs-Git: https://gitea.verdnatura.es/verdnatura/hedera-web
|
|
||||||
|
|
||||||
Package: hedera-web
|
|
||||||
Architecture: all
|
|
||||||
Depends: apache2 | httpd, nodejs, php-cli, php-vn-lib, php-apcu, php-imap, php-soap, libphp-phpmailer, php-gd, php-pear
|
|
||||||
Suggests: php-text-captcha, php-zip, cron
|
|
||||||
Section: misc
|
|
||||||
Priority: optional
|
|
||||||
Description: Verdnatura's web page
|
|
||||||
Web page used by Verdnatura, it includes user authetication, a simple CMS and
|
|
||||||
a webpshop.
|
|
|
@ -1,24 +0,0 @@
|
||||||
Format: http://dep.debian.net/deps/dep5
|
|
||||||
Name: hedera-web
|
|
||||||
Source: https://gitea.verdnatura.es/verdnatura/hedera-web
|
|
||||||
|
|
||||||
Files: *
|
|
||||||
Copyright: 2011-2015 Juan Ferrer Toribio <juan@verdnatura.es>
|
|
||||||
License: GPL-3.0+
|
|
||||||
|
|
||||||
License: GPL-3.0+
|
|
||||||
This package is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
.
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
.
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
.
|
|
||||||
On Debian systems, the complete text of the GNU General Public
|
|
||||||
License can be found in "/usr/share/common-licenses/GPL-3".
|
|
|
@ -1,10 +0,0 @@
|
||||||
MAILTO=webmaster
|
|
||||||
*/1 * * * * root hedera-web.php -m misc/mail
|
|
||||||
*/4 * * * * root hedera-web.php -m tpv/confirm-mail
|
|
||||||
*/2 * * * * root hedera-web.php -m edi/load
|
|
||||||
0 23 * * * root hedera-web.php -m edi/clean
|
|
||||||
0 5 * * * root hedera-web.php -m edi/update
|
|
||||||
0 5 * * * root hedera-web.php -m misc/exchange-rate
|
|
||||||
0 0 * * * root hedera-web.php -m image/sync
|
|
||||||
0 1 * * * root /usr/share/hedera-web/utils/image-clean.sh > /dev/null
|
|
||||||
0 */1 * * * root /usr/share/hedera-web/utils/update-browscap.sh > /dev/null
|
|
|
@ -1,19 +0,0 @@
|
||||||
apache.conf etc/hedera-web
|
|
||||||
config.php etc/hedera-web
|
|
||||||
php.ini etc/hedera-web
|
|
||||||
web usr/share/php/vn
|
|
||||||
doc/* usr/share/doc/hedera-web
|
|
||||||
hedera-web.php usr/share/hedera-web
|
|
||||||
forms usr/share/hedera-web
|
|
||||||
image usr/share/hedera-web
|
|
||||||
js usr/share/hedera-web
|
|
||||||
pages usr/share/hedera-web
|
|
||||||
reports usr/share/hedera-web
|
|
||||||
rest usr/share/hedera-web
|
|
||||||
utils usr/share/hedera-web
|
|
||||||
index.php usr/share/hedera-web
|
|
||||||
package.json usr/share/hedera-web
|
|
||||||
build usr/share/hedera-web
|
|
||||||
README.md usr/share/hedera-web
|
|
||||||
webpack.config.json usr/share/hedera-web
|
|
||||||
build-deps/node_modules usr/share/hedera-web
|
|
|
@ -1,3 +0,0 @@
|
||||||
usr/share/hedera-web/hedera-web.php usr/bin/hedera-web.php
|
|
||||||
etc/hedera-web/apache.conf etc/apache2/conf-available/hedera-web.conf
|
|
||||||
etc/hedera-web/php.ini etc/php/7.0/apache2/conf.d/99-hedera-web.ini
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
/usr/share/hedera-web/utils/update-browscap.sh > /dev/null
|
|
||||||
|
|
||||||
if [ -e /usr/share/apache2/apache2-maintscript-helper ]
|
|
||||||
then
|
|
||||||
. /usr/share/apache2/apache2-maintscript-helper
|
|
||||||
apache2_invoke enmod rewrite
|
|
||||||
apache2_invoke enmod headers
|
|
||||||
apache2_invoke enconf hedera-web.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
#service php7.3-fpm restart
|
|
||||||
#service cron restart
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ -e /usr/share/apache2/apache2-maintscript-helper ]
|
|
||||||
then
|
|
||||||
. /usr/share/apache2/apache2-maintscript-helper
|
|
||||||
apache2_invoke disconf hedera-web.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
#rm -rf /usr/share/hedera-web/node_modules
|
|
||||||
#service cron restart
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/usr/bin/make -f
|
|
||||||
|
|
||||||
#export DH_VERBOSE=1
|
|
||||||
|
|
||||||
%:
|
|
||||||
dh $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
npm run clean
|
|
||||||
dh_clean $@
|
|
||||||
|
|
||||||
build:
|
|
||||||
npm install --no-audit --prefer-offline
|
|
||||||
npm --omit=dev run build
|
|
||||||
|
|
||||||
mkdir -p build-deps
|
|
||||||
cp package.json package-lock.json build-deps
|
|
||||||
(cd build-deps && npm install --omit=dev --no-audit --prefer-offline)
|
|
|
@ -1 +0,0 @@
|
||||||
hedera-web: package-contains-npm-ignore-file
|
|
BIN
doc/Htk.odg
BIN
doc/Htk.odg
Binary file not shown.
|
@ -1,43 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
|
|
||||||
,activate() {
|
|
||||||
this.$.userModel.setInfo('c', 'myClient', 'hedera');
|
|
||||||
this.$.addresses.setInfo('a', 'myAddress', 'hedera');
|
|
||||||
}
|
|
||||||
|
|
||||||
,onAddAddressClick() {
|
|
||||||
this.hash.setAll({
|
|
||||||
form: 'account/address',
|
|
||||||
address: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
,onReturnClick() {
|
|
||||||
window.history.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onSetDefaultClick(event, addressId) {
|
|
||||||
if (event.defaultPrevented) return;
|
|
||||||
this.$.defaultAddress.value = addressId;
|
|
||||||
Htk.Toast.showMessage(_('DefaultAddressModified'));
|
|
||||||
}
|
|
||||||
|
|
||||||
,async onRemoveAddressClick(form) {
|
|
||||||
if (confirm(_('AreYouSureDeleteAddress'))) {
|
|
||||||
await form.set('isActive', false);
|
|
||||||
await form.refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,onEditAddressClick(address) {
|
|
||||||
this.hash.setAll({
|
|
||||||
form: 'account/address',
|
|
||||||
address
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
Addresses: Adreces
|
|
||||||
Return: Tornar
|
|
||||||
AddAddress: Afegir adreça
|
|
||||||
SetAsDefault: Establir com per defecte
|
|
||||||
RemoveAddress: Esborrar direcció
|
|
||||||
EditAddress: Modificar direcció
|
|
||||||
AreYouSureDeleteAddress: Estàs segur de que vols eliminar la direcció?
|
|
||||||
DefaultAddressModified: Adreça per defecte modificada
|
|
|
@ -1,8 +0,0 @@
|
||||||
Addresses: Addresses
|
|
||||||
Return: Return
|
|
||||||
AddAddress: Add address
|
|
||||||
SetAsDefault: Set as default
|
|
||||||
RemoveAddress: Remove address
|
|
||||||
EditAddress: Edit address
|
|
||||||
AreYouSureDeleteAddress: Are you sure you want to delete the address?
|
|
||||||
DefaultAddressModified: Default address modified
|
|
|
@ -1,8 +0,0 @@
|
||||||
Addresses: Direcciones
|
|
||||||
Return: Volver
|
|
||||||
AddAddress: Añadir dirección
|
|
||||||
SetAsDefault: Establecer como predeterminada
|
|
||||||
RemoveAddress: Borrar dirección
|
|
||||||
EditAddress: Modificar dirección
|
|
||||||
AreYouSureDeleteAddress: ¿Estás seguro de que quieres borrar la dirección?
|
|
||||||
DefaultAddressModified: Dirección por defecto modificada
|
|
|
@ -1,8 +0,0 @@
|
||||||
Addresses: Adresses
|
|
||||||
Return: Retour
|
|
||||||
AddAddress: Ajouter une adresse
|
|
||||||
SetAsDefault: Définir par défaut
|
|
||||||
RemoveAddress: Supprimer l'adresse
|
|
||||||
EditAddress: Changement d'adresse
|
|
||||||
AreYouSureDeleteAddress: Souhaitez-vous vraiment supprier l'adresse?
|
|
||||||
DefaultAddressModified: Adresse par défaut modifiée
|
|
|
@ -1,8 +0,0 @@
|
||||||
Addresses: Moradas
|
|
||||||
Return: Voltar
|
|
||||||
AddAddress: Adicionar Morada
|
|
||||||
SetAsDefault: Selecionar como pre-determinado
|
|
||||||
RemoveAddress: Eliminar Morada
|
|
||||||
EditAddress: Modificar Morada
|
|
||||||
AreYouSureDeleteAddress: Tens certeza que queres eliminar esta morada?
|
|
||||||
DefaultAddressModified: Endereço padrão modificado
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
hedera-address-list {
|
|
||||||
.htk-list .side {
|
|
||||||
padding-right: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
<vn>
|
|
||||||
<vn-group>
|
|
||||||
<db-form id="user-form">
|
|
||||||
<db-model property="model" id="user-model" updatable="true">
|
|
||||||
SELECT id, defaultAddressFk
|
|
||||||
FROM myClient c
|
|
||||||
</db-model>
|
|
||||||
</db-form>
|
|
||||||
<db-model id="addresses" updatable="true">
|
|
||||||
SELECT a.id, a.nickname, p.name province, a.postalCode,
|
|
||||||
a.city, a.street, a.isActive
|
|
||||||
FROM myAddress a
|
|
||||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
|
||||||
WHERE a.isActive
|
|
||||||
</db-model>
|
|
||||||
</vn-group>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>Addresses</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="actions">
|
|
||||||
<htk-bar-button
|
|
||||||
icon="add"
|
|
||||||
tip="_AddAddress"
|
|
||||||
on-click="this.onAddAddressClick()"/>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="hedera-address-list">
|
|
||||||
<div class="box vn-w-sm">
|
|
||||||
<htk-radio-group
|
|
||||||
id="default-address"
|
|
||||||
column="defaultAddressFk"
|
|
||||||
form="user-form"/>
|
|
||||||
<htk-repeater model="addresses" form-id="address" class="htk-list">
|
|
||||||
<custom>
|
|
||||||
<div class="item clickable" on-click="this.onSetDefaultClick($event, address.id)">
|
|
||||||
<div class="side">
|
|
||||||
<htk-radio
|
|
||||||
radio-group="default-address"
|
|
||||||
val="{{address.id}}"
|
|
||||||
tip="_SetAsDefault"
|
|
||||||
name="test"/>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<p class="important">
|
|
||||||
{{address.nickname}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{address.street}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{address.postalCode}}, {{address.city}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="actions"
|
|
||||||
on-click="$event.preventDefault()">
|
|
||||||
<htk-button
|
|
||||||
icon="delete"
|
|
||||||
tip="_RemoveAddress"
|
|
||||||
on-click="this.onRemoveAddressClick($iter)"/>
|
|
||||||
<htk-button
|
|
||||||
icon="edit"
|
|
||||||
tip="_EditAddress"
|
|
||||||
on-click="this.onEditAddressClick(address.id)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</custom>
|
|
||||||
</htk-repeater>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,20 +0,0 @@
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml'),
|
|
||||||
|
|
||||||
activate() {
|
|
||||||
this.$.model.setInfo('a', 'myAddress', 'hedera', ['id'], 'id');
|
|
||||||
this.$.model.setDefault('clientFk', 'a',
|
|
||||||
new Sql.Function({schema: 'account', name: 'myUser_getId'}));
|
|
||||||
},
|
|
||||||
|
|
||||||
onStatusChange() {
|
|
||||||
if (this.$.iter.ready && this.hash.$.address == 0)
|
|
||||||
this.$.iter.insertRow();
|
|
||||||
},
|
|
||||||
|
|
||||||
onOperationsDone() {
|
|
||||||
Htk.Toast.showMessage(_('AddressChangedSuccessfully'));
|
|
||||||
window.history.back()
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,10 +0,0 @@
|
||||||
AddEditAddress: Afegir o modificar adreça
|
|
||||||
Name: Consignatari
|
|
||||||
Address: Direcció
|
|
||||||
City: Ciutat
|
|
||||||
ZipCode: Codi postal
|
|
||||||
Country: País
|
|
||||||
Province: Província
|
|
||||||
Return: Tornar
|
|
||||||
Accept: Acceptar
|
|
||||||
AddressChangedSuccessfully: Adreça modificada correctament
|
|
|
@ -1,10 +0,0 @@
|
||||||
AddEditAddress: Add or edit address
|
|
||||||
Name: Consignee
|
|
||||||
Address: Address
|
|
||||||
City: City
|
|
||||||
ZipCode: Zip code
|
|
||||||
Country: Country
|
|
||||||
Province: Province
|
|
||||||
Return: Return
|
|
||||||
Accept: Accept
|
|
||||||
AddressChangedSuccessfully: Address changed successfully
|
|
|
@ -1,10 +0,0 @@
|
||||||
AddEditAddress: Añadir o modificar dirección
|
|
||||||
Name: Consignatario
|
|
||||||
Address: Dirección
|
|
||||||
City: Ciudad
|
|
||||||
ZipCode: Código postal
|
|
||||||
Country: País
|
|
||||||
Province: Provincia
|
|
||||||
Return: Volver
|
|
||||||
Accept: Aceptar
|
|
||||||
AddressChangedSuccessfully: Dirección modificada correctamente
|
|
|
@ -1,10 +0,0 @@
|
||||||
AddEditAddress: Ajouter ou modifier l'adresse
|
|
||||||
Name: Destinataire
|
|
||||||
Address: Numéro Rue
|
|
||||||
City: Ville
|
|
||||||
ZipCode: Code postal
|
|
||||||
Country: Pays
|
|
||||||
Province: Province
|
|
||||||
Return: Reviens
|
|
||||||
Accept: Accepter
|
|
||||||
AddressChangedSuccessfully: Adresse modifié avec succès
|
|
|
@ -1,10 +0,0 @@
|
||||||
AddEditAddress: Adicionar ou modificar morada
|
|
||||||
Name: Consignatario
|
|
||||||
Address: Morada
|
|
||||||
City: Concelho
|
|
||||||
ZipCode: Código postal
|
|
||||||
Country: País
|
|
||||||
Province: Distrito
|
|
||||||
Return: Voltar
|
|
||||||
Accept: Aceitar
|
|
||||||
AddressChangedSuccessfully: Morada modificada corretamente
|
|
|
@ -1,87 +0,0 @@
|
||||||
<vn>
|
|
||||||
<vn-group>
|
|
||||||
<vn-lot-query id="params">
|
|
||||||
<vn-spec name="address" type="Number"/>
|
|
||||||
</vn-lot-query>
|
|
||||||
<db-form id="iter" on-status-changed="this.onStatusChange()">
|
|
||||||
<db-model
|
|
||||||
id="model"
|
|
||||||
property="model"
|
|
||||||
updatable="true"
|
|
||||||
mode="ON_DEMAND"
|
|
||||||
lot="params"
|
|
||||||
on-operations-done="this.onOperationsDone()">
|
|
||||||
SELECT a.id, a.street, a.nickname, a.city,
|
|
||||||
a.postalCode, a.provinceFk, p.countryFk
|
|
||||||
FROM myAddress a
|
|
||||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
|
||||||
WHERE a.id = #address
|
|
||||||
</db-model>
|
|
||||||
</db-form>
|
|
||||||
</vn-group>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>Configuration</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="actions">
|
|
||||||
<htk-bar-button
|
|
||||||
icon="close"
|
|
||||||
tip="_Return"
|
|
||||||
on-click="window.history.back()"/>
|
|
||||||
<htk-bar-button
|
|
||||||
icon="check"
|
|
||||||
tip="_Accept"
|
|
||||||
on-click="iter.performOperations()"/>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="hedera-address">
|
|
||||||
<div class="form box vn-w-sm vn-pa-lg">
|
|
||||||
<h5 class="vn-mb-md">
|
|
||||||
<t>AddEditAddress</t>
|
|
||||||
</h5>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-entry
|
|
||||||
placeholder="_Name"
|
|
||||||
form="iter" column="nickname"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-entry
|
|
||||||
placeholder="_Address"
|
|
||||||
form="iter" column="street"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-entry
|
|
||||||
placeholder="_City"
|
|
||||||
form="iter" column="city"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-entry
|
|
||||||
placeholder="_ZipCode"
|
|
||||||
form="iter" column="postalCode"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-combo
|
|
||||||
placeholder="_Country"
|
|
||||||
form="iter" column="countryFk"
|
|
||||||
id="country"
|
|
||||||
one-way="true"
|
|
||||||
one-time="true">
|
|
||||||
<db-model property="model">
|
|
||||||
SELECT id, country FROM vn.country
|
|
||||||
ORDER BY country
|
|
||||||
</db-model>
|
|
||||||
</htk-combo>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-combo
|
|
||||||
placeholder="_Province"
|
|
||||||
column="provinceFk"
|
|
||||||
form="iter">
|
|
||||||
<db-model property="model" lot="country">
|
|
||||||
SELECT id, name FROM vn.province
|
|
||||||
WHERE countryFk = #id
|
|
||||||
ORDER BY name
|
|
||||||
</db-model>
|
|
||||||
</htk-combo>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,76 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml'),
|
|
||||||
|
|
||||||
activate() {
|
|
||||||
this.$.userModel.setInfo('c', 'myClient', 'hedera');
|
|
||||||
this.$.userModel.setInfo('u', 'myUser', 'account');
|
|
||||||
|
|
||||||
if (this.hash.$.verificationToken)
|
|
||||||
this.onPassChangeClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onPassChangeClick() {
|
|
||||||
this.$.oldPassword.value = '';
|
|
||||||
this.$.newPassword.value = '';
|
|
||||||
this.$.repeatPassword.value = '';
|
|
||||||
|
|
||||||
var verificationToken = this.hash.$.verificationToken;
|
|
||||||
this.$.oldPassword.style.display = verificationToken ? 'none' : 'block';
|
|
||||||
this.$.changePassword.show();
|
|
||||||
|
|
||||||
if (verificationToken)
|
|
||||||
this.$.newPassword.focus();
|
|
||||||
else
|
|
||||||
this.$.oldPassword.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
,async onPassModifyClick() {
|
|
||||||
var oldPassword = this.$.oldPassword.value;
|
|
||||||
var newPassword = this.$.newPassword.value;
|
|
||||||
var repeatedPassword = this.$.repeatPassword.value;
|
|
||||||
|
|
||||||
if (newPassword == '' && repeatedPassword == '')
|
|
||||||
throw new Error(_('Passwords empty'));
|
|
||||||
if (newPassword !== repeatedPassword)
|
|
||||||
throw new Error(_('Passwords doesn\'t match'));
|
|
||||||
|
|
||||||
var verificationToken = this.hash.$.verificationToken;
|
|
||||||
var params = {newPassword};
|
|
||||||
|
|
||||||
let err;
|
|
||||||
try {
|
|
||||||
if (verificationToken) {
|
|
||||||
params.verificationToken = verificationToken;
|
|
||||||
await this.conn.send('user/restore-password', params);
|
|
||||||
} else {
|
|
||||||
let userId = this.gui.user.id;
|
|
||||||
params.oldPassword = oldPassword;
|
|
||||||
await this.conn.patch(
|
|
||||||
`Accounts/${userId}/changePassword`, params);
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
err = e;
|
|
||||||
Htk.Toast.showError(err.message);
|
|
||||||
|
|
||||||
if (this.hash.$.verificationToken)
|
|
||||||
this.$.newPassword.select();
|
|
||||||
else
|
|
||||||
this.$.oldPassword.select();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$.changePassword.hide();
|
|
||||||
this.hash.unset('verificationToken');
|
|
||||||
Htk.Toast.showMessage(_('Password changed!'));
|
|
||||||
this.$.userForm.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onPassInfoClick() {
|
|
||||||
this.$.passwordInfo.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
Configuration: Configuració
|
|
||||||
Personal information: Dades personals
|
|
||||||
Username: Nom d'usuari
|
|
||||||
Password: Contrasenya
|
|
||||||
Email: Correu electrònic
|
|
||||||
Display name: Nom a mostrar
|
|
||||||
Language: Idioma
|
|
||||||
Billing: Facturació
|
|
||||||
Receive invoices by email: Rebre factures per correu electrònic
|
|
||||||
Old password: Contrasenya antiga
|
|
||||||
New password: Nova contrasenya
|
|
||||||
Repeat password: Repetir contrasenya
|
|
||||||
Requirements: Requisits
|
|
||||||
Modify: Modificar
|
|
||||||
Password requirements: Requisits de contrasenya
|
|
||||||
characters long: caràcters de longitud
|
|
||||||
alphabetic characters: caràcters alfabètics
|
|
||||||
capital letters: majúscules
|
|
||||||
digits: dígits
|
|
||||||
symbols: símbols
|
|
||||||
Password changed!: Contrasenya modificada!
|
|
||||||
Password doesn't meet the requirements: ''
|
|
||||||
Passwords doesn't match: Les contrasenyes no coincideixen!
|
|
||||||
Passwords empty: Les contrasenyes en blanc
|
|
||||||
Addresses: Adreces
|
|
||||||
Change password: Canvia la contrasenya
|
|
|
@ -1,26 +0,0 @@
|
||||||
Configuration: Configuration
|
|
||||||
Personal information: Personal information
|
|
||||||
Username: Username
|
|
||||||
Password: Password
|
|
||||||
Email: Email
|
|
||||||
Display name: Display name
|
|
||||||
Language: Language
|
|
||||||
Billing: Billing
|
|
||||||
Receive invoices by email: Receive invoices by email
|
|
||||||
Old password: Old password
|
|
||||||
New password: New password
|
|
||||||
Repeat password: Repeat password
|
|
||||||
Requirements: Requirements
|
|
||||||
Modify: Modify
|
|
||||||
Password requirements: Password requirements
|
|
||||||
characters long: characters long
|
|
||||||
alphabetic characters: alphabetic characters
|
|
||||||
capital letters: capital letters
|
|
||||||
digits: digits
|
|
||||||
symbols: 'symbols. Ej: $%&.'
|
|
||||||
Password changed!: Password changed!
|
|
||||||
Password doesn't meet the requirements: 'Password doesn''t meet the requirements, press info button for more details'
|
|
||||||
Passwords doesn't match: Passwords doesn't match
|
|
||||||
Passwords empty: Passwords empty
|
|
||||||
Addresses: Addresses
|
|
||||||
Change password: Change password
|
|
|
@ -1,28 +0,0 @@
|
||||||
Configuration: Configuración
|
|
||||||
Personal information: Datos personales
|
|
||||||
Username: Nombre de usuario
|
|
||||||
Password: Contraseña
|
|
||||||
Email: Correo electrónico
|
|
||||||
Display name: Nombre a mostrar
|
|
||||||
Language: Idioma
|
|
||||||
Billing: Facturación
|
|
||||||
Receive invoices by email: Recibir facturas por correo electrónico
|
|
||||||
Old password: Contaseña antigua
|
|
||||||
New password: Nueva contraseña
|
|
||||||
Repeat password: Repetir contraseña
|
|
||||||
Requirements: Requisitos
|
|
||||||
Modify: Modificar
|
|
||||||
Password requirements: Requisitos de constraseña
|
|
||||||
characters long: carácteres de longitud
|
|
||||||
alphabetic characters: carácteres alfabéticos
|
|
||||||
capital letters: letras mayúsculas
|
|
||||||
digits: dígitos
|
|
||||||
symbols: 'símbolos. Ej: $%&.'
|
|
||||||
Password changed!: ¡Contraseña modificada!
|
|
||||||
Password doesn't meet the requirements: >-
|
|
||||||
La nueva contraseña no reune los requisitos de seguridad necesarios, pulsa en
|
|
||||||
info para más detalle
|
|
||||||
Passwords doesn't match: ¡Las contraseñas no coinciden!
|
|
||||||
Passwords empty: Contraseña vacía
|
|
||||||
Addresses: Direcciones
|
|
||||||
Change password: Cambiar contraseña
|
|
|
@ -1,26 +0,0 @@
|
||||||
Configuration: Configuration
|
|
||||||
Personal information: Informations personnelles
|
|
||||||
Username: Utilisateur
|
|
||||||
Password: Mot de passe
|
|
||||||
Email: Courriel
|
|
||||||
Display name: Nom à afficher
|
|
||||||
Language: Langage
|
|
||||||
Billing: Facturation
|
|
||||||
Receive invoices by email: Recevoir des factures par e-mail
|
|
||||||
Old password: Ancien mot de passe
|
|
||||||
New password: Nouveau mot de passe
|
|
||||||
Repeat password: Répéter le mot de passe
|
|
||||||
Requirements: Exigences
|
|
||||||
Modify: Modifier
|
|
||||||
Password requirements: Mot de passe exigences
|
|
||||||
characters long: Longs caractères
|
|
||||||
alphabetic characters: les caractères alphabétiques
|
|
||||||
capital letters: lettres majuscules
|
|
||||||
digits: chiffres
|
|
||||||
symbols: 'symboles. Ej: $%&.'
|
|
||||||
Password changed!: Mot de passe modifié!
|
|
||||||
Password doesn't meet the requirements: ''
|
|
||||||
Passwords doesn't match: Les mots de passe ne correspondent pas!
|
|
||||||
Passwords empty: ''
|
|
||||||
Addresses: Adresses
|
|
||||||
Change password: Changer le mot de passe
|
|
|
@ -1,26 +0,0 @@
|
||||||
Configuration: Configuração
|
|
||||||
Personal information: Dados pessoais
|
|
||||||
Username: Nome de usuario
|
|
||||||
Password: Palavra-passe
|
|
||||||
Email: E-Mail
|
|
||||||
Display name: Nome para mostrar
|
|
||||||
Language: Idioma
|
|
||||||
Billing: Facturação
|
|
||||||
Receive invoices by email: Receber facturas por e-mail
|
|
||||||
Old password: Palavra-passe antiga
|
|
||||||
New password: Nova Palavra-passe
|
|
||||||
Repeat password: Repetir Palavra-passe
|
|
||||||
Requirements: Requisitos
|
|
||||||
Modify: Modificar
|
|
||||||
Password requirements: Requisitos de Palavra-passe
|
|
||||||
characters long: caracteres
|
|
||||||
alphabetic characters: caracteres alfabéticos
|
|
||||||
capital letters: letras maiúsculas
|
|
||||||
digits: dígitos
|
|
||||||
symbols: 'símbolos. Ej: $%&.'
|
|
||||||
Password changed!: Palavra-passe Modificada!
|
|
||||||
Password doesn't meet the requirements: Palavra-passe não atende aos requisitos
|
|
||||||
Passwords doesn't match: As Palavras-Passe não coincidem!
|
|
||||||
Passwords empty: Palavra-passe vazia
|
|
||||||
Addresses: Moradas
|
|
||||||
Change password: Mudar Palavra-passe
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
.pass-info ul {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
<vn>
|
|
||||||
<vn-group>
|
|
||||||
<db-form v-model="passwordForm">
|
|
||||||
<db-model property="model">
|
|
||||||
SELECT length, nAlpha, nUpper, nDigits, nPunct
|
|
||||||
FROM account.userPassword
|
|
||||||
</db-model>
|
|
||||||
</db-form>
|
|
||||||
<db-form id="user-form">
|
|
||||||
<db-model property="model" id="user-model" updatable="true">
|
|
||||||
SELECT u.id, u.name, u.email, u.nickname,
|
|
||||||
u.lang, c.isToBeMailed, c.id clientFk
|
|
||||||
FROM account.myUser u
|
|
||||||
LEFT JOIN myClient c
|
|
||||||
ON u.id = c.id
|
|
||||||
</db-model>
|
|
||||||
</db-form>
|
|
||||||
</vn-group>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>Configuration</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="actions">
|
|
||||||
<htk-bar-button
|
|
||||||
icon="place"
|
|
||||||
tip="_Addresses"
|
|
||||||
on-click="hash.setAll({form: 'account/address-list'})"/>
|
|
||||||
<htk-bar-button
|
|
||||||
icon="lock_reset"
|
|
||||||
tip="_Change password"
|
|
||||||
on-click="this.onPassChangeClick()"/>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="conf">
|
|
||||||
<div class="form box vn-w-sm vn-pa-lg">
|
|
||||||
<h5 class="vn-mb-md">
|
|
||||||
<t>Personal information</t>
|
|
||||||
</h5>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-entry
|
|
||||||
placeholder="_Username"
|
|
||||||
disabled="true"
|
|
||||||
form="user-form"
|
|
||||||
column="name"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-entry
|
|
||||||
placeholder="_Email"
|
|
||||||
form="user-form"
|
|
||||||
column="email">
|
|
||||||
</htk-entry>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-entry
|
|
||||||
placeholder="_Display name"
|
|
||||||
form="user-form"
|
|
||||||
column="nickname"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<htk-combo
|
|
||||||
placeholder="_Language"
|
|
||||||
form="user-form"
|
|
||||||
column="lang">
|
|
||||||
<db-model property="model">
|
|
||||||
<custom>
|
|
||||||
SELECT code, name FROM language WHERE isActive
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
|
||||||
</htk-combo>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>
|
|
||||||
<htk-check form="user-form" column="isToBeMailed"/>
|
|
||||||
<t>Receive invoices by email</t>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<htk-popup
|
|
||||||
id="change-password"
|
|
||||||
modal="true">
|
|
||||||
<div property="child-node" class="htk-dialog vn-w-xs vn-pa-lg">
|
|
||||||
<div class="form">
|
|
||||||
<h5 class="vn-mb-md">
|
|
||||||
<t>Change password</t>
|
|
||||||
</h5>
|
|
||||||
<input
|
|
||||||
id="old-password"
|
|
||||||
type="password"
|
|
||||||
placeholder="_Old password"/>
|
|
||||||
<input
|
|
||||||
id="new-password"
|
|
||||||
type="password"
|
|
||||||
placeholder="_New password"/>
|
|
||||||
<input
|
|
||||||
id="repeat-password"
|
|
||||||
type="password"
|
|
||||||
placeholder="_Repeat password"/>
|
|
||||||
</div>
|
|
||||||
<div class="button-bar">
|
|
||||||
<button class="thin" on-click="this.onPassModifyClick()">
|
|
||||||
<t>Modify</t>
|
|
||||||
</button>
|
|
||||||
<button class="thin" on-click="this.onPassInfoClick()">
|
|
||||||
<t>Requirements</t>
|
|
||||||
</button>
|
|
||||||
<div class="clear"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</htk-popup>
|
|
||||||
<htk-popup
|
|
||||||
id="password-info"
|
|
||||||
modal="true">
|
|
||||||
<div property="child-node" class="htk-dialog pass-info vn-w-xs vn-pa-lg">
|
|
||||||
<h5 class="vn-mb-md">
|
|
||||||
<t>Password requirements</t>
|
|
||||||
</h5>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
{{passwordForm.length}} <t>characters long</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{passwordForm.nAlpha}} <t>alphabetic characters</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{passwordForm.nUpper}} <t>capital letters</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{passwordForm.nDigits}} <t>digits</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{passwordForm.nPunct}} <t>symbols</t>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</htk-popup>
|
|
||||||
</vn>
|
|
|
@ -1,7 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
AccessLog: Registre d'accessos
|
|
||||||
'UserNumber:': 'N d''usuari:'
|
|
||||||
'User:': 'Usuari:'
|
|
||||||
'Phone:': 'Telèfon:'
|
|
||||||
'Mobile:': 'Mòbil:'
|
|
||||||
Access: Accés
|
|
||||||
OS: SO
|
|
||||||
Browser: Navegador
|
|
||||||
Version: Versió
|
|
||||||
Javascript: Javascript
|
|
||||||
Cookies: Cookies
|
|
|
@ -1,11 +0,0 @@
|
||||||
AccessLog: Access log
|
|
||||||
'UserNumber:': 'User Number:'
|
|
||||||
'User:': 'User:'
|
|
||||||
'Phone:': 'Phone:'
|
|
||||||
'Mobile:': 'Mobile:'
|
|
||||||
Access: Access
|
|
||||||
OS: OS
|
|
||||||
Browser: Browser
|
|
||||||
Version: Version
|
|
||||||
Javascript: Javascript
|
|
||||||
Cookies: Cookies
|
|
|
@ -1,11 +0,0 @@
|
||||||
AccessLog: Registro de accesos
|
|
||||||
'UserNumber:': 'Nº usuario:'
|
|
||||||
'User:': 'Usuario:'
|
|
||||||
'Phone:': 'Teléfono:'
|
|
||||||
'Mobile:': 'Móvil:'
|
|
||||||
Access: Acceso
|
|
||||||
OS: SO
|
|
||||||
Browser: Navegador
|
|
||||||
Version: Versión
|
|
||||||
Javascript: Javascript
|
|
||||||
Cookies: Cookies
|
|
|
@ -1,11 +0,0 @@
|
||||||
AccessLog: Fiche d'accès
|
|
||||||
'UserNumber:': 'Numéro utilisateur:'
|
|
||||||
'User:': 'Utilisateur:'
|
|
||||||
'Phone:': 'Téléphone:'
|
|
||||||
'Mobile:': 'Portable:'
|
|
||||||
Access: Accès
|
|
||||||
OS: OS
|
|
||||||
Browser: Navigateur
|
|
||||||
Version: Version
|
|
||||||
Javascript: Javascript
|
|
||||||
Cookies: Cookies
|
|
|
@ -1,11 +0,0 @@
|
||||||
AccessLog: Registro de acessos
|
|
||||||
'UserNumber:': 'Nº utilizador:'
|
|
||||||
'User:': 'Utilizador:'
|
|
||||||
'Phone:': 'Telefone:'
|
|
||||||
'Mobile:': 'Telemóvel:'
|
|
||||||
Access: Acceso
|
|
||||||
OS: OS
|
|
||||||
Browser: Navegador
|
|
||||||
Version: Versão
|
|
||||||
Javascript: Javascript
|
|
||||||
Cookies: Cookies
|
|
|
@ -1,12 +0,0 @@
|
||||||
|
|
||||||
.access-log .form > p {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
margin: .1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List */
|
|
||||||
|
|
||||||
.access-log .htk-list {
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
<vn>
|
|
||||||
<vn-group>
|
|
||||||
<db-form v-model="user">
|
|
||||||
<db-model property="model" lot="hash">
|
|
||||||
SELECT u.id, u.name user, u.nickname, u.email, c.phone, r.name role
|
|
||||||
FROM account.user u
|
|
||||||
JOIN account.role r ON r.id = u.role
|
|
||||||
LEFT JOIN vn.client c ON c.id = u.id
|
|
||||||
WHERE u.id = #user
|
|
||||||
</db-model>
|
|
||||||
</db-form>
|
|
||||||
</vn-group>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>AccessLog</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="access-log">
|
|
||||||
<div class="box vn-w-xs vn-pa-lg">
|
|
||||||
<div class="form">
|
|
||||||
<h4>{{user.nickname}}</h4>
|
|
||||||
<p>#{{user.id}} - {{user.user}}</p>
|
|
||||||
<p>{{user.role}}</p>
|
|
||||||
<p>{{user.email}}</p>
|
|
||||||
<p>{{user.phone}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<htk-repeater form-id="iter" class="box vn-w-xs htk-list vn-mt-md">
|
|
||||||
<db-model property="model" lot="hash">
|
|
||||||
SELECT u.stamp, a.platform, a.browser, a.version, a.javascript, a.cookies
|
|
||||||
FROM visitUser u
|
|
||||||
JOIN visitAccess c ON c.id = u.accessFk
|
|
||||||
JOIN visitAgent a ON a.id = c.agentFk
|
|
||||||
WHERE u.userFk = #user
|
|
||||||
ORDER BY u.stamp DESC
|
|
||||||
LIMIT 8
|
|
||||||
</db-model>
|
|
||||||
<custom>
|
|
||||||
<div class="item">
|
|
||||||
<div class="content">
|
|
||||||
<p>
|
|
||||||
{{Vn.Value.format(iter.stamp, _('%a, %e %b %Y at %T'))}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{iter.platform}} - {{iter.browser}} {{iter.version}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</custom>
|
|
||||||
</htk-repeater>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,33 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
|
|
||||||
,_timeoutId: null
|
|
||||||
|
|
||||||
,onModelStatusChange() {
|
|
||||||
if (!this.$.sessions.ready)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this._timeoutId)
|
|
||||||
clearTimeout(this._timeoutId);
|
|
||||||
|
|
||||||
this._timeoutId = setTimeout(
|
|
||||||
() => this.$.sessions.refresh(), 60000);
|
|
||||||
}
|
|
||||||
|
|
||||||
,deactivate() {
|
|
||||||
clearTimeout(this._timeoutId);
|
|
||||||
}
|
|
||||||
|
|
||||||
,async onChangeUserClick(userName) {
|
|
||||||
await this.gui.supplantUser(userName);
|
|
||||||
this.hash.setAll({form: 'ecomerce/orders'});
|
|
||||||
}
|
|
||||||
|
|
||||||
,sessionsFunc() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
Connections: Connexions
|
|
||||||
Refresh: Actualitzar
|
|
||||||
Visits: Visites
|
|
||||||
connections: connexions
|
|
|
@ -1,4 +0,0 @@
|
||||||
Connections: Connections
|
|
||||||
Refresh: Refresh
|
|
||||||
Visits: Visits
|
|
||||||
connections: connections
|
|
|
@ -1,4 +0,0 @@
|
||||||
Connections: Conexiones
|
|
||||||
Refresh: Actualizar
|
|
||||||
Visits: Visitas
|
|
||||||
connections: conexiones
|
|
|
@ -1,4 +0,0 @@
|
||||||
Connections: Connexions
|
|
||||||
Refresh: Actualiser
|
|
||||||
Visits: Visites
|
|
||||||
connections: connexions
|
|
|
@ -1,4 +0,0 @@
|
||||||
Connections: холболт
|
|
||||||
Refresh: Сэргээх
|
|
||||||
Visits: уулзалт
|
|
||||||
connections: холболт
|
|
|
@ -1,4 +0,0 @@
|
||||||
Connections: Conexões
|
|
||||||
Refresh: actualização
|
|
||||||
Visits: Visualizações
|
|
||||||
connections: conexões
|
|
|
@ -1,9 +0,0 @@
|
||||||
|
|
||||||
.action-bar .connections-sum {
|
|
||||||
padding: .4em;
|
|
||||||
background-color: #1e88e5;
|
|
||||||
border-radius: .1em;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
<vn>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>Connections</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="actions">
|
|
||||||
<htk-bar-button
|
|
||||||
icon="refresh"
|
|
||||||
tip="_Refresh"
|
|
||||||
on-click="sessions.refresh()"/>
|
|
||||||
<div class="connections-sum">
|
|
||||||
<htk-text>
|
|
||||||
<db-calc-sum
|
|
||||||
property="param"
|
|
||||||
model="sessions"
|
|
||||||
func="sessionsFunc"/>
|
|
||||||
</htk-text>
|
|
||||||
<t>connections</t>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="connections">
|
|
||||||
<htk-repeater form-id="iter" class="box htk-list vn-w-xs">
|
|
||||||
<db-model
|
|
||||||
property="model"
|
|
||||||
id="sessions"
|
|
||||||
on-status-changed="this.onModelStatusChange()">
|
|
||||||
SELECT vu.userFk userId, vu.stamp, u.nickname, s.lastUpdate,
|
|
||||||
a.platform, a.browser, a.version, u.name user
|
|
||||||
FROM userSession s
|
|
||||||
JOIN visitUser vu ON vu.id = s.userVisitFk
|
|
||||||
JOIN visitAccess ac ON ac.id = vu.accessFk
|
|
||||||
JOIN visitAgent a ON a.id = ac.agentFk
|
|
||||||
JOIN visit v ON v.id = a.visitFk
|
|
||||||
JOIN account.user u ON u.id = vu.userFk
|
|
||||||
ORDER BY lastUpdate DESC
|
|
||||||
</db-model>
|
|
||||||
<custom>
|
|
||||||
<a class="item"
|
|
||||||
href="{{`#!form=admin/access-log&user=${iter.userId}`}}"
|
|
||||||
title="_Access log">
|
|
||||||
<div class="content">
|
|
||||||
<p class="important">
|
|
||||||
{{iter.nickname}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{Vn.Value.format(iter.stamp, '%a, %T')}} -
|
|
||||||
{{Vn.Value.format(iter.lastUpdate, '%T')}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{iter.platform}} - {{iter.browser}} {{iter.version}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="actions"
|
|
||||||
on-click="$event.preventDefault()">
|
|
||||||
<htk-button
|
|
||||||
tip="_Supplant user"
|
|
||||||
icon="supervisor_account"
|
|
||||||
on-click="this.onChangeUserClick(iter.user)"/>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</custom>
|
|
||||||
</htk-repeater>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,10 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml'),
|
|
||||||
|
|
||||||
activate() {
|
|
||||||
this.$.items.setInfo('i', 'item', 'vn', ['id']);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,2 +0,0 @@
|
||||||
Items: Artícles
|
|
||||||
Enter a search term: Introdueix un terme de cerca
|
|
|
@ -1,2 +0,0 @@
|
||||||
Items: Items
|
|
||||||
Enter a search term: Enter a search term
|
|
|
@ -1,2 +0,0 @@
|
||||||
Items: Artículos
|
|
||||||
Enter a search term: Introduce un término de búsqueda
|
|
|
@ -1,2 +0,0 @@
|
||||||
Items: Articles
|
|
||||||
Enter a search term: Entrez un terme de recherche
|
|
|
@ -1,2 +0,0 @@
|
||||||
Items: Ítens
|
|
||||||
Enter a search term: Digite um termo de pesquisa
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
.items .item .photo {
|
|
||||||
border-radius: 10px;
|
|
||||||
height: 80px;
|
|
||||||
width: 80px;
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
<vn>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>Items</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="actions">
|
|
||||||
<htk-search-entry form="hash" column="search"/>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="items">
|
|
||||||
<htk-repeater
|
|
||||||
class="htk-list rows box vn-w-xs"
|
|
||||||
form-id="iter"
|
|
||||||
empty-message="_Enter a search term">
|
|
||||||
<db-model property="model" id="items" lot="hash">
|
|
||||||
SELECT i.id, i.longName, i.size, i.category,
|
|
||||||
i.value5, i.value6, i.value7,
|
|
||||||
i.image, im.updated
|
|
||||||
FROM vn.item i
|
|
||||||
LEFT JOIN image im
|
|
||||||
ON im.collectionFk = 'catalog'
|
|
||||||
AND im.name = i.image
|
|
||||||
WHERE i.longName LIKE CONCAT('%', #search, '%')
|
|
||||||
OR i.id = #search
|
|
||||||
ORDER BY i.longName LIMIT 50
|
|
||||||
</db-model>
|
|
||||||
<custom>
|
|
||||||
<div class="item">
|
|
||||||
<div class="side vn-mr-md">
|
|
||||||
<htk-image
|
|
||||||
form="$iter"
|
|
||||||
column="image"
|
|
||||||
stamp-column="updated"
|
|
||||||
class="photo"
|
|
||||||
directory="catalog"
|
|
||||||
subdir="200x200"
|
|
||||||
full-dir="1600x900"
|
|
||||||
editable="true"
|
|
||||||
conn="conn"/>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<p class="important">
|
|
||||||
{{iter.longName}}
|
|
||||||
</p>
|
|
||||||
<p class="tags">
|
|
||||||
{{iter.value5}} {{iter.value6}} {{iter.value7}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{iter.id}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{iter.image}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</custom>
|
|
||||||
</htk-repeater>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,7 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
ControlPanel: Panell de control
|
|
||||||
Module: Mòdul
|
|
||||||
Description: Descripció
|
|
|
@ -1,3 +0,0 @@
|
||||||
ControlPanel: Control panel
|
|
||||||
Module: Module
|
|
||||||
Description: Description
|
|
|
@ -1,3 +0,0 @@
|
||||||
ControlPanel: Panel de control
|
|
||||||
Module: Módulo
|
|
||||||
Description: Descripción
|
|
|
@ -1,3 +0,0 @@
|
||||||
ControlPanel: Panneau de configuration
|
|
||||||
Module: Module
|
|
||||||
Description: Description
|
|
|
@ -1,3 +0,0 @@
|
||||||
ControlPanel: Painel de controle
|
|
||||||
Module: Módulo
|
|
||||||
Description: Descrição
|
|
|
@ -1,50 +0,0 @@
|
||||||
|
|
||||||
.cpanel .items > div {
|
|
||||||
max-width: 900px;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 16px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.cpanel .item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0;
|
|
||||||
width: 140px;
|
|
||||||
padding: 15px;
|
|
||||||
text-align: center;
|
|
||||||
transition: background-color 250ms ease-out;
|
|
||||||
}
|
|
||||||
.cpanel .item:hover {
|
|
||||||
background-color: rgba(1, 1, 1, 0.05);
|
|
||||||
}
|
|
||||||
.cpanel .item > .htk-image {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0;
|
|
||||||
float: left;
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
.cpanel .item > .htk-image > img {
|
|
||||||
max-height: 60px;
|
|
||||||
max-width: 60px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.cpanel .item > h6 {
|
|
||||||
flex: none;
|
|
||||||
margin: .1em 0;
|
|
||||||
font-size: .9rem;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.cpanel .item > .text-secondary {
|
|
||||||
flex: none;
|
|
||||||
margin: 0;
|
|
||||||
font-size: .8rem;
|
|
||||||
height: 40px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
<vn>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>ControlPanel</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="cpanel">
|
|
||||||
<htk-repeater form-id="iter" class="items">
|
|
||||||
<db-model property="model">
|
|
||||||
<custom>
|
|
||||||
SELECT image, name, description, link FROM link
|
|
||||||
ORDER BY name
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
|
||||||
<custom>
|
|
||||||
<a class="item box"
|
|
||||||
href="{{iter.link}}"
|
|
||||||
target="_blank">
|
|
||||||
<htk-image
|
|
||||||
value="{{iter.image}}"
|
|
||||||
directory="link"
|
|
||||||
subdir="full"/>
|
|
||||||
<h6>
|
|
||||||
{{iter.name}}
|
|
||||||
</h6>
|
|
||||||
<p class="text-secondary">
|
|
||||||
{{iter.description}}
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</custom>
|
|
||||||
</htk-repeater>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,201 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
var Status = {
|
|
||||||
NONE : 0
|
|
||||||
,WAITING : 1
|
|
||||||
,UPLOADING : 2
|
|
||||||
,UPLOADED : 3
|
|
||||||
};
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
|
|
||||||
,filesData: []
|
|
||||||
,uploadCount: 0
|
|
||||||
,isUploading: false
|
|
||||||
|
|
||||||
,activate() {
|
|
||||||
this.$.schema.value = 'catalog';
|
|
||||||
}
|
|
||||||
|
|
||||||
,addFiles(files) {
|
|
||||||
if (!files)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var i = 0; i < files.length; i++)
|
|
||||||
this.addFile(files[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
,addFile(file) {
|
|
||||||
var doc = document;
|
|
||||||
var li = doc.createElement('div');
|
|
||||||
|
|
||||||
var div = doc.createElement('div');
|
|
||||||
div.className = 'thumb';
|
|
||||||
li.appendChild(div);
|
|
||||||
|
|
||||||
var thumb = doc.createElement('img');
|
|
||||||
thumb.file = file;
|
|
||||||
div.appendChild(thumb);
|
|
||||||
|
|
||||||
var reader = new FileReader();
|
|
||||||
reader.onload = function(e) {
|
|
||||||
thumb.src = e.target.result;
|
|
||||||
};
|
|
||||||
reader.readAsDataURL(file);
|
|
||||||
|
|
||||||
var name = doc.createElement('input');
|
|
||||||
name.type = 'text';
|
|
||||||
name.value = getFileName(file.name);
|
|
||||||
li.appendChild(name);
|
|
||||||
|
|
||||||
var statusNode = doc.createElement('div');
|
|
||||||
statusNode.className = 'status';
|
|
||||||
li.appendChild(statusNode);
|
|
||||||
|
|
||||||
var fileData = {
|
|
||||||
li: li,
|
|
||||||
file: file,
|
|
||||||
name: name,
|
|
||||||
statusNode: statusNode
|
|
||||||
};
|
|
||||||
|
|
||||||
var button = new Htk.Button({
|
|
||||||
tip: 'Remove',
|
|
||||||
icon: 'delete'
|
|
||||||
});
|
|
||||||
button.node.addEventListener('click',
|
|
||||||
() => this.onFileRemove(fileData));
|
|
||||||
li.appendChild(button.node);
|
|
||||||
|
|
||||||
this.filesData.push(fileData);
|
|
||||||
|
|
||||||
this.$.fileList.appendChild(li);
|
|
||||||
this.setImageStatus(fileData, Status.NONE, 'add', _('Pending upload'));
|
|
||||||
}
|
|
||||||
|
|
||||||
,async onUploadClick() {
|
|
||||||
if (this.isUploading) return;
|
|
||||||
|
|
||||||
const uploadQueue = [];
|
|
||||||
let hasFiles = false;
|
|
||||||
|
|
||||||
for (const fileData of this.filesData) {
|
|
||||||
if (fileData.status !== Status.NONE) continue;
|
|
||||||
this.setImageStatus(
|
|
||||||
fileData, Status.WAITING, 'cloud_upload', _('Waiting for upload'));
|
|
||||||
fileData.name.disabled = true;
|
|
||||||
uploadQueue.push(fileData);
|
|
||||||
hasFiles = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasFiles) {
|
|
||||||
Htk.Toast.showWarning(_('There are no files to upload'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isUploading = true;
|
|
||||||
let hasErrors = false;
|
|
||||||
|
|
||||||
for (const fileData of uploadQueue) {
|
|
||||||
this.setImageStatus(
|
|
||||||
fileData, Status.UPLOADING, 'upload', _('Uploading file'));
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('updateMatching', this.$.updateMatching.value);
|
|
||||||
formData.append('image', fileData.file);
|
|
||||||
formData.append('name', fileData.name.value);
|
|
||||||
formData.append('schema', this.$.schema.value);
|
|
||||||
formData.append('srv', 'json:image/upload');
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.conn.sendFormData(formData);
|
|
||||||
this.setImageStatus(
|
|
||||||
fileData, Status.UPLOADED, 'cloud_done', _('Image uploaded'));
|
|
||||||
} catch(err) {
|
|
||||||
this.setImageStatus(
|
|
||||||
fileData, Status.NONE, 'error', err.message);
|
|
||||||
fileData.name.disabled = false;
|
|
||||||
hasErrors = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isUploading = false;
|
|
||||||
|
|
||||||
if (hasErrors)
|
|
||||||
Htk.Toast.showError(_('Some errors happened on upload'));
|
|
||||||
else
|
|
||||||
Htk.Toast.showMessage(_('Upload finished successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
,setImageStatus(fileData, status, icon, title) {
|
|
||||||
fileData.status = status;
|
|
||||||
|
|
||||||
var statusNode = fileData.statusNode;
|
|
||||||
Vn.Node.removeChilds(statusNode);
|
|
||||||
|
|
||||||
var iconNode = new Htk.Icon({name: icon});
|
|
||||||
statusNode.appendChild(iconNode.node);
|
|
||||||
statusNode.title = title ? title : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
,onFileRemove(fileData) {
|
|
||||||
this.$.fileList.removeChild(fileData.li);
|
|
||||||
|
|
||||||
for (var i = 0; i < this.filesData.length; i++)
|
|
||||||
if (this.filesData[i] === fileData) {
|
|
||||||
this.filesData.splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,onClearClick() {
|
|
||||||
this.filesData = [];
|
|
||||||
Vn.Node.removeChilds(this.$.fileList);
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDropzoneClick() {
|
|
||||||
this.$.file.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onFileChange() {
|
|
||||||
this.addFiles(this.$.file.files);
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragEnter() {
|
|
||||||
this.$.dropzone.classList.add('dragover');
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragLeave() {
|
|
||||||
this.$.dropzone.classList.remove('dragover');
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragOver(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragEnd(event) {
|
|
||||||
this.$.dropzone.classList.remove('dragover');
|
|
||||||
event.dataTransfer.clearData();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDrop(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
this.addFiles(event.dataTransfer.files);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function getFileName(path) {
|
|
||||||
var barIndex = path.lastIndexOf('/');
|
|
||||||
if (barIndex === -1)
|
|
||||||
barIndex = path.lastIndexOf('\\');
|
|
||||||
if (barIndex === -1)
|
|
||||||
barIndex = 0;
|
|
||||||
|
|
||||||
var dotIndex = path.lastIndexOf('.');
|
|
||||||
if (dotIndex === -1)
|
|
||||||
dotIndex = 0;
|
|
||||||
|
|
||||||
return path.substr(barIndex, dotIndex);
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
Images: Imatges
|
|
||||||
Collection: Col·lecció
|
|
||||||
Click or drop files here: Prem o deixa anar els arxius aquí
|
|
||||||
Pending upload: Pujada pendent
|
|
||||||
Update items with matching id: Actualitzar els elements amb id coincident
|
|
||||||
Clear all: Netejar tot
|
|
||||||
Upload files: Pujar arxius
|
|
||||||
Waiting for upload: Esperant per pujar
|
|
||||||
Uploading file: Pujant fitxer
|
|
||||||
Image uploaded: Imatge pujada
|
|
||||||
Upload finished successfully: Imatges pujades correctament
|
|
||||||
Some errors happened on upload: Van ocórrer errors en pujar alguna de les imatges
|
|
||||||
There are no files to upload: No s'ha seleccionat arxius per pujar
|
|
|
@ -1,13 +0,0 @@
|
||||||
Images: Images
|
|
||||||
Collection: Collection
|
|
||||||
Click or drop files here: Click or drop files here
|
|
||||||
Pending upload: Pending upload
|
|
||||||
Update items with matching id: Update items with matching id
|
|
||||||
Clear all: Clear all
|
|
||||||
Upload files: Upload files
|
|
||||||
Waiting for upload: Waiting for upload
|
|
||||||
Uploading file: Uploading file
|
|
||||||
Image uploaded: Image uploaded
|
|
||||||
Upload finished successfully: Upload finished successfully
|
|
||||||
Some errors happened on upload: Some errors happened on upload
|
|
||||||
There are no files to upload: There are no files to upload
|
|
|
@ -1,13 +0,0 @@
|
||||||
Images: Imágenes
|
|
||||||
Collection: Colección
|
|
||||||
Click or drop files here: Pulsa o suelta los archivos aquí
|
|
||||||
Pending upload: Subida pendiente
|
|
||||||
Update items with matching id: Actualizar ítems con id coincidente
|
|
||||||
Clear all: Limpiar todo
|
|
||||||
Upload files: Subir archivos
|
|
||||||
Waiting for upload: Esperando para subir
|
|
||||||
Uploading file: Subiendo fichero
|
|
||||||
Image uploaded: Imagen subida
|
|
||||||
Upload finished successfully: Imágenes subidas correctamente
|
|
||||||
Some errors happened on upload: Ocurrieron errores al subir alguna de las imágenes
|
|
||||||
There are no files to upload: No se han seleccionado archivos para subir
|
|
|
@ -1,13 +0,0 @@
|
||||||
Images: Images
|
|
||||||
Collection: Collection
|
|
||||||
Click or drop files here: Cliquez ici ou déposer des fichiers
|
|
||||||
Pending upload: Hausse en attente
|
|
||||||
Update items with matching id: Mettre à jour les éléments avec l'identifiant correspondant
|
|
||||||
Clear all: Tout effacer
|
|
||||||
Upload files: Upload Files
|
|
||||||
Waiting for upload: En attente de télécharger
|
|
||||||
Uploading file: Uploader des fichiers
|
|
||||||
Image uploaded: Fichier uploadé
|
|
||||||
Upload finished successfully: Les images téléchargées correctement
|
|
||||||
Some errors happened on upload: Des erreurs sont survenues lors du téléchargement des images
|
|
||||||
There are no files to upload: Aucun fichier sélectionné pour télécharger
|
|
|
@ -1,13 +0,0 @@
|
||||||
Images: Imagens
|
|
||||||
Collection: Coleção
|
|
||||||
Click or drop files here: Clique ou solte arquivos aqui
|
|
||||||
Pending upload: Ascensão pendente
|
|
||||||
Update items with matching id: Atualizar itens com id correspondente
|
|
||||||
Clear all: Limpar tudo
|
|
||||||
Upload files: Fazer upload de arquivos
|
|
||||||
Waiting for upload: Esperando para enviar
|
|
||||||
Uploading file: Enviando arquivo
|
|
||||||
Image uploaded: Imagem Enviada
|
|
||||||
Upload finished successfully: Upload concluído com sucesso
|
|
||||||
Some errors happened on upload: Ocorreram erros ao subir alguma das imagens
|
|
||||||
There are no files to upload: Não há arquivos selecionados para upload
|
|
|
@ -1,81 +0,0 @@
|
||||||
|
|
||||||
/* Dropzone */
|
|
||||||
|
|
||||||
.photos .dropzone {
|
|
||||||
background-color: white;
|
|
||||||
border-style: dashed;
|
|
||||||
border-radius: .4em;
|
|
||||||
border-color: #2196F3;
|
|
||||||
padding: 2em 1em;
|
|
||||||
text-align: center;
|
|
||||||
color: #666;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.photos .dropzone.dragover {
|
|
||||||
color: #CCC;
|
|
||||||
border-style: solid;
|
|
||||||
}
|
|
||||||
.photos input[type=file] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* File list */
|
|
||||||
|
|
||||||
.photos .file-list {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
.photos .file-list > div {
|
|
||||||
height: 2.5em;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.photos .file-list > div > * {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.photos .file-list .thumb {
|
|
||||||
width: 2em;
|
|
||||||
padding-right: .5em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.photos .file-list .thumb > img {
|
|
||||||
max-height: 2em;
|
|
||||||
max-width: 2em;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.photos .file-list input {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
.photos .file-list .status {
|
|
||||||
cursor: pointer;
|
|
||||||
width: 1.2em;
|
|
||||||
padding-left: .5em;
|
|
||||||
padding-right: .5em;
|
|
||||||
}
|
|
||||||
.photos .file-list .status > .htk-icon {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.photos .file-list .htk-button {
|
|
||||||
opacity: .2;
|
|
||||||
}
|
|
||||||
.photos .file-list .htk-button:hover {
|
|
||||||
background-color: transparent;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.photos .file-list .htk-button > img {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Footer */
|
|
||||||
|
|
||||||
.photos .update-matching {
|
|
||||||
margin-top: 1.5em;
|
|
||||||
}
|
|
||||||
.photos .footer {
|
|
||||||
margin-top: 1.5em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.photos .footer > button {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
<vn>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>Images</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="photos">
|
|
||||||
<div class="box form vn-w-sm vn-pa-lg">
|
|
||||||
<div class="form-group">
|
|
||||||
<label><t>Collection</t></label>
|
|
||||||
<htk-combo id="schema">
|
|
||||||
<db-model property="model">
|
|
||||||
<custom>
|
|
||||||
SELECT name, `desc` FROM imageCollection ORDER BY `desc`
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
|
||||||
</htk-combo>
|
|
||||||
</div>
|
|
||||||
<div id="dropzone" class="dropzone"
|
|
||||||
on-dragenter="onDragEnter"
|
|
||||||
on-dragleave="onDragLeave"
|
|
||||||
on-mouseout="onDragLeave"
|
|
||||||
on-dragover="onDragOver"
|
|
||||||
on-drop="onDrop"
|
|
||||||
on-dragend="onDragEnd"
|
|
||||||
on-click="onDropzoneClick">
|
|
||||||
<t>Click or drop files here</t>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
id="file"
|
|
||||||
type="file"
|
|
||||||
multiple="true"
|
|
||||||
name="image"
|
|
||||||
on-change="onFileChange"/>
|
|
||||||
<div id="file-list" class="file-list"/>
|
|
||||||
<div class="update-matching">
|
|
||||||
<label>
|
|
||||||
<htk-check id="update-matching" value="true"/>
|
|
||||||
<t>Update items with matching id</t>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<button class="thin" on-click="onClearClick">
|
|
||||||
<t>Clear all</t>
|
|
||||||
</button>
|
|
||||||
<button class="thin" on-click="onUploadClick">
|
|
||||||
<t>Upload files</t>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,93 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
|
|
||||||
,activate() {
|
|
||||||
this.$.resultIndex.value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
,clean() {
|
|
||||||
if (this._grid) {
|
|
||||||
this.$.gridHolder.removeChild(this._grid.node);
|
|
||||||
this._grid.unref();
|
|
||||||
this._grid = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,onExecuteClick() {
|
|
||||||
this.clean();
|
|
||||||
|
|
||||||
var model = new Db.Model({
|
|
||||||
conn: this.conn,
|
|
||||||
query: this.$.sql.value,
|
|
||||||
resultIndex: this.$.resultIndex.value,
|
|
||||||
updatable: this.$.updatable.value
|
|
||||||
});
|
|
||||||
model.on('status-changed', this.onModelChange, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
,onCleanClick() {
|
|
||||||
this.clean();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onModelChange(model, status) {
|
|
||||||
if (status !== Db.Model.Status.LOADING) {
|
|
||||||
model.disconnect('status-changed', this.onModelChange, this);
|
|
||||||
model.unref();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status !== Db.Model.Status.READY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Htk.Toast.showMessage(_('Query executed!'));
|
|
||||||
|
|
||||||
var gridHolder = this.$.gridHolder;
|
|
||||||
|
|
||||||
if (gridHolder.firstChild)
|
|
||||||
gridHolder.removeChilds(gridHolder.firstChild);
|
|
||||||
|
|
||||||
var grid = new Htk.Grid();
|
|
||||||
|
|
||||||
var columns = model.columns;
|
|
||||||
|
|
||||||
for (var i = 0; i < columns.length; i++) {
|
|
||||||
var c = columns[i];
|
|
||||||
|
|
||||||
switch (c.type) {
|
|
||||||
case Db.Conn.Type.BOOLEAN:
|
|
||||||
var column = new Htk.ColumnCheck();
|
|
||||||
break;
|
|
||||||
case Db.Conn.Type.INTEGER:
|
|
||||||
var column = new Htk.ColumnSpin();
|
|
||||||
break;
|
|
||||||
case Db.Conn.Type.DOUBLE:
|
|
||||||
var column = new Htk.ColumnSpin({digits: 2});
|
|
||||||
break;
|
|
||||||
case Db.Conn.Type.DATE:
|
|
||||||
var column = new Htk.ColumnDate({format: '%a, %e %b %Y'});
|
|
||||||
break;
|
|
||||||
case Db.Conn.Type.DATE_TIME:
|
|
||||||
var column = new Htk.ColumnDate({format: '%a, %e %b %Y, %T'});
|
|
||||||
break;
|
|
||||||
case Db.Conn.Type.STRING:
|
|
||||||
default:
|
|
||||||
var column = new Htk.ColumnText();
|
|
||||||
}
|
|
||||||
|
|
||||||
column.setProperties({
|
|
||||||
title: c.name,
|
|
||||||
editable: this.$.updatable.value,
|
|
||||||
columnIndex: i
|
|
||||||
});
|
|
||||||
|
|
||||||
grid.appendColumn(column);
|
|
||||||
}
|
|
||||||
|
|
||||||
grid.model = model;
|
|
||||||
gridHolder.appendChild(grid.node);
|
|
||||||
this._grid = grid;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
Queries: Consultes
|
|
||||||
Execute: Executar
|
|
||||||
Clean: Netejar
|
|
||||||
SQL query: Consulta SQL
|
|
||||||
Updatable: Actualitzable
|
|
||||||
Query executed!: Consulta executada!
|
|
|
@ -1,6 +0,0 @@
|
||||||
Queries: Queries
|
|
||||||
Execute: Execute
|
|
||||||
Clean: Clean
|
|
||||||
SQL query: SQL query
|
|
||||||
Updatable: Updatable
|
|
||||||
Query executed!: Query executed!
|
|
|
@ -1,6 +0,0 @@
|
||||||
Queries: Consultas
|
|
||||||
Execute: Ejecutar
|
|
||||||
Clean: Limpiar
|
|
||||||
SQL query: Consulta SQL
|
|
||||||
Updatable: Actualizable
|
|
||||||
Query executed!: ¡Consulta ejecutada!
|
|
|
@ -1,6 +0,0 @@
|
||||||
Queries: Queries
|
|
||||||
Execute: Execute
|
|
||||||
Clean: Clean
|
|
||||||
SQL query: SQL query
|
|
||||||
Updatable: Updatable
|
|
||||||
Query executed!: Query executed!
|
|
|
@ -1,6 +0,0 @@
|
||||||
Queries: Consultas
|
|
||||||
Execute: Executar
|
|
||||||
Clean: Limpar
|
|
||||||
SQL query: Consulta SQL
|
|
||||||
Updatable: Actualizável
|
|
||||||
Query executed!: Consulta executada!
|
|
|
@ -1,10 +0,0 @@
|
||||||
|
|
||||||
.queries textarea {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 8em;
|
|
||||||
}
|
|
||||||
.queries .result {
|
|
||||||
margin-top: 1em;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
<vn>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>Queries</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="actions">
|
|
||||||
<htk-bar-button
|
|
||||||
icon="ok"
|
|
||||||
tip="_Execute"
|
|
||||||
on-click="this.onExecuteClick()"/>
|
|
||||||
<htk-bar-button
|
|
||||||
icon="delete"
|
|
||||||
tip="_Clean"
|
|
||||||
on-click="this.onCleanClick()"/>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="queries">
|
|
||||||
<div class="box form vn-w-sm vn-pa-lg">
|
|
||||||
<div class="form-group">
|
|
||||||
<label><t>SQL query</t></label>
|
|
||||||
<textarea
|
|
||||||
id="sql"
|
|
||||||
autocorrect="off"
|
|
||||||
autocapitalize="off"
|
|
||||||
spellcheck="false"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label><t>Result index</t></label>
|
|
||||||
<htk-spin id="result-index"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label><t>Updatable</t></label>
|
|
||||||
<htk-check id="updatable"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box result">
|
|
||||||
<div id="grid-holder"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,20 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
|
|
||||||
,rendererFunc(scope, form) {
|
|
||||||
var isEnabled = form.$.active
|
|
||||||
scope.$.disabled.style.display = isEnabled ?
|
|
||||||
'none' : 'block';
|
|
||||||
scope.$.impersonate.node.style.display = isEnabled ?
|
|
||||||
'block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
,async onChangeUserClick(userName) {
|
|
||||||
await this.gui.supplantUser(userName);
|
|
||||||
this.hash.setAll({form: 'ecomerce/orders'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
User management: Gestió d'usuaris
|
|
||||||
Disabled: Deshabilitat
|
|
||||||
Impersonate user: Suplantar usuari
|
|
||||||
Access log: Registre d'accessos
|
|
|
@ -1,4 +0,0 @@
|
||||||
User management: User management
|
|
||||||
Disabled: Disabled
|
|
||||||
Impersonate user: Impersonate user
|
|
||||||
Access log: Access log
|
|
|
@ -1,4 +0,0 @@
|
||||||
User management: Gestión de usuarios
|
|
||||||
Disabled: Desactivado
|
|
||||||
Impersonate user: Suplantar usuario
|
|
||||||
Access log: Registro de accesos
|
|
|
@ -1,4 +0,0 @@
|
||||||
User management: Gestion des utilisateurs
|
|
||||||
Disabled: Désactivé
|
|
||||||
Impersonate user: Accès utilisateur
|
|
||||||
Access log: Journal des accès
|
|
|
@ -1,4 +0,0 @@
|
||||||
User management: Gestão de usuarios
|
|
||||||
Disabled: Desativado
|
|
||||||
Impersonate user: Suplantar usuario
|
|
||||||
Access log: Registro de acessos
|
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
.users-box.item > .actions {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.users-box .disabled {
|
|
||||||
color: white;
|
|
||||||
background-color: #F66;
|
|
||||||
border-radius: .2em;
|
|
||||||
padding: .3em;
|
|
||||||
font-size: .8em;
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
<vn>
|
|
||||||
<div id="title">
|
|
||||||
<h1><t>User management</t></h1>
|
|
||||||
</div>
|
|
||||||
<div id="actions">
|
|
||||||
<htk-search-entry form="hash" column="user"/>
|
|
||||||
</div>
|
|
||||||
<div id="form" class="users">
|
|
||||||
<htk-repeater
|
|
||||||
form-id="iter"
|
|
||||||
renderer="rendererFunc"
|
|
||||||
class="htk-list box vn-w-xs">
|
|
||||||
<db-model property="model" lot="hash">
|
|
||||||
SELECT u.id, u.name, u.nickname, u.active
|
|
||||||
FROM account.user u
|
|
||||||
WHERE u.name LIKE CONCAT('%', #user, '%')
|
|
||||||
OR u.nickname LIKE CONCAT('%', #user, '%')
|
|
||||||
OR u.id = #user
|
|
||||||
ORDER BY u.name LIMIT 200
|
|
||||||
</db-model>
|
|
||||||
<custom>
|
|
||||||
<a class="users-box item"
|
|
||||||
href="{{`#!form=admin/access-log&user=${iter.id}`}}"
|
|
||||||
title="_Access log">
|
|
||||||
<div class="content">
|
|
||||||
<p class="important">
|
|
||||||
{{iter.nickname}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
#{{iter.id}} - {{iter.name}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="actions"
|
|
||||||
on-click="$event.preventDefault()">
|
|
||||||
<span id="disabled" class="disabled">
|
|
||||||
<t>Disabled</t>
|
|
||||||
</span>
|
|
||||||
<htk-button
|
|
||||||
id="impersonate"
|
|
||||||
icon="supervisor_account"
|
|
||||||
tip="_Impersonate user"
|
|
||||||
on-click="this.onChangeUserClick(iter.name)"/>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</custom>
|
|
||||||
</htk-repeater>
|
|
||||||
</div>
|
|
||||||
</vn>
|
|
|
@ -1,15 +0,0 @@
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default new Class({
|
|
||||||
Extends: Hedera.Form,
|
|
||||||
Template: require('./ui.xml')
|
|
||||||
|
|
||||||
,activate() {
|
|
||||||
if (!this.hash.$.to)
|
|
||||||
this.hash.assign({
|
|
||||||
from: new Date(),
|
|
||||||
to: new Date()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
Visits: Visites
|
|
||||||
Refresh: Actualitzar
|
|
||||||
Connections: Connexions
|
|
||||||
From: Desde
|
|
||||||
To: Fins
|
|
||||||
Select date interval: Selecciona un interval de dates
|
|
||||||
visits: visites
|
|
||||||
news: noves
|
|
||||||
'%a, %e %b %Y at %T': '%a, %e %b %Y a les %T'
|
|
|
@ -1,9 +0,0 @@
|
||||||
Visits: Visits
|
|
||||||
Refresh: Refresh
|
|
||||||
Connections: Connections
|
|
||||||
From: From
|
|
||||||
To: To
|
|
||||||
Select date interval: Select date interval
|
|
||||||
visits: visits
|
|
||||||
news: news
|
|
||||||
'%a, %e %b %Y at %T': '%a, %e %b %Y at %T'
|
|
|
@ -1,9 +0,0 @@
|
||||||
Visits: Visitas
|
|
||||||
Refresh: Actualizar
|
|
||||||
Connections: Conexiones
|
|
||||||
From: Desde
|
|
||||||
To: Hasta
|
|
||||||
Select date interval: Selecciona un intérvalo de fechas
|
|
||||||
visits: visitas
|
|
||||||
news: nuevas
|
|
||||||
'%a, %e %b %Y at %T': '%a, %e %b %Y a las %T'
|
|
|
@ -1,9 +0,0 @@
|
||||||
Visits: Visites
|
|
||||||
Refresh: Actualiser
|
|
||||||
Connections: Connexions
|
|
||||||
From: À partir de
|
|
||||||
To: À
|
|
||||||
Select date interval: Sélectionnez une plage de dates
|
|
||||||
visits: visites
|
|
||||||
news: nouvelles
|
|
||||||
'%a, %e %b %Y at %T': '%a, %e %b %Y à %T'
|
|
|
@ -1,9 +0,0 @@
|
||||||
Visits: уулзалт
|
|
||||||
Refresh: Сэргээх
|
|
||||||
Connections: холболт
|
|
||||||
From: эхлэн
|
|
||||||
To: нь
|
|
||||||
Select date interval: Сонгох огноо интервал
|
|
||||||
visits: уулзалт
|
|
||||||
news: мэдээ
|
|
||||||
'%a, %e %b %Y at %T': '%a, %e %b %Y нь %T'
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue