Compare commits
569 Commits
0000-impro
...
dev
Author | SHA1 | Date |
---|---|---|
|
a956c268b6 | |
|
5b968b6e46 | |
|
ef65622014 | |
|
35efe67c63 | |
|
6dbcf162ca | |
|
20f5dc46f7 | |
|
c0ab27bd7a | |
|
6508a4e4f0 | |
|
6fa75b3abc | |
|
ce230b1133 | |
|
f2ca49b261 | |
|
a5b8e56506 | |
|
93562bb4dd | |
|
aaa9d34404 | |
|
de5740856e | |
|
70746995ca | |
|
90dea8fde9 | |
|
f57967cd17 | |
|
1c54922692 | |
|
8929f8c55a | |
|
7f2c645682 | |
|
099f494101 | |
|
ddc5c2adc7 | |
|
16d1e1fd69 | |
|
340c68406c | |
|
c2f7ee1be8 | |
|
4d81b6c5b2 | |
|
fba0c73402 | |
|
5ac6652663 | |
|
21da29ab8d | |
|
1f373f1bc3 | |
|
47acbb7ebb | |
|
f863d8a897 | |
|
5186387162 | |
|
fd11c1ea00 | |
|
8a022aac66 | |
|
ddaff6afe9 | |
|
bdf7a16003 | |
|
3db9314dfd | |
|
7ff9e2e97d | |
|
0d61a9de03 | |
|
979b1293a9 | |
|
29168a6927 | |
|
b62185289f | |
|
d66047c451 | |
|
03be5f9a56 | |
|
96fd08b369 | |
|
36573342b7 | |
|
14451121ac | |
|
44a45a25b2 | |
|
7618e65105 | |
|
1efb84dd83 | |
|
90137ab08f | |
|
b73e292cb0 | |
|
444732460e | |
|
ab88575c72 | |
|
5cf6ef5b1c | |
|
dcf46094f0 | |
|
c6589989d4 | |
|
59e7999385 | |
|
756fccaa78 | |
|
7174842cfa | |
|
d6e7d3b025 | |
|
5bc20e9e05 | |
|
6be7bccff7 | |
|
bf5ba5dac1 | |
|
0d2ac8f9fb | |
|
cb61ad5d11 | |
|
5abcf9e71d | |
|
0952a690a5 | |
|
cc5faf97da | |
|
9507292a13 | |
|
17baf12449 | |
|
749189d726 | |
|
7a94c3a01e | |
|
c4977b7997 | |
|
ca4457bf54 | |
|
d1c4f9dba2 | |
|
921b029b06 | |
|
ff63cd11c3 | |
|
1f1043a43c | |
|
a868a5b540 | |
|
baa596430e | |
|
5ca765486f | |
|
61fac85554 | |
|
3a714debfc | |
|
647dd09013 | |
|
05c71c7425 | |
|
90e2b0abb5 | |
|
bcbbee411f | |
|
961ff02053 | |
|
e7eb2a01fe | |
|
98cefc8f0f | |
|
e40a28b649 | |
|
f869e7413c | |
|
29e800ea30 | |
|
1eb98b772a | |
|
1fe6816c08 | |
|
5bbc342471 | |
|
d808fa71d1 | |
|
ac226205b0 | |
|
87f17409f7 | |
|
ae70cbaaf4 | |
|
6e1613a26c | |
|
359ddb5d18 | |
|
d75fe3fc00 | |
|
e6cd88ee82 | |
|
a405cba00b | |
|
e4f55ca9e9 | |
|
d8ea9134d4 | |
|
a96859b6bb | |
|
e210a09f6b | |
|
5304a77f94 | |
|
3f63da06f1 | |
|
7d120598bc | |
|
4cf91140f7 | |
|
06554b7dee | |
|
83c6886ee6 | |
|
4765bc78de | |
|
0a9635feb2 | |
|
00c8e4b1e3 | |
|
1414b6c96e | |
|
244b3f939e | |
|
1d2f9061c5 | |
|
a121750fa7 | |
|
73ba16634e | |
|
2515cbcee7 | |
|
d1cdba800d | |
|
02ddc87755 | |
|
7689be689f | |
|
33778629e6 | |
|
7f1d8ebb8e | |
|
4d8a67f499 | |
|
c6120af93b | |
|
95f819c22f | |
|
496061fb3c | |
|
0b85c1230a | |
|
3ed871cb4c | |
|
c7159a1e13 | |
|
fba880fb33 | |
|
1535a557a8 | |
|
4a09fe39a8 | |
|
3977b258d3 | |
|
6915e06c71 | |
|
a474f9df05 | |
|
620bd53262 | |
|
8f98597ea2 | |
|
a2cd8a711e | |
|
08b4a3437c | |
|
a59c44fb3a | |
|
2adfd2299a | |
|
f929e67d76 | |
|
d37493b081 | |
|
0f3ddb1a99 | |
|
bb4e348d0c | |
|
754b8cd6c4 | |
|
7bb067223a | |
|
9363cdf5a4 | |
|
d17bc6115f | |
|
9475c26663 | |
|
607513452f | |
|
86be0278a6 | |
|
a8f98d62ab | |
|
2af5851066 | |
|
1470e77572 | |
|
32cc865290 | |
|
8bcfe9f50c | |
|
f638143e3e | |
|
07bde10609 | |
|
4231365e4f | |
|
fa56a4e540 | |
|
5bcfd5897c | |
|
572d4b7b83 | |
|
bbeb70eb6b | |
|
2905a6ab57 | |
|
5b84671d57 | |
|
9146d28db5 | |
|
59242daa79 | |
|
fd32b3f15a | |
|
56395aa91b | |
|
2610448e79 | |
|
9eba09ddf7 | |
|
74980fbdd7 | |
|
01326dc91c | |
|
5ce2f46842 | |
|
42f682739e | |
|
bbe7f2ea14 | |
|
cdafea824e | |
|
5fce203252 | |
|
9945c8f1b6 | |
|
1ef0d48ba7 | |
|
197758f2bc | |
|
511e925467 | |
|
f47e7e07a7 | |
|
b32be540f3 | |
|
4190aad94e | |
|
9bfd42eaf8 | |
|
dd7185d5dd | |
|
10d8128133 | |
|
b357c4a451 | |
|
e5941266ed | |
|
592f79fcbd | |
|
0abc6bdc23 | |
|
210b7e7806 | |
|
92a4bc458c | |
|
520e0c1eff | |
|
afd23e08b7 | |
|
18cdb4cc1b | |
|
ca5f80f6c3 | |
|
d1ff6889af | |
|
a632a15242 | |
|
67b6f77b12 | |
|
e8eab29887 | |
|
326aeee127 | |
|
bbb0089b59 | |
|
406b2f8300 | |
|
efc7342359 | |
|
806c4cc3ad | |
|
c463e967ca | |
|
be43a38b38 | |
|
59ed61ae9b | |
|
17e54cfc60 | |
|
baa9bb7cdf | |
|
87d75be910 | |
|
ac629dc97b | |
|
ff3320d590 | |
|
e8b727ab6c | |
|
5934ee3832 | |
|
4f09574697 | |
|
6d95dfb999 | |
|
1fa9b1e8b0 | |
|
327508c3ee | |
|
ba2c143677 | |
|
9309bd156c | |
|
875629fc17 | |
|
ebb6055be5 | |
|
209d2e2606 | |
|
11da415eb2 | |
|
6640314879 | |
|
b0b2451510 | |
|
922f27e71a | |
|
8978172515 | |
|
ca61ee24ce | |
|
5443cbe7f1 | |
|
f39b8b4cb3 | |
|
998e7a0b5e | |
|
17f6ba97b4 | |
|
9b71d4352b | |
|
16da03b0f9 | |
|
5824633e1b | |
|
8ec59e969b | |
|
faa04966c7 | |
|
e92e04b4d5 | |
|
ae70cd2b4e | |
|
ece21bb929 | |
|
339f885d1b | |
|
679bdc6235 | |
|
ed4b93330a | |
|
ac62118a20 | |
|
6ecce8fec6 | |
|
0c7476a37c | |
|
0510149fd8 | |
|
5f1f0423cf | |
|
22ce6425de | |
|
1f80bd5ee0 | |
|
ee989a04bc | |
|
cc42626406 | |
|
f613295e34 | |
|
6a8be05d4b | |
|
6f080b1275 | |
|
a59d062f95 | |
|
c07ff136ed | |
|
7b6b50e27e | |
|
7451f643af | |
|
8fac1a5ab4 | |
|
c2a601c30c | |
|
f82ecaad91 | |
|
5de1601348 | |
|
5abed9a207 | |
|
1b7de926d5 | |
|
656f1be008 | |
|
d4a7f41600 | |
|
59f446a824 | |
|
28876ad819 | |
|
137c912ba9 | |
|
3c4b201069 | |
|
94c4c43bb5 | |
|
c5d1a6fd3a | |
|
996f318fe6 | |
|
dc6b1b967e | |
|
dca89ed01c | |
|
1e514ab12a | |
|
bf5ad50f94 | |
|
e8f73c5147 | |
|
3f637fff80 | |
|
5e87da735f | |
|
81ba131375 | |
|
28ca363348 | |
|
958b39e9be | |
|
c11500b3de | |
|
a68436b330 | |
|
243dd6f44a | |
|
d9fdb3f4c2 | |
|
d16a992c8a | |
|
04b2e0ff50 | |
|
297b2f877c | |
|
87c3e8e11b | |
|
264a2c5f58 | |
|
3913eed8aa | |
|
a652f86172 | |
|
90e9941b4c | |
|
a43e0522f5 | |
|
a130163617 | |
|
2887497730 | |
|
13e61acb2a | |
|
574c63ea4e | |
|
be23ceed4b | |
|
00c7f9da0d | |
|
9ca2f78103 | |
|
fd6f39371a | |
|
d1819118d8 | |
|
7669dc0db0 | |
|
e635807cb9 | |
|
a1b77ce202 | |
|
68eedecb90 | |
|
2307c16748 | |
|
30052408de | |
|
87a583794a | |
|
de19063ed9 | |
|
894ff77877 | |
|
3de2c2f9fe | |
|
0141eea534 | |
|
fc22db73f2 | |
|
d2ed1fb1af | |
|
060acd294e | |
|
6de30422ff | |
|
2c5dcba923 | |
|
0600daec31 | |
|
1c311a851f | |
|
2f0dc7e282 | |
|
09e418da95 | |
|
60eabacf22 | |
|
f80e8b4476 | |
|
614038470d | |
|
f515249329 | |
|
dc0ba66257 | |
|
546e67d6f6 | |
|
11ba609144 | |
|
f815aa9992 | |
|
83ab901da6 | |
|
3384170793 | |
|
2aff47ef2e | |
|
1d782a28ed | |
|
39e41a8cbd | |
|
10cff090f1 | |
|
d23f06bd91 | |
|
17cf7135c7 | |
|
cb39b99020 | |
|
aa52198cd4 | |
|
4bb31e9dd3 | |
|
7e398059dc | |
|
4f82cc9e9a | |
|
7464abc5a4 | |
|
60561265e8 | |
|
aa4d1edd32 | |
|
f3bdb5f3c5 | |
|
b428a11ac0 | |
|
07632e077e | |
|
f5e1b11df9 | |
|
497f0c130b | |
|
8ec889a9f7 | |
|
2d12be21cb | |
|
32b794225a | |
|
803075f216 | |
|
aeb94d2569 | |
|
5a94525bd7 | |
|
188181b114 | |
|
2fe78cfc0e | |
|
559e7c48a2 | |
|
b2535c5d38 | |
|
8522097950 | |
|
89a2263adb | |
|
b9ff616e0f | |
|
dbbaaa34b1 | |
|
90a464a77d | |
|
06f58f07ca | |
|
995dbc3585 | |
|
52e295a393 | |
|
a014a40a12 | |
|
1530b571c0 | |
|
95aa622497 | |
|
6121973824 | |
|
1430fc2a1a | |
|
3c8bc545ec | |
|
25d5346f5d | |
|
ff58f1f1c3 | |
|
7591bebe83 | |
|
3008f4b87f | |
|
f9c8cd0e83 | |
|
66875ce193 | |
|
6a040cd4d8 | |
|
b09e345e62 | |
|
e53ed0d67a | |
|
87922964de | |
|
9e59d578b8 | |
|
690218c16e | |
|
846d7b9ec8 | |
|
65c02084d2 | |
|
3e26e49b86 | |
|
a07842e899 | |
|
989730a905 | |
|
079e9266f1 | |
|
6c59b72023 | |
|
7a46fc0bbc | |
|
1c6d346f51 | |
|
13c29b641f | |
|
fa2107befb | |
|
d543e64851 | |
|
c8c629cdf8 | |
|
d72ab8cefe | |
|
4886f4cd96 | |
|
d740c92efc | |
|
2ad9675dd7 | |
|
46e6a838f0 | |
|
8ad20d23e3 | |
|
8e916d376a | |
|
54966582b5 | |
|
7219962f0c | |
|
4733185e9f | |
|
0f2db56f1c | |
|
bc4000f135 | |
|
4863ff83ba | |
|
6322c44e14 | |
|
0db18864a4 | |
|
c4ad0d77e0 | |
|
5a8b0447dd | |
|
54dd5a21cf | |
|
d4fae5b077 | |
|
cf1e1255bd | |
|
ada90236ee | |
|
d91a40de3e | |
|
5fa047214a | |
|
955dce8cbf | |
|
00e7348b9a | |
|
e0c2c58089 | |
|
9595e9f21f | |
|
ad57c0d377 | |
|
b7ce16b034 | |
|
ed45e02a82 | |
|
23c19f1486 | |
|
976e06bcfd | |
|
1cc2f76ffa | |
|
9adc545f08 | |
|
1fb65632c6 | |
|
be9a23caca | |
|
fe21919a6e | |
|
de1b6a3998 | |
|
2fdb66a55b | |
|
ce0b782925 | |
|
bd4ec0fead | |
|
cdf7b176b2 | |
|
9082a7ede9 | |
|
c9400f2fca | |
|
c0e2578e3c | |
|
c9703bbeee | |
|
77a8787ad2 | |
|
21a4aee8e4 | |
|
d01fb711b1 | |
|
6fceb2cf69 | |
|
2cd2368eee | |
|
4ba69cf2da | |
|
28db4da4f8 | |
|
e1ed50b139 | |
|
4d7d35cb84 | |
|
a23725b815 | |
|
1029660760 | |
|
0477449c46 | |
|
6cb13727a7 | |
|
5fc168987d | |
|
ccfbdbd9f5 | |
|
d04ba0695a | |
|
5102571b5f | |
|
90161d1014 | |
|
7329310f1f | |
|
1bbe94385b | |
|
7673a21baf | |
|
b1c5bb1b6a | |
|
0b862f8a4e | |
|
235121a637 | |
|
6e59fd8ea7 | |
|
46f0420431 | |
|
55b5409624 | |
|
dc41737464 | |
|
fb422846dd | |
|
4f3b7efcb3 | |
|
0882952dcf | |
|
94590ac50a | |
|
230eae9eda | |
|
3f0b762650 | |
|
76b6689f60 | |
|
45852245a1 | |
|
774a471f3d | |
|
060abe371e | |
|
a374da6f9b | |
|
db1ac9d185 | |
|
72a97fa069 | |
|
6f1b96cb4a | |
|
95d9c6c4d5 | |
|
0a5aa8e6cd | |
|
27ec20369e | |
|
4907e37b70 | |
|
8dc92c484c | |
|
6ec94de7a3 | |
|
0ae35c2622 | |
|
ae0973c16b | |
|
c744e9286e | |
|
ec85573e39 | |
|
233c9f624c | |
|
b5c610daf4 | |
|
698cd9aeb8 | |
|
28146b08ef | |
|
8cc05e174e | |
|
38a6a7a3ac | |
|
c77373e772 | |
|
03dd6f94e4 | |
|
1ade47299a | |
|
9394ca8c51 | |
|
bdc8d0c225 | |
|
acd0a0025e | |
|
1395532b6c | |
|
81a31a8674 | |
|
562368e77d | |
|
04b34b5d31 | |
|
c39604fbc1 | |
|
3903d0f53b | |
|
78eed917b8 | |
|
6a8e5bb264 | |
|
96758a3abb | |
|
2382c70e16 | |
|
91dec387fa | |
|
d19438bad1 | |
|
a57498548f | |
|
063d9b92e8 | |
|
7f2f0372b3 | |
|
b56a12c341 | |
|
3ca7bb7688 | |
|
177133b6c0 | |
|
f5f0904d85 | |
|
65791be9d5 | |
|
7b10868dea | |
|
fdceb1cb0e | |
|
0376674081 | |
|
a4d3f323c3 | |
|
87237ed366 | |
|
2f1c31fa74 | |
|
283c534980 | |
|
bbf691764c | |
|
e344f6ac34 | |
|
01328996cf | |
|
df56173dd7 | |
|
ba802341db | |
|
9cddde8d8f | |
|
0313b8729f | |
|
3b14d419d6 | |
|
73b2750b8a | |
|
fadc5505ad | |
|
80b295f467 | |
|
21d3eda413 | |
|
342f4ab82d |
|
@ -0,0 +1,2 @@
|
||||||
|
debian
|
||||||
|
node_modules
|
|
@ -8,4 +8,8 @@ rules:
|
||||||
no-mixed-spaces-and-tabs: 0
|
no-mixed-spaces-and-tabs: 0
|
||||||
no-console: 0
|
no-console: 0
|
||||||
no-cond-assign: 0
|
no-cond-assign: 0
|
||||||
no-unexpected-multiline: 0
|
no-unexpected-multiline: 0
|
||||||
|
brace-style: [error, 1tbs]
|
||||||
|
space-before-function-paren: [error, never]
|
||||||
|
padded-blocks: [error, never]
|
||||||
|
func-call-spacing: [error, never]
|
|
@ -1,2 +1,6 @@
|
||||||
node_modules
|
node_modules
|
||||||
build/
|
build/
|
||||||
|
dist/
|
||||||
|
config.my.php
|
||||||
|
.vscode/
|
||||||
|
.quasar
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Not using buster because of bug: https://bugs.php.net/bug.php?id=78870
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
curl \
|
||||||
|
ca-certificates \
|
||||||
|
gnupg2
|
||||||
|
|
||||||
|
# Apache
|
||||||
|
|
||||||
|
RUN apt-get install -y --no-install-recommends \
|
||||||
|
apache2 \
|
||||||
|
libapache2-mod-php \
|
||||||
|
&& . /etc/apache2/envvars \
|
||||||
|
&& ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log" \
|
||||||
|
&& ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log" \
|
||||||
|
&& ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"
|
||||||
|
|
||||||
|
RUN a2dissite 000-default
|
||||||
|
|
||||||
|
# NodeJs
|
||||||
|
|
||||||
|
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||||
|
&& apt-get install -y --no-install-recommends nodejs
|
||||||
|
|
||||||
|
# Hedera
|
||||||
|
|
||||||
|
RUN curl -sL https://apt.verdnatura.es/conf/verdnatura.gpg | tee /etc/apt/trusted.gpg.d/verdnatura.gpg \
|
||||||
|
&& echo "deb http://apt.verdnatura.es/ bookworm main" \
|
||||||
|
> /etc/apt/sources.list.d/vn.list \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
php-apcu \
|
||||||
|
php-image-text \
|
||||||
|
php-text-captcha \
|
||||||
|
php-zip \
|
||||||
|
hedera-web \
|
||||||
|
cron
|
||||||
|
|
||||||
|
ARG BUILD_ID=unknown
|
||||||
|
ARG VERSION
|
||||||
|
ENV VERSION $VERSION
|
||||||
|
RUN echo $VERSION
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y php-vn-lib hedera-web=$VERSION \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
CMD ["apachectl", "-D", "FOREGROUND"]
|
|
@ -0,0 +1,102 @@
|
||||||
|
#!/usr/bin/env groovy
|
||||||
|
|
||||||
|
def BRANCH_ENV = [
|
||||||
|
test: 'test',
|
||||||
|
master: 'production'
|
||||||
|
]
|
||||||
|
def remote = [:]
|
||||||
|
|
||||||
|
node {
|
||||||
|
stage('Setup') {
|
||||||
|
env.NODE_ENV = BRANCH_ENV[env.BRANCH_NAME] ?: 'dev'
|
||||||
|
|
||||||
|
echo "NODE_NAME: ${env.NODE_NAME}"
|
||||||
|
echo "WORKSPACE: ${env.WORKSPACE}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
environment {
|
||||||
|
PROJECT_NAME = 'hedera-web'
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Debuild') {
|
||||||
|
when {
|
||||||
|
anyOf {
|
||||||
|
branch 'master'
|
||||||
|
branch 'test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
agent {
|
||||||
|
docker {
|
||||||
|
image 'registry.verdnatura.es/verdnatura/debuild:2.23.4-vn7'
|
||||||
|
registryUrl 'https://registry.verdnatura.es/'
|
||||||
|
registryCredentialsId 'docker-registry'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
sh 'debuild -us -uc -b'
|
||||||
|
sh 'mkdir -p debuild'
|
||||||
|
sh 'mv ../hedera-web_* debuild'
|
||||||
|
|
||||||
|
script {
|
||||||
|
def files = findFiles(glob: 'debuild/*.changes')
|
||||||
|
files.each { file -> env.CHANGES_FILE = file.name }
|
||||||
|
}
|
||||||
|
|
||||||
|
configFileProvider([
|
||||||
|
configFile(fileId: "dput.cf", variable: 'DPUT_CONFIG')
|
||||||
|
]) {
|
||||||
|
sshagent(credentials: ['jenkins-agent']) {
|
||||||
|
sh 'dput --config "$DPUT_CONFIG" verdnatura "debuild/$CHANGES_FILE"'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Deploy') {
|
||||||
|
when {
|
||||||
|
anyOf {
|
||||||
|
branch 'master'
|
||||||
|
branch 'test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
environment {
|
||||||
|
CREDS = credentials('docker-registry')
|
||||||
|
IMAGE = "$REGISTRY/verdnatura/hedera-web"
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def packageJson = readJSON file: 'package.json'
|
||||||
|
env.VERSION = "${packageJson.version}"
|
||||||
|
env.TAG = "${packageJson.version}-build${env.BUILD_ID}"
|
||||||
|
}
|
||||||
|
|
||||||
|
sh 'docker-compose build --build-arg BUILD_ID=$BUILD_ID --parallel'
|
||||||
|
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
|
||||||
|
sh 'docker push $IMAGE:$TAG'
|
||||||
|
|
||||||
|
script {
|
||||||
|
if (env.BRANCH_NAME == 'master') {
|
||||||
|
sh 'docker tag $IMAGE:$TAG $IMAGE:latest'
|
||||||
|
sh 'docker push $IMAGE:latest'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
withKubeConfig([
|
||||||
|
serverUrl: "$KUBERNETES_API",
|
||||||
|
credentialsId: 'kubernetes',
|
||||||
|
namespace: 'salix'
|
||||||
|
]) {
|
||||||
|
sh 'kubectl set image deployment/hedera-web-$BRANCH_NAME hedera-web-$BRANCH_NAME=$IMAGE:$TAG'
|
||||||
|
sh 'kubectl set image deployment/hedera-web-cron-$BRANCH_NAME hedera-web-cron-$BRANCH_NAME=$IMAGE:$TAG'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
unsuccessful {
|
||||||
|
setEnv()
|
||||||
|
sendEmail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
README.md
57
README.md
|
@ -1,3 +1,58 @@
|
||||||
# Hedera
|
# Hedera
|
||||||
|
|
||||||
Hedera is the main page for Verdnatura.
|
Hedera is the main web shop page for Verdnatura.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Required applications.
|
||||||
|
* PHP >= 8.4
|
||||||
|
* Node.js >= 20.0
|
||||||
|
|
||||||
|
Take a look to *debian/control* file to see additional dependencies.
|
||||||
|
|
||||||
|
Copy config.php to *config.my.php* and place your DB config there.
|
||||||
|
|
||||||
|
### Installing dependencies and launching
|
||||||
|
|
||||||
|
Pull from repository.
|
||||||
|
|
||||||
|
Run this commands on project root directory to install Node dependencies.
|
||||||
|
```
|
||||||
|
$ npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
Install project dependences (debian/control).
|
||||||
|
|
||||||
|
Pull from repository [php-vn-lib](https://gitea.verdnatura.es/verdnatura/php-vn-lib) and install [dependences](https://gitea.verdnatura.es/verdnatura/php-vn-lib/src/branch/master/debian/control) of this project.
|
||||||
|
|
||||||
|
Configure config.php file.
|
||||||
|
|
||||||
|
Launch project fronted.
|
||||||
|
```
|
||||||
|
$ npm run front
|
||||||
|
```
|
||||||
|
|
||||||
|
Launch salix backend.
|
||||||
|
```
|
||||||
|
$ npm run db
|
||||||
|
$ npm run back
|
||||||
|
```
|
||||||
|
Launch project backend.
|
||||||
|
```
|
||||||
|
$ php -S 127.0.0.1:3001 -t . index.php
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command line
|
||||||
|
|
||||||
|
Run server side method from command line.
|
||||||
|
```
|
||||||
|
$ php hedera-web.php -m method_path
|
||||||
|
```
|
||||||
|
|
||||||
|
## Built with
|
||||||
|
|
||||||
|
* [nodejs](https://nodejs.org/)
|
||||||
|
* [php](https://www.php.net/)
|
||||||
|
* [Webpack](https://webpack.js.org/)
|
||||||
|
* [MooTools](https://mootools.net/)
|
||||||
|
* [TinyMCE](https://www.tinymce.com/)
|
||||||
|
|
|
@ -1,14 +1,22 @@
|
||||||
# Alias /hedera-web /usr/share/hedera-web/
|
|
||||||
# Alias /image-db /var/lib/hedera-web/image-db/
|
|
||||||
|
|
||||||
<IfModule mod_mime.c>
|
<IfModule mod_mime.c>
|
||||||
AddType text/x-yaml .yml
|
AddType text/x-yaml .yml
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
|
<IfModule mpm_prefork_module>
|
||||||
|
ServerLimit 30
|
||||||
|
MaxRequestWorkers 30
|
||||||
|
MaxRequestsPerChild 1000
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<VirtualHost *:80>
|
||||||
|
DocumentRoot /usr/share/hedera-web/
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
<Directory /usr/share/hedera-web/>
|
<Directory /usr/share/hedera-web/>
|
||||||
Options -Indexes -FollowSymLinks
|
Options -Indexes -FollowSymLinks
|
||||||
AllowOverride None
|
AllowOverride None
|
||||||
Require all granted
|
Require all granted
|
||||||
|
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
|
||||||
|
|
||||||
<FilesMatch "\.(css|js|json|yml|php|xml|html|svg)$">
|
<FilesMatch "\.(css|js|json|yml|php|xml|html|svg)$">
|
||||||
SetOutputFilter DEFLATE
|
SetOutputFilter DEFLATE
|
||||||
|
@ -16,13 +24,7 @@
|
||||||
|
|
||||||
<FilesMatch "\.(ttf|otf|eot|woff)$">
|
<FilesMatch "\.(ttf|otf|eot|woff)$">
|
||||||
<IfModule mod_headers.c>
|
<IfModule mod_headers.c>
|
||||||
Header set Access-Control-Allow-Origin "*"
|
Header set Access-Control-Allow-Origin "*"
|
||||||
</IfModule>
|
</IfModule>
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
<Directory /var/lib/hedera-web/image-db/>
|
|
||||||
Options Indexes FollowSymLinks MultiViews
|
|
||||||
AllowOverride FileInfo Options
|
|
||||||
Require all granted
|
|
||||||
</Directory>
|
|
84
app.js
84
app.js
|
@ -1,71 +1,41 @@
|
||||||
|
__webpack_public_path__ = _PUBLIC_PATH;
|
||||||
|
|
||||||
var assetsPath;
|
import 'promise-polyfill/src/polyfill';
|
||||||
|
import 'hedera/hedera';
|
||||||
|
const locales = require('./import').locales;
|
||||||
|
const packageJson = require('./package.json');
|
||||||
|
|
||||||
if (_DEV_MODE)
|
window.onload = function() {
|
||||||
{
|
loadLocale(main);
|
||||||
var host = window.location.host.split(':')[0];
|
|
||||||
assetsPath = 'http://'+ host +':'+ _DEV_SERVER_PORT +'/'+ _PUBLIC_PATH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
assetsPath = _PUBLIC_PATH;
|
|
||||||
|
|
||||||
__webpack_public_path__ = assetsPath;
|
|
||||||
|
|
||||||
require ('hedera/hedera');
|
|
||||||
|
|
||||||
window.onload = function ()
|
|
||||||
{
|
|
||||||
loadLocale (main);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function main (req)
|
function main() {
|
||||||
{
|
Vn.setVersion(packageJson.version);
|
||||||
if (req)
|
const hederaWeb = new Hedera.App();
|
||||||
onLocaleLoad (req);
|
window.hederaWeb = hederaWeb;
|
||||||
|
hederaWeb.run();
|
||||||
hederaWeb = new Hedera.App ();
|
|
||||||
hederaWeb.run ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadLocale (cb)
|
function loadLocale(callback) {
|
||||||
{
|
Vn.Locale.init();
|
||||||
Vn.Locale.init ();
|
|
||||||
var lang = Vn.Locale.language;
|
var lang = Vn.Locale.language;
|
||||||
|
|
||||||
var req = require.context ('js', true, /locale\/en.yml$/);
|
var req = require.context('js', true, /locale\/en.yml$/);
|
||||||
onLocaleLoad (req);
|
onLocaleLoad(Vn.Locale.fallbackLang, req);
|
||||||
|
|
||||||
switch (lang)
|
const loadFn = locales[lang];
|
||||||
{
|
if (loadFn)
|
||||||
case 'ca':
|
loadFn(function(req) {
|
||||||
require ([], function () {
|
onLocaleLoad(lang, req);
|
||||||
cb (require.context ('js', true, /locale\/ca.yml$/)); });
|
callback();
|
||||||
break;
|
});
|
||||||
case 'es':
|
else
|
||||||
require ([], function () {
|
callback();
|
||||||
cb (require.context ('js', true, /locale\/es.yml$/)); });
|
|
||||||
break;
|
|
||||||
case 'fr':
|
|
||||||
require ([], function () {
|
|
||||||
cb (require.context ('js', true, /locale\/fr.yml$/)); });
|
|
||||||
break;
|
|
||||||
case 'mn':
|
|
||||||
require ([], function () {
|
|
||||||
cb (require.context ('js', true, /locale\/mn.yml$/)); });
|
|
||||||
break;
|
|
||||||
case 'pt':
|
|
||||||
require ([], function () {
|
|
||||||
cb (require.context ('js', true, /locale\/pt.yml$/)); });
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cb ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onLocaleLoad (req)
|
function onLocaleLoad(lang, req) {
|
||||||
{
|
var keys = req.keys();
|
||||||
var keys = req.keys ();
|
|
||||||
|
|
||||||
for (var i = 0; i < keys.length; i++)
|
for (var i = 0; i < keys.length; i++)
|
||||||
Vn.Locale.add (req (keys[i]));
|
Vn.Locale.add(req(keys[i]), lang);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,18 +12,19 @@
|
||||||
*
|
*
|
||||||
* - http://www.mydomain.org -> config.www.php
|
* - http://www.mydomain.org -> config.www.php
|
||||||
* - http://test.mydomain.org -> config.test.php
|
* - http://test.mydomain.org -> config.test.php
|
||||||
|
*
|
||||||
|
* Put the password in base64.
|
||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
|
/**
|
||||||
/**
|
* Database parameters.
|
||||||
* Database parameters.
|
*/
|
||||||
**/
|
'db' => [
|
||||||
'db' => [
|
'host' => 'localhost'
|
||||||
'host' => 'localhost'
|
,'port' => 3306
|
||||||
,'port' => 3306
|
,'schema' => 'hedera'
|
||||||
,'schema' => 'hedera-web'
|
,'user' => 'hedera-web'
|
||||||
,'user' => 'hedera-web'
|
,'pass' => '' // base64 encoded
|
||||||
,'pass' => ''
|
,'tz' => 'Europe/madrid'
|
||||||
]
|
]
|
||||||
|
|
||||||
];
|
];
|
|
@ -1,4 +1,4 @@
|
||||||
hedera-web (1.405.78) stable; urgency=low
|
hedera-web (25.4.4) stable; urgency=low
|
||||||
|
|
||||||
* Initial Release.
|
* Initial Release.
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
9
|
10
|
|
@ -5,12 +5,12 @@ Build-Depends: build-essential, debhelper, nodejs
|
||||||
Standards-Version: 3.9.3
|
Standards-Version: 3.9.3
|
||||||
Section: misc
|
Section: misc
|
||||||
Homepage: https://verdnatura.es
|
Homepage: https://verdnatura.es
|
||||||
Vcs-Git: https://git.verdnatura.es/hedera-web
|
Vcs-Git: https://gitea.verdnatura.es/verdnatura/hedera-web
|
||||||
|
|
||||||
Package: hedera-web
|
Package: hedera-web
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: apache2 | httpd, nodejs, php5-cli, php5-mysql, php5-mcrypt, php5-ldap, php5-ssh2, php-vn-lib
|
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, php5-imap, tinymce
|
Suggests: php-image-text, php-text-captcha, php-zip, cron
|
||||||
Section: misc
|
Section: misc
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Description: Verdnatura's web page
|
Description: Verdnatura's web page
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Format: http://dep.debian.net/deps/dep5
|
Format: http://dep.debian.net/deps/dep5
|
||||||
Name: hedera-web
|
Name: hedera-web
|
||||||
Source: git://www.verdnatura.es/var/git/hedera-web
|
Source: https://gitea.verdnatura.es/verdnatura/hedera-web
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2011-2015 Juan Ferrer Toribio <juan@verdnatura.es>
|
Copyright: 2011-2015 Juan Ferrer Toribio <juan@verdnatura.es>
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
MAILTO=webmaster
|
MAILTO=webmaster
|
||||||
*/4 * * * * root hedera-web.php -m tpv/confirm-mail
|
*/1 * * * * root hedera-web.php -m misc/mail
|
||||||
*/2 * * * * root hedera-web.php -m edi/load
|
*/2 * * * * root hedera-web.php -m edi/load
|
||||||
0 23 * * * root hedera-web.php -m edi/clean
|
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 edi/update
|
||||||
*/1 * * * * root hedera-web.php -m misc/mail
|
0 0 * * * root hedera-web.php -m image/sync
|
||||||
0 5 * * * root hedera-web.php -m misc/exchange-rate
|
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,4 +1,6 @@
|
||||||
conf/* etc/hedera-web
|
apache.conf etc/hedera-web
|
||||||
|
config.php etc/hedera-web
|
||||||
|
php.ini etc/hedera-web
|
||||||
web usr/share/php/vn
|
web usr/share/php/vn
|
||||||
doc/* usr/share/doc/hedera-web
|
doc/* usr/share/doc/hedera-web
|
||||||
hedera-web.php usr/share/hedera-web
|
hedera-web.php usr/share/hedera-web
|
||||||
|
@ -8,8 +10,10 @@ js usr/share/hedera-web
|
||||||
pages usr/share/hedera-web
|
pages usr/share/hedera-web
|
||||||
reports usr/share/hedera-web
|
reports usr/share/hedera-web
|
||||||
rest usr/share/hedera-web
|
rest usr/share/hedera-web
|
||||||
|
utils usr/share/hedera-web
|
||||||
index.php usr/share/hedera-web
|
index.php usr/share/hedera-web
|
||||||
package.json usr/share/hedera-web
|
package.json usr/share/hedera-web
|
||||||
build usr/share/hedera-web
|
build usr/share/hedera-web
|
||||||
README.md usr/share/hedera-web
|
README.md usr/share/hedera-web
|
||||||
webpack.config.json usr/share/hedera-web
|
webpack.config.json usr/share/hedera-web
|
||||||
|
build-deps/node_modules usr/share/hedera-web
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
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/apache.conf etc/apache2/conf-available/hedera-web.conf
|
||||||
usr/share/hedera-web/hedera-web.php usr/bin/hedera-web.php
|
etc/hedera-web/php.ini etc/php/8.2/apache2/conf.d/99-hedera-web.ini
|
|
@ -2,14 +2,15 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
(cd /usr/share/hedera-web && npm install --production)
|
/usr/share/hedera-web/utils/update-browscap.sh > /dev/null
|
||||||
|
|
||||||
if [ -e /usr/share/apache2/apache2-maintscript-helper ]
|
if [ -e /usr/share/apache2/apache2-maintscript-helper ]
|
||||||
then
|
then
|
||||||
. /usr/share/apache2/apache2-maintscript-helper
|
. /usr/share/apache2/apache2-maintscript-helper
|
||||||
|
apache2_invoke enmod rewrite
|
||||||
|
apache2_invoke enmod headers
|
||||||
apache2_invoke enconf hedera-web.conf
|
apache2_invoke enconf hedera-web.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
service php5-fpm restart
|
#service php7.3-fpm restart
|
||||||
service cron restart
|
#service cron restart
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,5 @@ then
|
||||||
apache2_invoke disconf hedera-web.conf
|
apache2_invoke disconf hedera-web.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf /usr/share/hedera-web/node_modules
|
#rm -rf /usr/share/hedera-web/node_modules
|
||||||
service cron restart
|
#service cron restart
|
||||||
|
|
|
@ -6,9 +6,13 @@
|
||||||
dh $@
|
dh $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
npm --production run clean
|
npm run clean
|
||||||
dh_clean $@
|
dh_clean $@
|
||||||
|
|
||||||
build:
|
build:
|
||||||
npm --production run 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)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
hedera-web: package-contains-npm-ignore-file
|
|
@ -0,0 +1,9 @@
|
||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
main:
|
||||||
|
image: registry.verdnatura.es/verdnatura/hedera-web:${TAG:?}
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
- VERSION=${VERSION:?}
|
3
env.php
3
env.php
|
@ -2,12 +2,11 @@
|
||||||
|
|
||||||
require_once __DIR__.'/../php-vn-lib/env.php';
|
require_once __DIR__.'/../php-vn-lib/env.php';
|
||||||
|
|
||||||
set_include_path (__DIR__.PATH_SEPARATOR.get_include_path ());
|
set_include_path(__DIR__.PATH_SEPARATOR.get_include_path());
|
||||||
|
|
||||||
$vnAutoloadMap['vn/web'] = __DIR__.'/web';
|
$vnAutoloadMap['vn/web'] = __DIR__.'/web';
|
||||||
|
|
||||||
const _ENABLE_DEBUG = TRUE;
|
const _ENABLE_DEBUG = TRUE;
|
||||||
const _DEV_MODE = TRUE;
|
const _DEV_MODE = TRUE;
|
||||||
const _CONFIG_DIR = __DIR__.'/../../.config';
|
|
||||||
const _LOG_DIR = '/tmp';
|
const _LOG_DIR = '/tmp';
|
||||||
const _DATA_DIR = '/tmp';
|
const _DATA_DIR = '/tmp';
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
|
|
||||||
Hedera.AddressList = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,activate: function ()
|
|
||||||
{
|
|
||||||
this.$('user-model').setInfo ('c', 'myClient', 'hedera');
|
|
||||||
this.$('addresses').setInfo ('a', 'myAddress', 'hedera');
|
|
||||||
}
|
|
||||||
|
|
||||||
,onAddAddressClick: function ()
|
|
||||||
{
|
|
||||||
this.hash.set ({
|
|
||||||
form: 'account/address',
|
|
||||||
address: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
,onReturnClick: function ()
|
|
||||||
{
|
|
||||||
window.history.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onRemoveAddressClick: function (button, form)
|
|
||||||
{
|
|
||||||
if (confirm (_('AreYouSureDeleteAddress')))
|
|
||||||
{
|
|
||||||
form.set ('isActive', false);
|
|
||||||
form.refresh ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,onEditAddressClick: function (button, form)
|
|
||||||
{
|
|
||||||
this.hash.set ({
|
|
||||||
form: 'account/address',
|
|
||||||
address: form.get ('id')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
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,7 +1,8 @@
|
||||||
Addresses: Direccions
|
Addresses: Adreces
|
||||||
Return: Tornar
|
Return: Tornar
|
||||||
AddAddress: Afegir adreça
|
AddAddress: Afegir adreça
|
||||||
SetAsDefault: Establir com per defecte
|
SetAsDefault: Establir com per defecte
|
||||||
RemoveAddress: Esborrar direcció
|
RemoveAddress: Esborrar direcció
|
||||||
EditAddress: Modificar direcció
|
EditAddress: Modificar direcció
|
||||||
AreYouSureDeleteAddress: Estàs segur de que vols eliminar la direcció?
|
AreYouSureDeleteAddress: Estàs segur de que vols eliminar la direcció?
|
||||||
|
DefaultAddressModified: Adreça per defecte modificada
|
||||||
|
|
|
@ -5,3 +5,4 @@ SetAsDefault: Set as default
|
||||||
RemoveAddress: Remove address
|
RemoveAddress: Remove address
|
||||||
EditAddress: Edit address
|
EditAddress: Edit address
|
||||||
AreYouSureDeleteAddress: Are you sure you want to delete the address?
|
AreYouSureDeleteAddress: Are you sure you want to delete the address?
|
||||||
|
DefaultAddressModified: Default address modified
|
||||||
|
|
|
@ -5,3 +5,4 @@ SetAsDefault: Establecer como predeterminada
|
||||||
RemoveAddress: Borrar dirección
|
RemoveAddress: Borrar dirección
|
||||||
EditAddress: Modificar dirección
|
EditAddress: Modificar dirección
|
||||||
AreYouSureDeleteAddress: ¿Estás seguro de que quieres borrar la dirección?
|
AreYouSureDeleteAddress: ¿Estás seguro de que quieres borrar la dirección?
|
||||||
|
DefaultAddressModified: Dirección por defecto modificada
|
||||||
|
|
|
@ -5,3 +5,4 @@ SetAsDefault: Définir par défaut
|
||||||
RemoveAddress: Supprimer l'adresse
|
RemoveAddress: Supprimer l'adresse
|
||||||
EditAddress: Changement d'adresse
|
EditAddress: Changement d'adresse
|
||||||
AreYouSureDeleteAddress: Souhaitez-vous vraiment supprier l'adresse?
|
AreYouSureDeleteAddress: Souhaitez-vous vraiment supprier l'adresse?
|
||||||
|
DefaultAddressModified: Adresse par défaut modifiée
|
||||||
|
|
|
@ -5,3 +5,4 @@ SetAsDefault: Selecionar como pre-determinado
|
||||||
RemoveAddress: Eliminar Morada
|
RemoveAddress: Eliminar Morada
|
||||||
EditAddress: Modificar Morada
|
EditAddress: Modificar Morada
|
||||||
AreYouSureDeleteAddress: Tens certeza que queres eliminar esta morada?
|
AreYouSureDeleteAddress: Tens certeza que queres eliminar esta morada?
|
||||||
|
DefaultAddressModified: Endereço padrão modificado
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
|
|
||||||
.address-list
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.address-list .box
|
|
||||||
{
|
|
||||||
max-width: 30em;
|
|
||||||
}
|
|
||||||
.address-list .form
|
|
||||||
{
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 25em;
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
.address
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
border-bottom: 1px solid #DDD;
|
|
||||||
}
|
|
||||||
.address p
|
|
||||||
{
|
|
||||||
margin: 0.2em 0;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.address p.important
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
.address .actions
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
.address .actions > .htk-button
|
|
||||||
{
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.address .actions > *
|
|
||||||
{
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.address .actions > input
|
|
||||||
{
|
|
||||||
margin: .6em;
|
|
||||||
}
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
hedera-address-list {
|
||||||
|
.htk-list .side {
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,21 +2,16 @@
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<db-form id="user-form">
|
<db-form id="user-form">
|
||||||
<db-model property="model" id="user-model" updatable="true">
|
<db-model property="model" id="user-model" updatable="true">
|
||||||
<custom>
|
SELECT id, defaultAddressFk
|
||||||
SELECT id, defaultAddressFk
|
FROM myClient c
|
||||||
FROM myClient c
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
<db-model id="addresses" updatable="true">
|
<db-model id="addresses" updatable="true">
|
||||||
<custom>
|
SELECT a.id, a.nickname, p.name province, a.postalCode,
|
||||||
SELECT a.id, a.nickname, p.name province, a.postalCode,
|
a.city, a.street, a.isActive
|
||||||
a.city, a.street, a.isActive, c.country
|
FROM myAddress a
|
||||||
FROM myAddress a
|
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
||||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
WHERE a.isActive
|
||||||
JOIN vn.country c ON c.id = p.countryFk
|
|
||||||
WHERE a.isActive
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
|
@ -26,46 +21,47 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="add"
|
icon="add"
|
||||||
tip="_AddAddress"
|
tip="_AddAddress"
|
||||||
on-click="onAddAddressClick"/>
|
on-click="this.onAddAddressClick()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="address-list">
|
<div id="form" class="hedera-address-list">
|
||||||
<div class="box">
|
<div class="box vn-w-sm">
|
||||||
<htk-radio-group
|
<htk-radio-group
|
||||||
id="default-address"
|
id="default-address"
|
||||||
column="defaultAddressFk"
|
column="defaultAddressFk"
|
||||||
form="user-form"/>
|
form="user-form"/>
|
||||||
<htk-repeater model="addresses" form-id="iter">
|
<htk-repeater model="addresses" form-id="address" class="htk-list">
|
||||||
<custom>
|
<custom>
|
||||||
<div class="address">
|
<div class="item clickable" on-click="this.onSetDefaultClick($event, address.id)">
|
||||||
<div class="actions">
|
<div class="side">
|
||||||
<htk-radio
|
<htk-radio
|
||||||
form="iter"
|
|
||||||
column="id"
|
|
||||||
radio-group="default-address"
|
radio-group="default-address"
|
||||||
tip="_SetAsDefault"/>
|
val="{{address.id}}"
|
||||||
<htk-button
|
tip="_SetAsDefault"
|
||||||
form="iter"
|
name="test"/>
|
||||||
column="id"
|
</div>
|
||||||
tip="_RemoveAddress"
|
<div class="content">
|
||||||
icon="delete"
|
<p class="important">
|
||||||
on-click="onRemoveAddressClick"/>
|
{{address.nickname}}
|
||||||
<htk-button
|
</p>
|
||||||
form="iter"
|
<p>
|
||||||
column="id"
|
{{address.street}}
|
||||||
tip="_EditAddress"
|
</p>
|
||||||
icon="edit"
|
<p>
|
||||||
on-click="onEditAddressClick"/>
|
{{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>
|
||||||
<p class="important">
|
|
||||||
<htk-text form="iter" column="nickname"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="iter" column="street"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="iter" column="postalCode"/>,
|
|
||||||
<htk-text form="iter" column="city"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</custom>
|
</custom>
|
||||||
</htk-repeater>
|
</htk-repeater>
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
|
|
||||||
Hedera.Address = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,activate: function ()
|
|
||||||
{
|
|
||||||
this.$('model').setInfo ('a', 'myAddress', 'hedera', ['id'], 'id');
|
|
||||||
this.$('model').setDefault ('clientFk', 'a',
|
|
||||||
new Sql.Function ({schema: 'account', name: 'userGetId'}));
|
|
||||||
}
|
|
||||||
|
|
||||||
,onStatusChange: function (form)
|
|
||||||
{
|
|
||||||
if (form.ready && this.$('address').value == 0)
|
|
||||||
form.insertRow ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onOperationsDone: function ()
|
|
||||||
{
|
|
||||||
Htk.Toast.showMessage (_('AddressChangedSuccessfully'));
|
|
||||||
this.onReturnClick ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onAcceptClick: function ()
|
|
||||||
{
|
|
||||||
this.$('iter').performOperations ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onReturnClick: function ()
|
|
||||||
{
|
|
||||||
window.history.back();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
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,16 +0,0 @@
|
||||||
|
|
||||||
.address
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.address .box
|
|
||||||
{
|
|
||||||
max-width: 30em;
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
.address .form
|
|
||||||
{
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 25em;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,96 +1,86 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<vn-param id="address"/>
|
<vn-lot-query id="params">
|
||||||
<vn-hash-param key="address" param="address"/>
|
<vn-spec name="address" type="Number"/>
|
||||||
<db-form id="iter" on-status-changed="onStatusChange">
|
</vn-lot-query>
|
||||||
|
<db-form id="iter" on-status-changed="this.onStatusChange()">
|
||||||
<db-model
|
<db-model
|
||||||
id="model"
|
id="model"
|
||||||
property="model"
|
property="model"
|
||||||
updatable="true"
|
updatable="true"
|
||||||
mode="ON_DEMAND"
|
mode="ON_DEMAND"
|
||||||
on-operations-done="onOperationsDone">
|
lot="params"
|
||||||
<custom>
|
on-operations-done="this.onOperationsDone()">
|
||||||
SELECT a.id, a.street, a.nickname, a.city,
|
SELECT a.id, a.street, a.nickname, a.city,
|
||||||
a.postalCode, a.provinceFk, c.id countryFk
|
a.postalCode, a.provinceFk, p.countryFk
|
||||||
FROM myAddress a
|
FROM myAddress a
|
||||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
||||||
JOIN vn.country c ON c.id = p.countryFk
|
WHERE a.id = #address
|
||||||
WHERE a.id = #address
|
|
||||||
</custom>
|
|
||||||
<sql-batch property="batch">
|
|
||||||
<custom>
|
|
||||||
<item name="address" param="address"/>
|
|
||||||
</custom>
|
|
||||||
</sql-batch>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>AddEditAddress</t></h1>
|
<h1><t>Configuration</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="actions">
|
<div id="actions">
|
||||||
<htk-bar-button
|
|
||||||
icon="ok"
|
|
||||||
tip="_Accept"
|
|
||||||
on-click="onAcceptClick"/>
|
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="close"
|
icon="close"
|
||||||
tip="_Return"
|
tip="_Return"
|
||||||
on-click="onReturnClick"/>
|
on-click="window.history.back()"/>
|
||||||
|
<htk-bar-button
|
||||||
|
icon="check"
|
||||||
|
tip="_Accept"
|
||||||
|
on-click="iter.performOperations()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="address">
|
<div id="form" class="hedera-address">
|
||||||
<div class="box">
|
<div class="form box vn-w-sm vn-pa-lg">
|
||||||
<div class="form">
|
<h5 class="vn-mb-md">
|
||||||
<div class="form-group">
|
<t>AddEditAddress</t>
|
||||||
<label><t>Name</t></label>
|
</h5>
|
||||||
<htk-entry column="nickname" form="iter"/>
|
<div class="form-group">
|
||||||
</div>
|
<htk-entry
|
||||||
<div class="form-group">
|
placeholder="_Name"
|
||||||
<label><t>Address</t></label>
|
form="iter" column="nickname"/>
|
||||||
<htk-entry column="street" form="iter"/>
|
</div>
|
||||||
</div>
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<htk-entry
|
||||||
<label><t>City</t></label>
|
placeholder="_Address"
|
||||||
<htk-entry column="city" form="iter"/>
|
form="iter" column="street"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>ZipCode</t></label>
|
<htk-entry
|
||||||
<htk-entry column="postalCode" form="iter"/>
|
placeholder="_City"
|
||||||
</div>
|
form="iter" column="city"/>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label><t>Country</t></label>
|
<div class="form-group">
|
||||||
<htk-combo>
|
<htk-entry
|
||||||
<db-param
|
placeholder="_ZipCode"
|
||||||
id="country"
|
form="iter" column="postalCode"/>
|
||||||
property="param"
|
</div>
|
||||||
form="iter"
|
<div class="form-group">
|
||||||
column="countryFk"
|
<htk-combo
|
||||||
one-way="true"/>
|
placeholder="_Country"
|
||||||
<db-model property="model">
|
form="iter" column="countryFk"
|
||||||
<custom>
|
id="country"
|
||||||
SELECT id, country FROM vn.country
|
one-way="true"
|
||||||
ORDER BY country
|
one-time="true">
|
||||||
</custom>
|
<db-model property="model">
|
||||||
</db-model>
|
SELECT id, name FROM vn.country
|
||||||
</htk-combo>
|
ORDER BY name
|
||||||
</div>
|
</db-model>
|
||||||
<div class="form-group">
|
</htk-combo>
|
||||||
<label><t>Province</t></label>
|
</div>
|
||||||
<htk-combo column="provinceFk" form="iter">
|
<div class="form-group">
|
||||||
<db-model property="model">
|
<htk-combo
|
||||||
<custom>
|
placeholder="_Province"
|
||||||
SELECT id, name FROM vn.province
|
column="provinceFk"
|
||||||
WHERE countryFk = #country
|
form="iter">
|
||||||
ORDER BY name
|
<db-model property="model" lot="country">
|
||||||
</custom>
|
SELECT id, name FROM vn.province
|
||||||
<sql-batch property="batch">
|
WHERE countryFk = #id
|
||||||
<custom>
|
ORDER BY name
|
||||||
<item name="country" param="country"/>
|
</db-model>
|
||||||
</custom>
|
</htk-combo>
|
||||||
</sql-batch>
|
|
||||||
</db-model>
|
|
||||||
</htk-combo>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
|
|
||||||
Hedera.Conf = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,activate: function ()
|
|
||||||
{
|
|
||||||
this.$('user-model').setInfo ('c', 'myClient', 'hedera');
|
|
||||||
}
|
|
||||||
|
|
||||||
,onPassChangeClick: function ()
|
|
||||||
{
|
|
||||||
this.$('old-password').value = '';
|
|
||||||
this.$('new-password').value = '';
|
|
||||||
this.$('repeat-password').value = '';
|
|
||||||
|
|
||||||
var recoverPass = this.$('user-form').get ('recoverPass');
|
|
||||||
this.$('old-password').style.display = recoverPass ? 'none' : 'block';
|
|
||||||
this.$('change-password').show ();
|
|
||||||
|
|
||||||
if (recoverPass)
|
|
||||||
this.$('new-password').focus ();
|
|
||||||
else
|
|
||||||
this.$('old-password').focus ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onPassModifyClick: function ()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
var oldPassword = this.$('old-password').value;
|
|
||||||
var newPassword = this.$('new-password').value;
|
|
||||||
var repeatedPassword = this.$('repeat-password').value;
|
|
||||||
|
|
||||||
if (newPassword == '' && repeatedPassword == '')
|
|
||||||
throw new Error (_('Passwords empty'));
|
|
||||||
if (newPassword !== repeatedPassword)
|
|
||||||
throw new Error (_('Passwords doesn\'t match'));
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
oldPassword: oldPassword,
|
|
||||||
newPassword: newPassword
|
|
||||||
};
|
|
||||||
this.conn.send ('core/change-password', params,
|
|
||||||
this._onPassChange.bind (this));
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
Htk.Toast.showError (e.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,_onPassChange: function (json, error)
|
|
||||||
{
|
|
||||||
if (json)
|
|
||||||
{
|
|
||||||
this.$('change-password').hide ();
|
|
||||||
Htk.Toast.showMessage (_('Password changed!'));
|
|
||||||
this.$('user-form').refresh ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Htk.Toast.showError (error.message);
|
|
||||||
this.$('old-password').select ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,onPassInfoClick: function ()
|
|
||||||
{
|
|
||||||
this.$('password-info').show ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onAddressesClick: function ()
|
|
||||||
{
|
|
||||||
this.hash.set ({form: 'account/address-list'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
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');
|
||||||
|
this.$.changePassword.conn = this.conn
|
||||||
|
this.$.changePassword.user = this.gui.user
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,4 +1,5 @@
|
||||||
Configuration: Configuració
|
Configuration: Configuració
|
||||||
|
Personal information: Dades personals
|
||||||
Username: Nom d'usuari
|
Username: Nom d'usuari
|
||||||
Password: Contrasenya
|
Password: Contrasenya
|
||||||
Email: Correu electrònic
|
Email: Correu electrònic
|
||||||
|
@ -9,7 +10,7 @@ Receive invoices by email: Rebre factures per correu electrònic
|
||||||
Old password: Contrasenya antiga
|
Old password: Contrasenya antiga
|
||||||
New password: Nova contrasenya
|
New password: Nova contrasenya
|
||||||
Repeat password: Repetir contrasenya
|
Repeat password: Repetir contrasenya
|
||||||
Info: Info
|
Requirements: Requisits
|
||||||
Modify: Modificar
|
Modify: Modificar
|
||||||
Password requirements: Requisits de contrasenya
|
Password requirements: Requisits de contrasenya
|
||||||
characters long: caràcters de longitud
|
characters long: caràcters de longitud
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
Configuration: Configuration
|
Configuration: Configuration
|
||||||
|
Personal information: Personal information
|
||||||
Username: Username
|
Username: Username
|
||||||
Password: Password
|
Password: Password
|
||||||
Email: Email
|
Email: Email
|
||||||
|
@ -9,7 +10,7 @@ Receive invoices by email: Receive invoices by email
|
||||||
Old password: Old password
|
Old password: Old password
|
||||||
New password: New password
|
New password: New password
|
||||||
Repeat password: Repeat password
|
Repeat password: Repeat password
|
||||||
Info: Info
|
Requirements: Requirements
|
||||||
Modify: Modify
|
Modify: Modify
|
||||||
Password requirements: Password requirements
|
Password requirements: Password requirements
|
||||||
characters long: characters long
|
characters long: characters long
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
Configuration: Configuración
|
Configuration: Configuración
|
||||||
|
Personal information: Datos personales
|
||||||
Username: Nombre de usuario
|
Username: Nombre de usuario
|
||||||
Password: Contraseña
|
Password: Contraseña
|
||||||
Email: Correo electrónico
|
Email: Correo electrónico
|
||||||
|
@ -9,7 +10,7 @@ Receive invoices by email: Recibir facturas por correo electrónico
|
||||||
Old password: Contaseña antigua
|
Old password: Contaseña antigua
|
||||||
New password: Nueva contraseña
|
New password: Nueva contraseña
|
||||||
Repeat password: Repetir contraseña
|
Repeat password: Repetir contraseña
|
||||||
Info: Info
|
Requirements: Requisitos
|
||||||
Modify: Modificar
|
Modify: Modificar
|
||||||
Password requirements: Requisitos de constraseña
|
Password requirements: Requisitos de constraseña
|
||||||
characters long: carácteres de longitud
|
characters long: carácteres de longitud
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
Configuration: Configuration
|
Configuration: Configuration
|
||||||
|
Personal information: Informations personnelles
|
||||||
Username: Utilisateur
|
Username: Utilisateur
|
||||||
Password: Mot de passe
|
Password: Mot de passe
|
||||||
Email: Courriel
|
Email: Courriel
|
||||||
|
@ -9,7 +10,7 @@ Receive invoices by email: Recevoir des factures par e-mail
|
||||||
Old password: Ancien mot de passe
|
Old password: Ancien mot de passe
|
||||||
New password: Nouveau mot de passe
|
New password: Nouveau mot de passe
|
||||||
Repeat password: Répéter le mot de passe
|
Repeat password: Répéter le mot de passe
|
||||||
Info: Info
|
Requirements: Exigences
|
||||||
Modify: Modifier
|
Modify: Modifier
|
||||||
Password requirements: Mot de passe exigences
|
Password requirements: Mot de passe exigences
|
||||||
characters long: Longs caractères
|
characters long: Longs caractères
|
||||||
|
|
|
@ -1,25 +1,26 @@
|
||||||
Configuration: Configuração
|
Configuration: Configuração
|
||||||
|
Personal information: Dados pessoais
|
||||||
Username: Nome de usuario
|
Username: Nome de usuario
|
||||||
Password: Palavra-Passe
|
Password: Palavra-passe
|
||||||
Email: E-Mail
|
Email: E-Mail
|
||||||
Display name: Nome para mostrar
|
Display name: Nome para mostrar
|
||||||
Language: Idioma
|
Language: Idioma
|
||||||
Billing: Facturação
|
Billing: Facturação
|
||||||
Receive invoices by email: Receber facturas por e-mail
|
Receive invoices by email: Receber facturas por e-mail
|
||||||
Old password: Palavra-Passe antiga
|
Old password: Palavra-passe antiga
|
||||||
New password: Nova Palavra-Passe
|
New password: Nova Palavra-passe
|
||||||
Repeat password: Repetir Palavra-Passe
|
Repeat password: Repetir Palavra-passe
|
||||||
Info: Info
|
Requirements: Requisitos
|
||||||
Modify: Modificar
|
Modify: Modificar
|
||||||
Password requirements: Requisitos de Palavra-Passe
|
Password requirements: Requisitos de Palavra-passe
|
||||||
characters long: caracteres
|
characters long: caracteres
|
||||||
alphabetic characters: caracteres alfabéticos
|
alphabetic characters: caracteres alfabéticos
|
||||||
capital letters: letras maiúsculas
|
capital letters: letras maiúsculas
|
||||||
digits: dígitos
|
digits: dígitos
|
||||||
symbols: 'símbolos. Ej: $%&.'
|
symbols: 'símbolos. Ej: $%&.'
|
||||||
Password changed!: Palavra-Passe Modificada!
|
Password changed!: Palavra-passe Modificada!
|
||||||
Password doesn't meet the requirements: Palavra-Passe não atende aos requisitos
|
Password doesn't meet the requirements: Palavra-passe não atende aos requisitos
|
||||||
Passwords doesn't match: As Palavras-Passe não coincidem!
|
Passwords doesn't match: As Palavras-Passe não coincidem!
|
||||||
Passwords empty: Palavra-Passe vazia
|
Passwords empty: Palavra-passe vazia
|
||||||
Addresses: Moradas
|
Addresses: Moradas
|
||||||
Change password: Mudar Palavra-Passe
|
Change password: Mudar Palavra-passe
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
|
|
||||||
.conf
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.conf .box
|
|
||||||
{
|
|
||||||
max-width: 30em;
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
.conf .form
|
|
||||||
{
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 25em;
|
|
||||||
}
|
|
||||||
.conf .form-group input[type=password]
|
|
||||||
{
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pass-change
|
|
||||||
{
|
|
||||||
max-width: 15em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pass-info
|
|
||||||
{
|
|
||||||
width: 15em;
|
|
||||||
}
|
|
||||||
.pass-info ul
|
|
||||||
{
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
.pass-info ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
|
@ -1,22 +1,12 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<db-form id="password-form">
|
|
||||||
<db-model property="model">
|
|
||||||
<custom>
|
|
||||||
SELECT length, nAlpha, nUpper, nDigits, nPunct
|
|
||||||
FROM account.userPassword
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
|
||||||
</db-form>
|
|
||||||
<db-form id="user-form">
|
<db-form id="user-form">
|
||||||
<db-model property="model" id="user-model" updatable="true">
|
<db-model property="model" id="user-model" updatable="true">
|
||||||
<custom>
|
SELECT u.id, u.name, u.email, u.nickname,
|
||||||
SELECT u.id, u.name, u.email, u.recoverPass,
|
u.lang, c.isToBeMailed, c.id clientFk
|
||||||
u.nickname, u.lang, c.isToBeMailed, c.id clientFk
|
FROM account.myUser u
|
||||||
FROM account.userView u
|
LEFT JOIN myClient c
|
||||||
LEFT JOIN myClient c
|
ON u.id = c.id
|
||||||
ON u.id = c.id
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
|
@ -27,102 +17,56 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="place"
|
icon="place"
|
||||||
tip="_Addresses"
|
tip="_Addresses"
|
||||||
on-click="onAddressesClick"/>
|
on-click="hash.setAll({form: 'account/address-list'})"/>
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="preferences"
|
icon="lock_reset"
|
||||||
tip="_Change password"
|
tip="_Change password"
|
||||||
on-click="onPassChangeClick"/>
|
on-click="this.$.changePassword.open()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="conf">
|
<div id="form" class="conf">
|
||||||
<div class="box">
|
<div class="form box vn-w-sm vn-pa-lg">
|
||||||
<div class="form">
|
<h5 class="vn-mb-md">
|
||||||
<div class="form-group">
|
<t>Personal information</t>
|
||||||
<label for="user-name"><t>Username</t></label>
|
</h5>
|
||||||
<htk-text form="user-form" column="name"/>
|
<div class="form-group">
|
||||||
</div>
|
<htk-entry
|
||||||
<div class="form-group">
|
placeholder="_Username"
|
||||||
<label for="email"><t>Email</t></label>
|
disabled="true"
|
||||||
<htk-entry form="user-form" column="email"></htk-entry>
|
form="user-form"
|
||||||
</div>
|
column="name"/>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="nickname"><t>Display name</t></label>
|
<div class="form-group">
|
||||||
<htk-entry form="user-form" column="nickname"/>
|
<htk-entry
|
||||||
</div>
|
placeholder="_Email"
|
||||||
<div class="form-group">
|
form="user-form"
|
||||||
<label for="lang"><t>Language</t></label>
|
column="email">
|
||||||
<htk-combo form="user-form" column="lang">
|
</htk-entry>
|
||||||
<db-model property="model">
|
</div>
|
||||||
<custom>
|
<div class="form-group">
|
||||||
SELECT code, name FROM language WHERE isActive
|
<htk-entry
|
||||||
</custom>
|
placeholder="_Display name"
|
||||||
</db-model>
|
form="user-form"
|
||||||
</htk-combo>
|
column="nickname"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="mail"><t>Receive invoices by email</t></label>
|
<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"/>
|
<htk-check form="user-form" column="isToBeMailed"/>
|
||||||
</div>
|
<t>Receive invoices by email</t>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<htk-popup
|
<htk-change-password id="change-password"/>
|
||||||
id="change-password"
|
|
||||||
modal="true">
|
|
||||||
<div property="child-node" class="htk-dialog pass-change">
|
|
||||||
<div>
|
|
||||||
<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="onPassModifyClick">
|
|
||||||
<t>Modify</t>
|
|
||||||
</button>
|
|
||||||
<button class="thin" on-click="onPassInfoClick">
|
|
||||||
<t>Info</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">
|
|
||||||
<h3>
|
|
||||||
<t>Password requirements</t>
|
|
||||||
</h3>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<htk-text form="password-form" column="length"/>
|
|
||||||
<t>characters long</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<htk-text form="password-form" column="nAlpha"/>
|
|
||||||
<t>alphabetic characters</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<htk-text form="password-form" column="nUpper"/>
|
|
||||||
<t>capital letters</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<htk-text form="password-form" column="nDigits"/>
|
|
||||||
<t>digits</t>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<htk-text form="password-form" column="nPunct"/>
|
|
||||||
<t>symbols</t>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</htk-popup>
|
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
Hedera.AccessLog = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default new Class({
|
||||||
|
Extends: Hedera.Form,
|
||||||
|
Template: require('./ui.xml')
|
||||||
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
AccessLog: Registro de acessos
|
AccessLog: Registro de acessos
|
||||||
'UserNumber:': 'Nº usuario:'
|
'UserNumber:': 'Nº utilizador:'
|
||||||
'User:': 'Usuario:'
|
'User:': 'Utilizador:'
|
||||||
'Phone:': 'Telefone:'
|
'Phone:': 'Telefone:'
|
||||||
'Mobile:': 'Telemóvel:'
|
'Mobile:': 'Telemóvel:'
|
||||||
Access: Acceso
|
Access: Acceso
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
.access-log
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.access-log .box
|
|
||||||
{
|
|
||||||
max-width: 25em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.access-log .form
|
|
||||||
{
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
.access-log .form > p
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
margin: .1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List */
|
|
||||||
|
|
||||||
.access-log .list
|
|
||||||
{
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
.access-log .item
|
|
||||||
{
|
|
||||||
display: block;
|
|
||||||
padding: 1em;
|
|
||||||
border-bottom: 1px solid #DDD;
|
|
||||||
}
|
|
||||||
.access-log .item > p
|
|
||||||
{
|
|
||||||
margin: .1em 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
.access-log .form > p {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin: .1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List */
|
||||||
|
|
||||||
|
.access-log .htk-list {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
<vn-group>
|
||||||
<vn-param id="user"/>
|
<db-form v-model="user">
|
||||||
<vn-hash-param key="user" param="user"/>
|
<db-model property="model" lot="hash">
|
||||||
<db-form id="user-form">
|
SELECT u.id, u.name user, u.nickname, u.email, c.phone, r.name role
|
||||||
<db-model property="model">
|
FROM account.user u
|
||||||
<custom>
|
JOIN account.role r ON r.id = u.role
|
||||||
SELECT Id_Cliente, Cliente, Telefono, movil
|
LEFT JOIN vn.client c ON c.id = u.id
|
||||||
FROM vn2008.Clientes WHERE Id_Cliente = #user
|
WHERE u.id = #user
|
||||||
</custom>
|
|
||||||
<sql-batch property="batch">
|
|
||||||
<custom>
|
|
||||||
<item name="user" param="user"/>
|
|
||||||
</custom>
|
|
||||||
</sql-batch>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
</db-form>
|
</db-form>
|
||||||
</vn-group>
|
</vn-group>
|
||||||
|
@ -20,55 +14,37 @@
|
||||||
<h1><t>AccessLog</t></h1>
|
<h1><t>AccessLog</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="access-log">
|
<div id="form" class="access-log">
|
||||||
<div class="box">
|
<div class="box vn-w-xs vn-pa-lg">
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<p>
|
<h4>{{user.nickname}}</h4>
|
||||||
<htk-text form="user-form" column="Id_Cliente"/>
|
<p>#{{user.id}} - {{user.user}}</p>
|
||||||
</p>
|
<p>{{user.role}}</p>
|
||||||
<p>
|
<p>{{user.email}}</p>
|
||||||
<htk-text form="user-form" column="Cliente"/>
|
<p>{{user.phone}}</p>
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="user-form" column="Telefono"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="user-form" column="movil"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="list box">
|
|
||||||
<div>
|
|
||||||
<htk-repeater form-id="iter">
|
|
||||||
<db-model property="model">
|
|
||||||
<custom>
|
|
||||||
SELECT u.stamp, a.platform, a.browser, a.version, a.javascript, a.cookies
|
|
||||||
FROM visitUser u
|
|
||||||
JOIN visitAccess c ON c.id = u.access
|
|
||||||
JOIN visitAgent a ON a.id = c.agent
|
|
||||||
WHERE u.user = #user
|
|
||||||
ORDER BY u.stamp DESC
|
|
||||||
LIMIT 8
|
|
||||||
</custom>
|
|
||||||
<sql-batch property="batch">
|
|
||||||
<custom>
|
|
||||||
<item name="user" param="user"/>
|
|
||||||
</custom>
|
|
||||||
</sql-batch>
|
|
||||||
</db-model>
|
|
||||||
<custom>
|
|
||||||
<div class="item">
|
|
||||||
<p>
|
|
||||||
<htk-text form="iter" column="stamp" format="_%a, %e %b %Y at %T"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="iter" column="platform"/> -
|
|
||||||
<htk-text form="iter" column="browser"/>
|
|
||||||
<htk-text form="iter" column="version"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</custom>
|
|
||||||
</htk-repeater>
|
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
Hedera.Connections = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,_timeoutId: null
|
|
||||||
|
|
||||||
,onModelStatusChange: function (model, status)
|
|
||||||
{
|
|
||||||
if (!model.ready)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this._timeoutId)
|
|
||||||
clearTimeout (this._timeoutId);
|
|
||||||
|
|
||||||
this._timeoutId = setTimeout (this.onRefreshClick.bind (this), 60000);
|
|
||||||
}
|
|
||||||
|
|
||||||
,deactivate: function ()
|
|
||||||
{
|
|
||||||
clearTimeout (this._timeoutId);
|
|
||||||
}
|
|
||||||
|
|
||||||
,onRefreshClick: function ()
|
|
||||||
{
|
|
||||||
this.$('sessions').refresh ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onAccessLogClick: function (button, form)
|
|
||||||
{
|
|
||||||
this.hash.set ({
|
|
||||||
'form': 'admin/access-log'
|
|
||||||
,'user': form.get ('userId')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
,onChangeUserClick: function (button, form)
|
|
||||||
{
|
|
||||||
this.gui.supplantUser (form.get ('user'),
|
|
||||||
this._onUserSupplant.bind (this));
|
|
||||||
}
|
|
||||||
|
|
||||||
,_onUserSupplant: function (userName)
|
|
||||||
{
|
|
||||||
this.hash.set ({'form': 'ecomerce/orders'});
|
|
||||||
}
|
|
||||||
|
|
||||||
,sessionsFunc: function ()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
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,44 +0,0 @@
|
||||||
.connections
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.connections .box
|
|
||||||
{
|
|
||||||
max-width: 25em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.action-bar .connections-sum
|
|
||||||
{
|
|
||||||
padding: .4em;
|
|
||||||
margin-top: .9em;
|
|
||||||
margin-right: .5em;
|
|
||||||
background-color: #1e88e5;
|
|
||||||
border-radius: 0.1em;
|
|
||||||
box-shadow: 0 0 0.4em #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List */
|
|
||||||
|
|
||||||
.connections .item
|
|
||||||
{
|
|
||||||
display: block;
|
|
||||||
padding: 1em;
|
|
||||||
border-bottom: 1px solid #DDD;
|
|
||||||
}
|
|
||||||
.connections .item > button
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.connections .item > p
|
|
||||||
{
|
|
||||||
margin: .1em 0;
|
|
||||||
}
|
|
||||||
.connections .item > p.important
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
.action-bar .connections-sum {
|
||||||
|
padding: .4em;
|
||||||
|
background-color: #1e88e5;
|
||||||
|
border-radius: .1em;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="refresh"
|
icon="refresh"
|
||||||
tip="_Refresh"
|
tip="_Refresh"
|
||||||
on-click="onRefreshClick"/>
|
on-click="sessions.refresh()"/>
|
||||||
<div class="connections-sum">
|
<div class="connections-sum">
|
||||||
<htk-text>
|
<htk-text>
|
||||||
<db-calc-sum
|
<db-calc-sum
|
||||||
|
@ -18,50 +18,46 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="connections">
|
<div id="form" class="connections">
|
||||||
<div class="box">
|
<htk-repeater form-id="iter" class="box htk-list vn-w-xs">
|
||||||
<htk-repeater form-id="iter">
|
<db-model
|
||||||
<db-model property="model" id="sessions" on-status-changed="onModelStatusChange">
|
property="model"
|
||||||
<custom>
|
id="sessions"
|
||||||
SELECT vu.user userId, vu.stamp, u.nickname, s.lastUpdate,
|
on-status-changed="this.onModelStatusChange()">
|
||||||
a.platform, a.browser, a.version, u.name user
|
SELECT vu.userFk userId, vu.stamp, u.nickname, s.lastUpdate,
|
||||||
FROM userSession s
|
a.platform, a.browser, a.version, u.name user
|
||||||
JOIN visitUser vu ON vu.id = s.userVisit
|
FROM userSession s
|
||||||
JOIN visitAccess ac ON ac.id = vu.access
|
JOIN visitUser vu ON vu.id = s.userVisitFk
|
||||||
JOIN visitAgent a ON a.id = ac.agent
|
JOIN visitAccess ac ON ac.id = vu.accessFk
|
||||||
JOIN visit v ON v.id = a.visit
|
JOIN visitAgent a ON a.id = ac.agentFk
|
||||||
JOIN account.user u ON u.id = vu.user
|
JOIN visit v ON v.id = a.visitFk
|
||||||
ORDER BY lastUpdate DESC
|
JOIN account.user u ON u.id = vu.userFk
|
||||||
</custom>
|
ORDER BY lastUpdate DESC
|
||||||
</db-model>
|
</db-model>
|
||||||
<custom>
|
<custom>
|
||||||
<div class="item">
|
<a class="item"
|
||||||
<htk-button
|
href="{{`#!form=admin/access-log&user=${iter.userId}`}}"
|
||||||
form="iter"
|
title="_Access log">
|
||||||
column="id"
|
<div class="content">
|
||||||
tip="_Supplant user"
|
|
||||||
icon="incognito"
|
|
||||||
on-click="onChangeUserClick"/>
|
|
||||||
<htk-button
|
|
||||||
form="iter"
|
|
||||||
column="id"
|
|
||||||
tip="_Access log"
|
|
||||||
icon="gnome"
|
|
||||||
on-click="onAccessLogClick"/>
|
|
||||||
<p class="important">
|
<p class="important">
|
||||||
<htk-text form="iter" column="nickname"/>
|
{{iter.nickname}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<htk-text form="iter" column="stamp" format="%a, %T"/> -
|
{{Vn.Value.format(iter.stamp, '%a, %T')}} -
|
||||||
<htk-text form="iter" column="lastUpdate" format="%T"/>
|
{{Vn.Value.format(iter.lastUpdate, '%T')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<htk-text form="iter" column="platform"/> -
|
{{iter.platform}} - {{iter.browser}} {{iter.version}}
|
||||||
<htk-text form="iter" column="browser"/>
|
|
||||||
<htk-text form="iter" column="version"/>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</custom>
|
<div class="actions"
|
||||||
</htk-repeater>
|
on-click="$event.preventDefault()">
|
||||||
</div>
|
<htk-button
|
||||||
|
tip="_Supplant user"
|
||||||
|
icon="supervisor_account"
|
||||||
|
on-click="this.onChangeUserClick(iter.user)"/>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</custom>
|
||||||
|
</htk-repeater>
|
||||||
</div>
|
</div>
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default new Class({
|
||||||
|
Extends: Hedera.Form,
|
||||||
|
Template: require('./ui.xml'),
|
||||||
|
|
||||||
|
activate() {
|
||||||
|
this.$.items.setInfo('i', 'item', 'vn', ['id']);
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
Hedera.Items = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
.items
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.items .box
|
|
||||||
{
|
|
||||||
max-width: 25em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Row */
|
|
||||||
|
|
||||||
.items .row
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
border-bottom: 1px solid #DDD;
|
|
||||||
}
|
|
||||||
.items .row > .photo
|
|
||||||
{
|
|
||||||
margin-right: 1em;
|
|
||||||
float: left;
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 3.2em;
|
|
||||||
width: 3.2em;
|
|
||||||
}
|
|
||||||
.items .row > p
|
|
||||||
{
|
|
||||||
margin: .1em 0;
|
|
||||||
margin-left: 5em;
|
|
||||||
}
|
|
||||||
.items .row > p.important
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Topbar */
|
|
||||||
|
|
||||||
.action-bar .htk-search-entry
|
|
||||||
{
|
|
||||||
margin: .8em .6em;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
.items .item .photo {
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 80px;
|
||||||
|
width: 80px;
|
||||||
|
}
|
|
@ -1,58 +1,57 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
|
||||||
<vn-param id="filter"/>
|
|
||||||
<vn-hash-param key="filter" param="filter"/>
|
|
||||||
</vn-group>
|
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>Items</t></h1>
|
<h1><t>Items</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="actions">
|
<div id="actions">
|
||||||
<htk-search-entry
|
<htk-search-entry form="hash" column="search"/>
|
||||||
param="filter"/>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="items">
|
<div id="form" class="items">
|
||||||
<div class="rows box">
|
<htk-repeater
|
||||||
<htk-repeater form-id="iter" empty-message="_Enter a search term">
|
class="htk-list rows box vn-w-xs"
|
||||||
<db-model property="model">
|
form-id="iter"
|
||||||
<custom>
|
empty-message="_Enter a search term">
|
||||||
SELECT Id_Article, Article, Medida, Categoria, Foto
|
<db-model property="model" id="items" lot="hash">
|
||||||
FROM vn2008.Articles
|
SELECT i.id, i.longName, i.size, i.category,
|
||||||
WHERE Article LIKE CONCAT('%', #filter, '%')
|
i.value5, i.value6, i.value7,
|
||||||
OR Id_Article = #filter
|
i.image, im.updated
|
||||||
ORDER BY Article LIMIT 50
|
FROM vn.item i
|
||||||
</custom>
|
LEFT JOIN image im
|
||||||
<sql-batch property="batch">
|
ON im.collectionFk = 'catalog'
|
||||||
<custom>
|
AND im.name = i.image
|
||||||
<item name="filter" param="filter"/>
|
WHERE i.isActive
|
||||||
</custom>
|
AND (i.longName LIKE CONCAT('%', #search, '%') OR i.id = #search)
|
||||||
</sql-batch>
|
ORDER BY i.longName LIMIT 50
|
||||||
</db-model>
|
</db-model>
|
||||||
<custom>
|
<custom>
|
||||||
<div class="row">
|
<div class="item">
|
||||||
|
<div class="side vn-mr-md">
|
||||||
<htk-image
|
<htk-image
|
||||||
form="iter"
|
form="$iter"
|
||||||
column="Foto"
|
column="image"
|
||||||
|
stamp-column="updated"
|
||||||
class="photo"
|
class="photo"
|
||||||
directory="catalog"
|
directory="catalog"
|
||||||
subdir="200x200"
|
subdir="200x200"
|
||||||
full-dir="900x900"
|
full-dir="1600x900"
|
||||||
editable="true"
|
editable="true"
|
||||||
conn="conn"/>
|
conn="conn"/>
|
||||||
<p class="concept">
|
|
||||||
<htk-text form="iter" column="Article"/>
|
|
||||||
<htk-text form="iter" column="Medida"/>
|
|
||||||
<htk-text form="iter" column="Categoria"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="iter" column="Id_Article"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="iter" column="Foto"/>
|
|
||||||
</p>
|
|
||||||
<div class="clear"/>
|
|
||||||
</div>
|
</div>
|
||||||
</custom>
|
<div class="content">
|
||||||
</htk-repeater>
|
<p class="important">
|
||||||
</div>
|
{{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>
|
</div>
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default new Class({
|
||||||
|
Extends: Hedera.Form,
|
||||||
|
Template: require('./ui.xml')
|
||||||
|
});
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
Hedera.Links = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,repeaterFunc: function (res, form)
|
|
||||||
{
|
|
||||||
res.$('link').href = form.get ('link');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
|
|
||||||
.cpanel
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.cpanel .box
|
|
||||||
{
|
|
||||||
max-width: 30em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Items */
|
|
||||||
|
|
||||||
.cpanel .item
|
|
||||||
{
|
|
||||||
display: block;
|
|
||||||
padding: 1em;
|
|
||||||
border-bottom: 1px solid #DDD;
|
|
||||||
}
|
|
||||||
.cpanel .item:hover
|
|
||||||
{
|
|
||||||
background-color: rgba(1, 1, 1, 0.05);
|
|
||||||
}
|
|
||||||
.cpanel .item > .htk-image
|
|
||||||
{
|
|
||||||
margin: 0;
|
|
||||||
margin-right: 1em;
|
|
||||||
float: left;
|
|
||||||
max-height: 2.8em;
|
|
||||||
max-width: 2.8em;
|
|
||||||
}
|
|
||||||
.cpanel .item > p
|
|
||||||
{
|
|
||||||
margin: .1em 0;
|
|
||||||
}
|
|
||||||
.cpanel .item > p.important
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
|
@ -3,30 +3,29 @@
|
||||||
<h1><t>ControlPanel</t></h1>
|
<h1><t>ControlPanel</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="cpanel">
|
<div id="form" class="cpanel">
|
||||||
<div class="box">
|
<htk-repeater form-id="iter" class="items">
|
||||||
<htk-repeater form-id="iter" renderer="repeaterFunc">
|
<db-model property="model">
|
||||||
<db-model property="model">
|
|
||||||
<custom>
|
|
||||||
SELECT image, name, description, link FROM link
|
|
||||||
ORDER BY name
|
|
||||||
</custom>
|
|
||||||
</db-model>
|
|
||||||
<custom>
|
<custom>
|
||||||
<a id="link" class="item" target="_blank">
|
SELECT image, name, description, link FROM link
|
||||||
<htk-image
|
ORDER BY name
|
||||||
form="iter"
|
|
||||||
column="image"
|
|
||||||
directory="link"
|
|
||||||
subdir="full"/>
|
|
||||||
<p class="important">
|
|
||||||
<htk-text form="iter" column="name"/>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<htk-text form="iter" column="description"/>
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</custom>
|
</custom>
|
||||||
</htk-repeater>
|
</db-model>
|
||||||
</div>
|
<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>
|
</div>
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
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,6 +1,8 @@
|
||||||
Images: Imatges
|
Images: Imatges
|
||||||
Collection: Col·lecció
|
Collection: Col·lecció
|
||||||
Click or drop files here: Prem o deixa anar els arxius aquí
|
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
|
Clear all: Netejar tot
|
||||||
Upload files: Pujar arxius
|
Upload files: Pujar arxius
|
||||||
Waiting for upload: Esperant per pujar
|
Waiting for upload: Esperant per pujar
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Images: Images
|
Images: Images
|
||||||
Collection: Collection
|
Collection: Collection
|
||||||
Click or drop files here: Click or drop files here
|
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
|
Clear all: Clear all
|
||||||
Upload files: Upload files
|
Upload files: Upload files
|
||||||
Waiting for upload: Waiting for upload
|
Waiting for upload: Waiting for upload
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Images: Imágenes
|
Images: Imágenes
|
||||||
Collection: Colección
|
Collection: Colección
|
||||||
Click or drop files here: Pulsa o suelta los archivos aquí
|
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
|
Clear all: Limpiar todo
|
||||||
Upload files: Subir archivos
|
Upload files: Subir archivos
|
||||||
Waiting for upload: Esperando para subir
|
Waiting for upload: Esperando para subir
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Images: Images
|
Images: Images
|
||||||
Collection: Collection
|
Collection: Collection
|
||||||
Click or drop files here: Cliquez ici ou déposer des fichiers
|
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
|
Clear all: Tout effacer
|
||||||
Upload files: Upload Files
|
Upload files: Upload Files
|
||||||
Waiting for upload: En attente de télécharger
|
Waiting for upload: En attente de télécharger
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Images: Imagens
|
Images: Imagens
|
||||||
Collection: Coleção
|
Collection: Coleção
|
||||||
Click or drop files here: Clique ou solte arquivos aqui
|
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
|
Clear all: Limpar tudo
|
||||||
Upload files: Fazer upload de arquivos
|
Upload files: Fazer upload de arquivos
|
||||||
Waiting for upload: Esperando para enviar
|
Waiting for upload: Esperando para enviar
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
(function() {
|
|
||||||
|
|
||||||
var Status = {
|
|
||||||
NONE : 0
|
|
||||||
,WAITING : 1
|
|
||||||
,UPLOADING : 2
|
|
||||||
,UPLOADED : 3
|
|
||||||
};
|
|
||||||
|
|
||||||
Hedera.Photos = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
,filesData: []
|
|
||||||
,uploadCount: 0
|
|
||||||
,errors: false
|
|
||||||
,uploadQueue: []
|
|
||||||
,isUploading: false
|
|
||||||
|
|
||||||
,activate: function ()
|
|
||||||
{
|
|
||||||
this.$('schema').value = 'catalog';
|
|
||||||
}
|
|
||||||
|
|
||||||
,addFiles: function (files)
|
|
||||||
{
|
|
||||||
if (!files)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var i = 0; i < files.length; i++)
|
|
||||||
this.addFile (files[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
,addFile: function (file)
|
|
||||||
{
|
|
||||||
var doc = document;
|
|
||||||
var div = doc.createElement ('div');
|
|
||||||
|
|
||||||
var button = new Htk.Button ({
|
|
||||||
tip: 'Remove',
|
|
||||||
icon: 'delete'
|
|
||||||
});
|
|
||||||
button.on ('click', this.onFileRemove, this);
|
|
||||||
div.appendChild (button.node);
|
|
||||||
|
|
||||||
var thumb = doc.createElement ('img');
|
|
||||||
thumb.file = file;
|
|
||||||
thumb.className = 'thumb';
|
|
||||||
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);
|
|
||||||
div.appendChild (name);
|
|
||||||
|
|
||||||
var statusNode = doc.createElement ('span');
|
|
||||||
statusNode.className = 'status';
|
|
||||||
div.appendChild (statusNode);
|
|
||||||
|
|
||||||
var fileData = {
|
|
||||||
div: div,
|
|
||||||
file: file,
|
|
||||||
name: name,
|
|
||||||
statusNode: statusNode,
|
|
||||||
status: Status.NONE
|
|
||||||
};
|
|
||||||
this.filesData.push (fileData);
|
|
||||||
button.value = fileData;
|
|
||||||
|
|
||||||
this.$('file-list').appendChild (div);
|
|
||||||
}
|
|
||||||
|
|
||||||
,onUploadClick: function ()
|
|
||||||
{
|
|
||||||
var filesData = this.filesData;
|
|
||||||
var count = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < filesData.length; i++)
|
|
||||||
{
|
|
||||||
var fileData = filesData[i];
|
|
||||||
|
|
||||||
if (fileData.status === Status.NONE)
|
|
||||||
{
|
|
||||||
this.setImageStatus (
|
|
||||||
fileData, Status.WAITING, 'cloud-upload', _('Waiting for upload'));
|
|
||||||
fileData.name.disabled = true;
|
|
||||||
this.uploadQueue.push (fileData);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count === 0)
|
|
||||||
Htk.Toast.showWarning (_('There are no files to upload'));
|
|
||||||
else
|
|
||||||
this.uploadNextFile ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,uploadNextFile: function ()
|
|
||||||
{
|
|
||||||
if (this.isUploading)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.isUploading = true;
|
|
||||||
|
|
||||||
var fileData = this.uploadQueue.shift ();
|
|
||||||
this.setImageStatus (
|
|
||||||
fileData, Status.UPLOADING, 'upload', _('Uploading file'));
|
|
||||||
|
|
||||||
var formData = new FormData();
|
|
||||||
formData.append ('image', fileData.file);
|
|
||||||
formData.append ('name', fileData.name.value);
|
|
||||||
formData.append ('schema', this.$('schema').value);
|
|
||||||
formData.append ('srv', 'json:image/upload');
|
|
||||||
this.conn.sendFormData (formData,
|
|
||||||
this.onFileUpload.bind (this, fileData));
|
|
||||||
}
|
|
||||||
|
|
||||||
,onFileUpload: function (fileData, data, error)
|
|
||||||
{
|
|
||||||
this.isUploading = false;
|
|
||||||
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
this.setImageStatus (
|
|
||||||
fileData, Status.UPLOADED, 'ok', _('Image uploaded'));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.setImageStatus (
|
|
||||||
fileData, Status.NONE, 'error', error.message);
|
|
||||||
fileData.name.disabled = false;
|
|
||||||
this.errors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.uploadQueue.length === 0)
|
|
||||||
{
|
|
||||||
if (this.errors)
|
|
||||||
Htk.Toast.showError (_('Some errors happened on upload'));
|
|
||||||
else
|
|
||||||
Htk.Toast.showMessage (_('Upload finished successfully'));
|
|
||||||
|
|
||||||
this.errors = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this.uploadNextFile ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,setImageStatus: function (fileData, status, icon, title)
|
|
||||||
{
|
|
||||||
fileData.status = status;
|
|
||||||
|
|
||||||
var statusNode = fileData.statusNode;
|
|
||||||
Vn.Node.removeChilds (statusNode);
|
|
||||||
|
|
||||||
var iconNode = new Htk.Icon ({icon: icon});
|
|
||||||
statusNode.appendChild (iconNode.node);
|
|
||||||
statusNode.title = title ? title : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
,onFileRemove: function (button)
|
|
||||||
{
|
|
||||||
var fileData = button.value;
|
|
||||||
this.$('file-list').removeChild (fileData.div);
|
|
||||||
|
|
||||||
for (var i = 0; i < this.filesData.length; i++)
|
|
||||||
if (this.filesData[i] === fileData)
|
|
||||||
{
|
|
||||||
this.filesData.splice (i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,onClearClick: function ()
|
|
||||||
{
|
|
||||||
this.filesData = [];
|
|
||||||
Vn.Node.removeChilds (this.$('file-list'));
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDropzoneClick: function ()
|
|
||||||
{
|
|
||||||
this.$('file').click ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onFileChange: function ()
|
|
||||||
{
|
|
||||||
this.addFiles (this.$('file').files);
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragEnter: function (event)
|
|
||||||
{
|
|
||||||
Vn.Node.addClass (this.$('dropzone'), 'dragover');
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragLeave: function (event)
|
|
||||||
{
|
|
||||||
Vn.Node.removeClass (this.$('dropzone'), 'dragover');
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragOver: function (event)
|
|
||||||
{
|
|
||||||
event.preventDefault ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDragEnd: function (event)
|
|
||||||
{
|
|
||||||
Vn.Node.removeClass (this.$('dropzone'), 'dragover');
|
|
||||||
event.dataTransfer.clearData ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onDrop: function (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,73 +0,0 @@
|
||||||
|
|
||||||
.photos
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.photos .box
|
|
||||||
{
|
|
||||||
max-width: 25em;
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
.photos .file-list .thumb
|
|
||||||
{
|
|
||||||
max-height: 2em;
|
|
||||||
max-width: 2em;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 0 1em;
|
|
||||||
}
|
|
||||||
.photos .file-list input
|
|
||||||
{
|
|
||||||
max-width: 10em;
|
|
||||||
}
|
|
||||||
.photos .file-list .status
|
|
||||||
{
|
|
||||||
margin-left: .5em;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Footer */
|
|
||||||
|
|
||||||
.photos .footer
|
|
||||||
{
|
|
||||||
margin-top: 1.5em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.photos .footer > button
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
<h1><t>Images</t></h1>
|
<h1><t>Images</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="photos">
|
<div id="form" class="photos">
|
||||||
<div class="box">
|
<div class="box form vn-w-sm vn-pa-lg">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>Collection</t></label>
|
<label><t>Collection</t></label>
|
||||||
<htk-combo id="schema">
|
<htk-combo id="schema">
|
||||||
|
@ -31,6 +31,12 @@
|
||||||
name="image"
|
name="image"
|
||||||
on-change="onFileChange"/>
|
on-change="onFileChange"/>
|
||||||
<div id="file-list" class="file-list"/>
|
<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">
|
<div class="footer">
|
||||||
<button class="thin" on-click="onClearClick">
|
<button class="thin" on-click="onClearClick">
|
||||||
<t>Clear all</t>
|
<t>Clear all</t>
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
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,102 +0,0 @@
|
||||||
|
|
||||||
Hedera.Queries = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,activate: function ()
|
|
||||||
{
|
|
||||||
this.$('result-index').value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
,clean: function ()
|
|
||||||
{
|
|
||||||
if (this._grid)
|
|
||||||
{
|
|
||||||
this.$('grid-holder').removeChild (this._grid.node);
|
|
||||||
this._grid.unref ();
|
|
||||||
this._grid = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
,_onExecuteClick: function ()
|
|
||||||
{
|
|
||||||
this.clean ();
|
|
||||||
|
|
||||||
var model = new Db.Model ({
|
|
||||||
conn: this.conn,
|
|
||||||
query: this.$('sql').value,
|
|
||||||
resultIndex: this.$('result-index').value,
|
|
||||||
updatable: this.$('updatable').value
|
|
||||||
});
|
|
||||||
model.on ('status-changed', this._onModelChange, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
,_onCleanClick: function ()
|
|
||||||
{
|
|
||||||
this.clean ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,_onModelChange: function (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.$('grid-holder');
|
|
||||||
|
|
||||||
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,25 +0,0 @@
|
||||||
.queries
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.queries .box
|
|
||||||
{
|
|
||||||
max-width: 40em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.queries .form
|
|
||||||
{
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
.queries textarea
|
|
||||||
{
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 8em;
|
|
||||||
}
|
|
||||||
.queries .result
|
|
||||||
{
|
|
||||||
margin-top: 1em;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
.queries textarea {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 8em;
|
||||||
|
}
|
||||||
|
.queries .result {
|
||||||
|
margin-top: 1em;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
|
@ -6,14 +6,14 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="ok"
|
icon="ok"
|
||||||
tip="_Execute"
|
tip="_Execute"
|
||||||
on-click="_onExecuteClick"/>
|
on-click="this.onExecuteClick()"/>
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="delete"
|
icon="delete"
|
||||||
tip="_Clean"
|
tip="_Clean"
|
||||||
on-click="_onCleanClick"/>
|
on-click="this.onCleanClick()"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="queries">
|
<div id="form" class="queries">
|
||||||
<div class="box form">
|
<div class="box form vn-w-sm vn-pa-lg">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>SQL query</t></label>
|
<label><t>SQL query</t></label>
|
||||||
<textarea
|
<textarea
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
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,45 +0,0 @@
|
||||||
.users
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.users .box
|
|
||||||
{
|
|
||||||
max-width: 30em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.users-box
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
border-bottom: 1px solid #DDD;
|
|
||||||
}
|
|
||||||
.users-box > button
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.users-box > p
|
|
||||||
{
|
|
||||||
margin: .2em 0;
|
|
||||||
}
|
|
||||||
.users-box > p.important
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
.users-box > .disabled
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
color: white;
|
|
||||||
background-color: #F66;
|
|
||||||
border-radius: .2em;
|
|
||||||
padding: .2em;
|
|
||||||
margin: .3em;
|
|
||||||
font-size: .8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Topbar */
|
|
||||||
|
|
||||||
.action-bar .htk-search-entry
|
|
||||||
{
|
|
||||||
margin: .8em .6em;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
.users-box.item > .actions {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.users-box .disabled {
|
||||||
|
color: white;
|
||||||
|
background-color: #F66;
|
||||||
|
border-radius: .2em;
|
||||||
|
padding: .3em;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
|
@ -1,62 +1,48 @@
|
||||||
<vn>
|
<vn>
|
||||||
<vn-group>
|
|
||||||
<vn-param id="user-name"/>
|
|
||||||
<vn-hash-param key="user" param="user-name"/>
|
|
||||||
</vn-group>
|
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>User management</t></h1>
|
<h1><t>User management</t></h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="actions">
|
<div id="actions">
|
||||||
<htk-search-entry
|
<htk-search-entry form="hash" column="user"/>
|
||||||
param="user-name"/>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="users">
|
<div id="form" class="users">
|
||||||
<div class="box">
|
<htk-repeater
|
||||||
<htk-repeater form-id="iter" renderer="rendererFunc">
|
form-id="iter"
|
||||||
<db-model property="model">
|
renderer="rendererFunc"
|
||||||
<custom>
|
class="htk-list box vn-w-xs">
|
||||||
SELECT u.id, u.name, u.nickname, u.active
|
<db-model property="model" lot="hash">
|
||||||
FROM account.user u
|
SELECT u.id, u.name, u.nickname, u.active
|
||||||
WHERE u.name LIKE CONCAT('%', #user, '%')
|
FROM account.user u
|
||||||
OR u.nickname LIKE CONCAT('%', #user, '%')
|
WHERE u.name LIKE CONCAT('%', #user, '%')
|
||||||
OR u.id = #user
|
OR u.nickname LIKE CONCAT('%', #user, '%')
|
||||||
ORDER BY u.name LIMIT 200
|
OR u.id = #user
|
||||||
</custom>
|
ORDER BY u.name LIMIT 200
|
||||||
<sql-batch property="batch">
|
</db-model>
|
||||||
<custom>
|
<custom>
|
||||||
<item name="user" param="user-name"/>
|
<a class="users-box item"
|
||||||
</custom>
|
href="{{`#!form=admin/access-log&user=${iter.id}`}}"
|
||||||
</sql-batch>
|
title="_Access log">
|
||||||
</db-model>
|
<div class="content">
|
||||||
<custom>
|
<p class="important">
|
||||||
<div class="users-box">
|
{{iter.nickname}}
|
||||||
<htk-button
|
</p>
|
||||||
form="iter"
|
<p>
|
||||||
column="id"
|
#{{iter.id}} - {{iter.name}}
|
||||||
tip="_Access log"
|
</p>
|
||||||
icon="gnome"
|
</div>
|
||||||
on-click="onAccessLogClick"/>
|
<div class="actions"
|
||||||
<htk-button
|
on-click="$event.preventDefault()">
|
||||||
id="impersonate"
|
|
||||||
form="iter"
|
|
||||||
column="id"
|
|
||||||
tip="_Impersonate user"
|
|
||||||
icon="incognito"
|
|
||||||
on-click="onChangeUserClick"/>
|
|
||||||
<span id="disabled" class="disabled">
|
<span id="disabled" class="disabled">
|
||||||
<t>Disabled</t>
|
<t>Disabled</t>
|
||||||
</span>
|
</span>
|
||||||
<p class="important">
|
<htk-button
|
||||||
<htk-text form="iter" column="nickname"/>
|
id="impersonate"
|
||||||
</p>
|
icon="supervisor_account"
|
||||||
<p>
|
tip="_Impersonate user"
|
||||||
@<htk-text form="iter" column="id"/> -
|
on-click="this.onChangeUserClick(iter.name)"/>
|
||||||
<htk-text form="iter" column="name"/>
|
|
||||||
</p>
|
|
||||||
<div class="clear"/>
|
|
||||||
</div>
|
</div>
|
||||||
</custom>
|
</a>
|
||||||
</htk-repeater>
|
</custom>
|
||||||
</div>
|
</htk-repeater>
|
||||||
</div>
|
</div>
|
||||||
</vn>
|
</vn>
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
|
|
||||||
Hedera.Users = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,onAccessLogClick: function (button, form)
|
|
||||||
{
|
|
||||||
this.hash.set ({
|
|
||||||
'form': 'admin/access-log'
|
|
||||||
,'user': form.get ('id')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
,rendererFunc: function (scope, form)
|
|
||||||
{
|
|
||||||
var isEnabled = form.get('active')
|
|
||||||
scope.$('disabled').style.display = isEnabled ?
|
|
||||||
'none' : 'block';
|
|
||||||
scope.$('impersonate').node.style.display = isEnabled ?
|
|
||||||
'block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
,onChangeUserClick: function (button, form)
|
|
||||||
{
|
|
||||||
this.gui.supplantUser (form.get ('name'),
|
|
||||||
this.onUserSupplant.bind (this));
|
|
||||||
}
|
|
||||||
|
|
||||||
,onUserSupplant: function ()
|
|
||||||
{
|
|
||||||
this.hash.set ({form: 'ecomerce/orders'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default new Class({
|
||||||
|
Extends: Hedera.Form,
|
||||||
|
Template: require('./ui.xml')
|
||||||
|
|
||||||
|
,activate() {
|
||||||
|
if (!this.hash.$.to)
|
||||||
|
this.hash.assign({
|
||||||
|
from: Date.vnNew(),
|
||||||
|
to: Date.vnNew()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
.visits
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.visits .box
|
|
||||||
{
|
|
||||||
max-width: 25em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
.visits .form
|
|
||||||
{
|
|
||||||
padding: 1.5em;
|
|
||||||
max-width: 20em;
|
|
||||||
}
|
|
||||||
.visits .summary
|
|
||||||
{
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
.visits .summary p
|
|
||||||
{
|
|
||||||
padding: 1.5em;
|
|
||||||
font-size: 1.4em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* List */
|
|
||||||
|
|
||||||
.visits .list
|
|
||||||
{
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
.visits .item
|
|
||||||
{
|
|
||||||
display: block;
|
|
||||||
padding: 1em;
|
|
||||||
border-bottom: 1px solid #DDD;
|
|
||||||
}
|
|
||||||
.visits .item > p
|
|
||||||
{
|
|
||||||
margin: .1em 0;
|
|
||||||
}
|
|
||||||
.visits .item > p.important
|
|
||||||
{
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
.visits .box {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.visits .box:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.visits .summary p {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
margin: 0;
|
||||||
|
text-align: right;
|
||||||
|
}
|
|
@ -1,4 +1,8 @@
|
||||||
<vn>
|
<vn>
|
||||||
|
<vn-lot-query id="params">
|
||||||
|
<vn-spec name="from" type="Date"/>
|
||||||
|
<vn-spec name="to" type="Date"/>
|
||||||
|
</vn-lot-query>
|
||||||
<div id="title">
|
<div id="title">
|
||||||
<h1><t>Visits</t></h1>
|
<h1><t>Visits</t></h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,87 +10,78 @@
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="refresh"
|
icon="refresh"
|
||||||
tip="_Refresh"
|
tip="_Refresh"
|
||||||
on-click="onRefreshClick"/>
|
on-click="visits.refresh()"/>
|
||||||
<htk-bar-button
|
<htk-bar-button
|
||||||
icon="user-info"
|
icon="visibility"
|
||||||
tip="_Connections"
|
tip="_Connections"
|
||||||
on-click="onSessionsClick"/>
|
on-click="this.hash.setAll({form: 'admin/connections'})"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="form" class="visits">
|
<div id="form" class="visits">
|
||||||
<div class="box">
|
<div class="vn-w-xs">
|
||||||
<div class="form">
|
<div class="form vn-pa-lg box">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>From</t></label>
|
<label><t>From</t></label>
|
||||||
<htk-date-chooser>
|
<htk-date-chooser
|
||||||
<vn-param property="param" id="from"/>
|
form="params"
|
||||||
</htk-date-chooser>
|
column="from"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><t>To</t></label>
|
<label><t>To</t></label>
|
||||||
<htk-date-chooser>
|
<htk-date-chooser
|
||||||
<vn-param property="param" id="to"/>
|
form="params"
|
||||||
</htk-date-chooser>
|
column="to"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="summary vn-pa-lg box">
|
||||||
<div class="summary box">
|
<p>
|
||||||
<p>
|
<htk-text>
|
||||||
<htk-text>
|
<db-calc-sum
|
||||||
<db-calc-sum
|
property="param"
|
||||||
property="param"
|
model="visits"
|
||||||
model="visits"
|
column-name="visits"/>
|
||||||
column-name="visits"/>
|
</htk-text>
|
||||||
</htk-text>
|
<t>visits</t>,
|
||||||
<t>visits</t>,
|
<htk-text>
|
||||||
<htk-text>
|
<db-calc-sum
|
||||||
<db-calc-sum
|
property="param"
|
||||||
property="param"
|
model="visits"
|
||||||
model="visits"
|
column-name="newVisits"/>
|
||||||
column-name="newVisits"/>
|
</htk-text>
|
||||||
</htk-text>
|
<t>news</t>
|
||||||
<t>news</t>
|
</p>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
<htk-repeater
|
||||||
<div class="list box">
|
class="box htk-list"
|
||||||
<htk-repeater form-id="iter" empty-message="_Select date interval">
|
form-id="iter"
|
||||||
<db-model property="model" id="visits">
|
empty-message="_Select date interval">
|
||||||
<custom>
|
<db-model property="model" id="visits" lot="params">
|
||||||
SELECT browser
|
SELECT browser,
|
||||||
,MIN(CAST(version AS DECIMAL(4,1))) minVersion
|
MIN(CAST(version AS DECIMAL(4,1))) minVersion,
|
||||||
,MAX(CAST(version AS DECIMAL(4,1))) maxVersion
|
MAX(CAST(version AS DECIMAL(4,1))) maxVersion,
|
||||||
,MAX(c.stamp) lastVisit
|
MAX(c.stamp) lastVisit,
|
||||||
,COUNT(DISTINCT c.id) visits
|
COUNT(DISTINCT c.id) visits,
|
||||||
,SUM(a.firstAccess = c.id AND v.firstAgent = a.id) newVisits
|
SUM(a.firstAccessFk = c.id AND v.firstAgentFk = a.id) newVisits
|
||||||
FROM visitUser e
|
FROM visitUser e
|
||||||
JOIN visitAccess c ON e.access = c.id
|
JOIN visitAccess c ON c.id = e.accessFk
|
||||||
JOIN visitAgent a ON c.agent = a.id
|
JOIN visitAgent a ON a.id = c.agentFk
|
||||||
JOIN visit v ON a.visit = v.id
|
JOIN visit v ON v.id = a.visitFk
|
||||||
WHERE c.stamp BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
|
WHERE c.stamp BETWEEN TIMESTAMP(#from,'00:00:00') AND TIMESTAMP(#to,'23:59:59')
|
||||||
GROUP BY browser ORDER BY visits DESC
|
GROUP BY browser ORDER BY visits DESC
|
||||||
</custom>
|
|
||||||
<sql-batch property="batch">
|
|
||||||
<custom>
|
|
||||||
<item name="from" param="from"/>
|
|
||||||
<item name="to" param="to"/>
|
|
||||||
</custom>
|
|
||||||
</sql-batch>
|
|
||||||
</db-model>
|
</db-model>
|
||||||
<custom>
|
<custom>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<p class="important">
|
<div class="content">
|
||||||
<htk-text form="iter" column="browser"/>
|
<p class="important">
|
||||||
<htk-text form="iter" column="minVersion"/> -
|
{{iter.browser}} {{iter.minVersion}} - {{iter.maxVersion}}
|
||||||
<htk-text form="iter" column="maxVersion"/>
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
{{iter.visits}} <t>visits</t>,
|
||||||
<htk-text form="iter" column="visits"/>
|
{{iter.newVisits}} <t>news</t>
|
||||||
<t>visits</t>,
|
</p>
|
||||||
<htk-text form="iter" column="newVisits"/>
|
<p>
|
||||||
<t>news</t>
|
{{Vn.Value.format(iter.lastVisit, _('%a, %e %b %Y at %T'))}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
</div>
|
||||||
<htk-text form="iter" column="lastVisit" format="_%a, %e %b %Y at %T"/>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</custom>
|
</custom>
|
||||||
</htk-repeater>
|
</htk-repeater>
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
|
|
||||||
Hedera.Visits = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,activate: function ()
|
|
||||||
{
|
|
||||||
this.$('from').value = new Date ();
|
|
||||||
this.$('to').value = new Date ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onRefreshClick: function ()
|
|
||||||
{
|
|
||||||
this.$('visits').refresh ();
|
|
||||||
}
|
|
||||||
|
|
||||||
,onSessionsClick: function ()
|
|
||||||
{
|
|
||||||
this.hash.set ({'form': 'admin/connections'});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default new Class({
|
||||||
|
Extends: Hedera.Form,
|
||||||
|
Template: require('./ui.xml'),
|
||||||
|
});
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Paquets per agència
|
ListByAgency: Paquets per agència
|
||||||
ShowByProvince: Mostrar desglose per província
|
|
||||||
Agency: Agència
|
Agency: Agència
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Paquets
|
Bundles: Paquets
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Bundles by agency
|
ListByAgency: Bundles by agency
|
||||||
ShowByProvince: Show breakdown by province
|
|
||||||
Agency: Agency
|
Agency: Agency
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Bundles
|
Bundles: Bundles
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Bultos por agencia
|
ListByAgency: Bultos por agencia
|
||||||
ShowByProvince: Mostrar desglose por provincia
|
|
||||||
Agency: Agencia
|
Agency: Agencia
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Bultos
|
Bundles: Bultos
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Liste par agence
|
ListByAgency: Liste par agence
|
||||||
ShowByProvince: Montrer par province
|
|
||||||
Agency: Agence
|
Agency: Agence
|
||||||
Exps: Expéditeur
|
Exps: Expéditeur
|
||||||
Bundles: Cartons
|
Bundles: Cartons
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ListByAgency: Bultos por agencia
|
ListByAgency: Bultos por agencia
|
||||||
ShowByProvince: Mostrar desglosse por Distrito
|
|
||||||
Agency: Agencia
|
Agency: Agencia
|
||||||
Exps: Exps.
|
Exps: Exps.
|
||||||
Bundles: Bultos
|
Bundles: Bultos
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
|
|
||||||
Hedera.Packages = new Class
|
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
|
||||||
|
|
||||||
,onShowClick: function (column, agencyId)
|
|
||||||
{
|
|
||||||
this.hash.set ({
|
|
||||||
'form': 'agencies/provinces',
|
|
||||||
'agency': agencyId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
.packages
|
|
||||||
{
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
.packages .box
|
|
||||||
{
|
|
||||||
max-width: 40em;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue