mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Compare commits
604 Commits
v1.8.13-tr
...
v1.11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0634735288 | ||
|
|
719c45b408 | ||
|
|
b70edd5424 | ||
|
|
a6498c2f96 | ||
|
|
56be7b1d46 | ||
|
|
b2f3477261 | ||
|
|
14b73149be | ||
|
|
0ab7d95607 | ||
|
|
ee08dcfeb4 | ||
|
|
b893dea810 | ||
|
|
ec5ce45850 | ||
|
|
9afb97fa0f | ||
|
|
676abe0ced | ||
|
|
73d38cb91b | ||
|
|
fffae46a63 | ||
|
|
6ed91cab1f | ||
|
|
cc5d0c35dd | ||
|
|
c34570154c | ||
|
|
a5940e1641 | ||
|
|
39f0c5b5b0 | ||
|
|
abb5adec43 | ||
|
|
525cb4826f | ||
|
|
fde0aba96c | ||
|
|
ff18fd25f1 | ||
|
|
9248ac05ac | ||
|
|
a066c6391d | ||
|
|
4d11485283 | ||
|
|
9e270690ef | ||
|
|
15b781b271 | ||
|
|
5dc8f21b7b | ||
|
|
9ccb3ee80b | ||
|
|
27de66b055 | ||
|
|
ba98c7e2c5 | ||
|
|
22eae753fe | ||
|
|
d832d850fe | ||
|
|
aead867ea0 | ||
|
|
97f5022bdd | ||
|
|
0cb7a555d3 | ||
|
|
52b7872a55 | ||
|
|
522aaee1a3 | ||
|
|
179cf6e484 | ||
|
|
28ded1f0c2 | ||
|
|
7d971fc39d | ||
|
|
4f0b20e8ad | ||
|
|
a6f2ee1367 | ||
|
|
eb1c598a6c | ||
|
|
4706bf0528 | ||
|
|
969b6caa96 | ||
|
|
69ea1e6d26 | ||
|
|
91704d9df7 | ||
|
|
dbbc2ddb1c | ||
|
|
99729457cc | ||
|
|
5a58294bc6 | ||
|
|
398b3bbd8b | ||
|
|
6cb038c362 | ||
|
|
cc40948783 | ||
|
|
00bdcd3948 | ||
|
|
c860ffc176 | ||
|
|
8664411880 | ||
|
|
f17f1008e3 | ||
|
|
a2828f3b9a | ||
|
|
cbfdfb43e3 | ||
|
|
23e672aef9 | ||
|
|
6d9cc7e29d | ||
|
|
8a47788a09 | ||
|
|
afed5ab666 | ||
|
|
357eda8c19 | ||
|
|
f18401d183 | ||
|
|
4ea91d14f9 | ||
|
|
f57661b13f | ||
|
|
ad25c1d1b2 | ||
|
|
87af5dcee5 | ||
|
|
106871b956 | ||
|
|
4d25abcfce | ||
|
|
2ccdf3c97a | ||
|
|
89bd9c8038 | ||
|
|
88627dc837 | ||
|
|
8ca57b0705 | ||
|
|
c7db283e8c | ||
|
|
83ca3b7b8b | ||
|
|
830699d2b8 | ||
|
|
f822e658c4 | ||
|
|
8817a1afb7 | ||
|
|
693adf181e | ||
|
|
f269f13b09 | ||
|
|
9845258a25 | ||
|
|
edbed2c8d3 | ||
|
|
8e0f2d2500 | ||
|
|
e022504c26 | ||
|
|
62e4cbd052 | ||
|
|
70ae59550d | ||
|
|
f74af8fa2d | ||
|
|
82d1b57005 | ||
|
|
c32aacc1b3 | ||
|
|
523b4045bf | ||
|
|
8e4e273b7c | ||
|
|
816297e22f | ||
|
|
72889b5c36 | ||
|
|
0f0216fe79 | ||
|
|
42433d1ad4 | ||
|
|
52533fc04c | ||
|
|
bb0223877c | ||
|
|
5eb1fcddbb | ||
|
|
c646eb3939 | ||
|
|
a313c99370 | ||
|
|
0f84d9f02e | ||
|
|
900a9c6145 | ||
|
|
5b33cbe9aa | ||
|
|
114ce3b764 | ||
|
|
660d3f326f | ||
|
|
b8d51ae0de | ||
|
|
0bdda6387a | ||
|
|
4fbdbb1aa2 | ||
|
|
72ddcb4fff | ||
|
|
50ef2de5f9 | ||
|
|
55d3ee1af0 | ||
|
|
422166441e | ||
|
|
9d3f85628c | ||
|
|
669d9c3c66 | ||
|
|
dcb406d246 | ||
|
|
cadad28b0c | ||
|
|
01b0a033fd | ||
|
|
0fb66ab258 | ||
|
|
a49c21cfd1 | ||
|
|
f67a8c1f2d | ||
|
|
f4624ead42 | ||
|
|
2cd570383f | ||
|
|
920900b619 | ||
|
|
e98d934a67 | ||
|
|
31a846b9c3 | ||
|
|
5eaea28401 | ||
|
|
50ef902adb | ||
|
|
75b6a078c6 | ||
|
|
c0c93c172e | ||
|
|
ed18244070 | ||
|
|
e13063e0c6 | ||
|
|
6c38997010 | ||
|
|
0e01c0d69b | ||
|
|
caab3ea74d | ||
|
|
c543dff2e1 | ||
|
|
92badfd88c | ||
|
|
dca64e6939 | ||
|
|
a9c4d27d5e | ||
|
|
610c2f9519 | ||
|
|
05d757e7c4 | ||
|
|
31a2453882 | ||
|
|
5febd0a0d6 | ||
|
|
694f1e9b25 | ||
|
|
131bf842a9 | ||
|
|
8ec1c2e04a | ||
|
|
e94dc257a1 | ||
|
|
3bd4fc59d4 | ||
|
|
7b8463b03a | ||
|
|
00e7fc1c0d | ||
|
|
2ca20ad701 | ||
|
|
775da82072 | ||
|
|
162b392004 | ||
|
|
26bedf0523 | ||
|
|
ff3ee62509 | ||
|
|
9c2a78adf2 | ||
|
|
5a767ba3ef | ||
|
|
691d642721 | ||
|
|
7dbfc3740d | ||
|
|
b2897d7feb | ||
|
|
b18177c215 | ||
|
|
cec0a8c2e7 | ||
|
|
412de318ed | ||
|
|
92cc7a4648 | ||
|
|
96c0481e17 | ||
|
|
5dd7ddc288 | ||
|
|
ea91a82f30 | ||
|
|
8e10269b50 | ||
|
|
dae74666c5 | ||
|
|
94e31e35ba | ||
|
|
c835b4eb1a | ||
|
|
ef9e43fbd3 | ||
|
|
f083433854 | ||
|
|
9052b1c3db | ||
|
|
59578a73af | ||
|
|
c691e260cf | ||
|
|
82072c8970 | ||
|
|
d0c52ac176 | ||
|
|
6811a62568 | ||
|
|
8653d03969 | ||
|
|
90d5a04368 | ||
|
|
84e4ebef08 | ||
|
|
98603c4042 | ||
|
|
26a4ee0171 | ||
|
|
4f03a2d25c | ||
|
|
6a830a3843 | ||
|
|
3ffd049135 | ||
|
|
e6d1b38b82 | ||
|
|
f8a892faf2 | ||
|
|
54e141489a | ||
|
|
e64fd1d308 | ||
|
|
01647c3df9 | ||
|
|
cd6d7c76f6 | ||
|
|
efa71c4ac8 | ||
|
|
d4eb27a4ed | ||
|
|
eca18ba6ee | ||
|
|
31fa49feed | ||
|
|
b68aafdb72 | ||
|
|
fd09a63e48 | ||
|
|
afc50863cd | ||
|
|
fea2240c39 | ||
|
|
9642e8295e | ||
|
|
1424d44eab | ||
|
|
0a5f0a518d | ||
|
|
ff1672e411 | ||
|
|
32d8368990 | ||
|
|
e7f8102eb9 | ||
|
|
24e1d0b775 | ||
|
|
ceadd386aa | ||
|
|
d42dc2b286 | ||
|
|
e9c8e17710 | ||
|
|
bfd845915c | ||
|
|
b7976a2356 | ||
|
|
cd744dab68 | ||
|
|
02e3aac3f0 | ||
|
|
50075f02a0 | ||
|
|
05d8cd09e3 | ||
|
|
02fd87158e | ||
|
|
165af4b812 | ||
|
|
dba8e36752 | ||
|
|
a245590114 | ||
|
|
5ecae39051 | ||
|
|
2508234a7c | ||
|
|
da5f9e7ebc | ||
|
|
0d483882de | ||
|
|
9e40502876 | ||
|
|
c38e58159f | ||
|
|
acf0919bfa | ||
|
|
bca409bfe4 | ||
|
|
1fe10b4b25 | ||
|
|
768378b147 | ||
|
|
1fcbf6b44d | ||
|
|
f96502c369 | ||
|
|
c031b0e52b | ||
|
|
6006952603 | ||
|
|
e5fb8712d7 | ||
|
|
508dfa4f23 | ||
|
|
65d176f533 | ||
|
|
089c754f62 | ||
|
|
aae8f1cbc4 | ||
|
|
7194db40ee | ||
|
|
f2ad087be5 | ||
|
|
0b8b5e694e | ||
|
|
01f9fd3232 | ||
|
|
99cac20725 | ||
|
|
068dbe5013 | ||
|
|
ed375a1e2c | ||
|
|
4345285164 | ||
|
|
eb7cb02f33 | ||
|
|
f22dd7513d | ||
|
|
c54119f482 | ||
|
|
23d2b3a664 | ||
|
|
c747bb5305 | ||
|
|
d147d2035d | ||
|
|
4dd71c1240 | ||
|
|
6ad7c7b835 | ||
|
|
10bbc5f9ef | ||
|
|
b8a124b99e | ||
|
|
28b1ea2d9f | ||
|
|
2b989f49ea | ||
|
|
bdc701f880 | ||
|
|
7af154d675 | ||
|
|
2552b5faac | ||
|
|
d8e3052575 | ||
|
|
3c797d3b86 | ||
|
|
46ca3bc950 | ||
|
|
75ec77dc31 | ||
|
|
a09a54e4cb | ||
|
|
e486dbd4f8 | ||
|
|
db5503dd80 | ||
|
|
dd3d205536 | ||
|
|
90007d7114 | ||
|
|
7ba99c0fe0 | ||
|
|
ba61f94906 | ||
|
|
7c82fa3d44 | ||
|
|
665749d0c5 | ||
|
|
d3566f9303 | ||
|
|
7d2deca969 | ||
|
|
0f19be4db4 | ||
|
|
393a4efbf6 | ||
|
|
34b109cbb7 | ||
|
|
4785f3eacc | ||
|
|
e14b017f1f | ||
|
|
d2096cf6d1 | ||
|
|
fbda1a27ad | ||
|
|
098afc62c1 | ||
|
|
1cd1e9dc37 | ||
|
|
0bbaafbd41 | ||
|
|
0e42c1cf30 | ||
|
|
620721c8cb | ||
|
|
5cba635783 | ||
|
|
08c723b10f | ||
|
|
61feb2b27d | ||
|
|
a2dee8d3d8 | ||
|
|
a74c502fd9 | ||
|
|
f6c3a2a46e | ||
|
|
4464a85a74 | ||
|
|
22bbe29f3d | ||
|
|
9832966b77 | ||
|
|
19213a5ca8 | ||
|
|
3a0b47c451 | ||
|
|
0cd43987de | ||
|
|
ca1987fc87 | ||
|
|
2f153d799b | ||
|
|
742dd0b5dd | ||
|
|
ecef905444 | ||
|
|
dd56e03be1 | ||
|
|
7b456461f3 | ||
|
|
e4872172c8 | ||
|
|
2ed5e144ca | ||
|
|
f9df4d4c93 | ||
|
|
1aa477c57c | ||
|
|
69385370ee | ||
|
|
65ab83a9a5 | ||
|
|
746c2ffef9 | ||
|
|
6690f2e9e7 | ||
|
|
74a7cb82bc | ||
|
|
15ed4c32d9 | ||
|
|
56ff877b25 | ||
|
|
926f196b96 | ||
|
|
5b7e2f7ca8 | ||
|
|
0a12f78444 | ||
|
|
da5c907e0f | ||
|
|
f065cbe251 | ||
|
|
511afa0ddc | ||
|
|
d5ab9eb675 | ||
|
|
cb08011450 | ||
|
|
41b7be900c | ||
|
|
6133b302af | ||
|
|
4fb1c7fd92 | ||
|
|
b31881baa5 | ||
|
|
4e96487da9 | ||
|
|
98317e96d0 | ||
|
|
4865533f26 | ||
|
|
1f8890b430 | ||
|
|
11daf89005 | ||
|
|
fab893e60b | ||
|
|
a04116466e | ||
|
|
2f6493bb86 | ||
|
|
589c2a1500 | ||
|
|
8cae874109 | ||
|
|
7c406f7c3a | ||
|
|
862443ed6d | ||
|
|
3b78179dea | ||
|
|
f317cee9e9 | ||
|
|
35912605c3 | ||
|
|
8901af897a | ||
|
|
ee92f46bd5 | ||
|
|
44ba499ad9 | ||
|
|
44d172f3b4 | ||
|
|
d2b6ba4330 | ||
|
|
576e4db9be | ||
|
|
692ccf0598 | ||
|
|
ce65a9d063 | ||
|
|
ffc99df373 | ||
|
|
5c58d30ca7 | ||
|
|
3efabf5c50 | ||
|
|
919e39f950 | ||
|
|
0e14704572 | ||
|
|
e9d062a8c2 | ||
|
|
f3af36deca | ||
|
|
ecb78233d9 | ||
|
|
a68ae1fe2d | ||
|
|
28ba05ec6b | ||
|
|
5b675cbaba | ||
|
|
42dd58426e | ||
|
|
c83755f901 | ||
|
|
ae2d3d3fd9 | ||
|
|
e6eb45b453 | ||
|
|
01ce092ebc | ||
|
|
5d77ef52c5 | ||
|
|
e8636c0cbf | ||
|
|
f890927423 | ||
|
|
6499d17cb1 | ||
|
|
1d1e581c85 | ||
|
|
64009a2c9e | ||
|
|
14f6ea4c01 | ||
|
|
fdca1f6606 | ||
|
|
63a15ec392 | ||
|
|
356dad73ba | ||
|
|
fb5784fbda | ||
|
|
4ef97aa418 | ||
|
|
b9d72ce4cf | ||
|
|
9733bb3a77 | ||
|
|
532dc57725 | ||
|
|
f4c3fbf8bc | ||
|
|
778526af2e | ||
|
|
1aebee0583 | ||
|
|
ed5c650456 | ||
|
|
b8c6da301c | ||
|
|
269a60b36f | ||
|
|
25907f97a8 | ||
|
|
d1779b9457 | ||
|
|
ddac179f9b | ||
|
|
25f48d944c | ||
|
|
c9c4680ef6 | ||
|
|
1449169b16 | ||
|
|
c6e50a3f7f | ||
|
|
56295e5ffb | ||
|
|
33a3db8698 | ||
|
|
c4f9a5a234 | ||
|
|
627899bbd4 | ||
|
|
12f4f2d17a | ||
|
|
300dc3084c | ||
|
|
50c3d1367d | ||
|
|
a1cad82564 | ||
|
|
298fd057f5 | ||
|
|
33b570b117 | ||
|
|
3b05b76b80 | ||
|
|
c97a140471 | ||
|
|
7c831c9844 | ||
|
|
5c16fefe41 | ||
|
|
5ad88f992c | ||
|
|
f87f4310f0 | ||
|
|
987ad0df6c | ||
|
|
d500c20d3f | ||
|
|
99a7665edc | ||
|
|
37f60bf7a1 | ||
|
|
b5a6bcdf9d | ||
|
|
858852123d | ||
|
|
ae72ebef5e | ||
|
|
1450bfd726 | ||
|
|
22e4a50807 | ||
|
|
a039286240 | ||
|
|
9ac638f8ba | ||
|
|
da335703b4 | ||
|
|
d374ab569d | ||
|
|
47df2dc20b | ||
|
|
5c43c75b00 | ||
|
|
f83c7a88df | ||
|
|
5ae473e07f | ||
|
|
e69b27a3c4 | ||
|
|
e52e04ba29 | ||
|
|
1dcffa790d | ||
|
|
f22278db51 | ||
|
|
0280e04008 | ||
|
|
41607c5846 | ||
|
|
1c69f2c670 | ||
|
|
05a69ff0c6 | ||
|
|
758f57a889 | ||
|
|
eed11faa62 | ||
|
|
7fd8c5956d | ||
|
|
8ed983cf03 | ||
|
|
b6292e2723 | ||
|
|
8bdf57d0d9 | ||
|
|
03f590ccc4 | ||
|
|
06279848c6 | ||
|
|
3623325cab | ||
|
|
df18329233 | ||
|
|
1db0bbef09 | ||
|
|
f3322dd82e | ||
|
|
d2d07f0362 | ||
|
|
131d9384c2 | ||
|
|
7beb6e624c | ||
|
|
73041e9263 | ||
|
|
e600621883 | ||
|
|
0f1fb68ee8 | ||
|
|
20b2e831e9 | ||
|
|
11ccb9a6d2 | ||
|
|
074018d2a6 | ||
|
|
386972db3b | ||
|
|
4cec7213b5 | ||
|
|
3f3085c66b | ||
|
|
f4b1c5de9c | ||
|
|
ca677a3ccd | ||
|
|
4cdd0831e8 | ||
|
|
39dc765c63 | ||
|
|
1fe20eba45 | ||
|
|
72d264fab9 | ||
|
|
f50e745826 | ||
|
|
949faa7fde | ||
|
|
96e31235da | ||
|
|
e217f96454 | ||
|
|
3aa50ed38f | ||
|
|
d7de7d462f | ||
|
|
4c238748c6 | ||
|
|
2c65218ce3 | ||
|
|
613016a6cf | ||
|
|
1899e2fa98 | ||
|
|
c7608c6f44 | ||
|
|
0349e2026b | ||
|
|
a763c24f3c | ||
|
|
1faa1579f3 | ||
|
|
630e61ee5a | ||
|
|
47468df2a5 | ||
|
|
5b1947429e | ||
|
|
8db1fa4e77 | ||
|
|
b3c94fd688 | ||
|
|
7a33b9cea7 | ||
|
|
4d94b65d25 | ||
|
|
d27b8f8fcb | ||
|
|
fe7d3b0d58 | ||
|
|
318f89f9a2 | ||
|
|
7e5e167215 | ||
|
|
665acdef8f | ||
|
|
d8e17231ec | ||
|
|
ff2b2e17d9 | ||
|
|
4b89a1d736 | ||
|
|
595d7b5594 | ||
|
|
bc62ad5797 | ||
|
|
3b8cab9392 | ||
|
|
9aca5459b7 | ||
|
|
819a003f26 | ||
|
|
3a9b71bd1f | ||
|
|
62c5ccf904 | ||
|
|
2f3f20e433 | ||
|
|
85fefcd946 | ||
|
|
e087a008c2 | ||
|
|
4c4969e86b | ||
|
|
f6c8a11b7b | ||
|
|
1ef4bf5da0 | ||
|
|
a18bf4b666 | ||
|
|
bdfd718c51 | ||
|
|
3c73282d57 | ||
|
|
d09e0cd44a | ||
|
|
d581fc4863 | ||
|
|
790bc5b187 | ||
|
|
f0e2d426c3 | ||
|
|
8c56bd23fc | ||
|
|
6254dfde11 | ||
|
|
49d96206e1 | ||
|
|
ce562889a9 | ||
|
|
5a2c3f5c5c | ||
|
|
7874d96003 | ||
|
|
8e5b94b5ca | ||
|
|
4a989f705b | ||
|
|
3e6e3173ee | ||
|
|
72292b1dd3 | ||
|
|
6816061915 | ||
|
|
23585e6ea8 | ||
|
|
cf4bd8d755 | ||
|
|
22b5431279 | ||
|
|
4e35c0448b | ||
|
|
fd259e0a63 | ||
|
|
e7ecdcc251 | ||
|
|
a70cdaadb6 | ||
|
|
d8c227c43f | ||
|
|
a87c89c83d | ||
|
|
6817ac0d79 | ||
|
|
c439a23ef9 | ||
|
|
a80d75e7e2 | ||
|
|
d2b6a47ae4 | ||
|
|
5ad0f8bb2e | ||
|
|
a9966f48af | ||
|
|
b5bac722ca | ||
|
|
8a42b606eb | ||
|
|
31f2551116 | ||
|
|
c992095959 | ||
|
|
513330cfff | ||
|
|
1136cb40a9 | ||
|
|
e73330d597 | ||
|
|
f22a12d657 | ||
|
|
d68104cecb | ||
|
|
5eb42eac3c | ||
|
|
ac8cfe24e6 | ||
|
|
bfaaf16030 | ||
|
|
c47af55bb9 | ||
|
|
3ff051f238 | ||
|
|
0a8e8dfbbb | ||
|
|
1170897587 | ||
|
|
73abb93737 | ||
|
|
0a043a6919 | ||
|
|
2c374b448a | ||
|
|
2a44b190fe | ||
|
|
3605b610fe | ||
|
|
0219118e19 | ||
|
|
5ad197278c | ||
|
|
3135ef6b7f | ||
|
|
0446b8d72f | ||
|
|
858576d870 | ||
|
|
48e50540db | ||
|
|
8eca260297 | ||
|
|
017b63fa71 | ||
|
|
efe0d3ab22 | ||
|
|
bfd54ef621 | ||
|
|
38da4c8e12 | ||
|
|
b5d33fc4b5 | ||
|
|
f5c4537afa | ||
|
|
09aed63cd4 | ||
|
|
757f886af5 | ||
|
|
f73f0d4bf9 | ||
|
|
d4f7efd08a | ||
|
|
a1aac7643a | ||
|
|
36022fb143 | ||
|
|
c70de9f73c | ||
|
|
d3d4628e29 | ||
|
|
942ab55ddc | ||
|
|
86460ffbde | ||
|
|
90d1d5400a | ||
|
|
1b151ee015 | ||
|
|
3a04136705 | ||
|
|
880fda7b40 | ||
|
|
67b992cf44 | ||
|
|
8645b4a7f6 | ||
|
|
a76b64b80b | ||
|
|
483db2bc29 | ||
|
|
bd3f626872 | ||
|
|
efd3c34a0c | ||
|
|
3e01636f77 | ||
|
|
f9c0edf4b9 |
@@ -1,14 +1,36 @@
|
||||
engines:
|
||||
version: "2"
|
||||
plugins:
|
||||
rubocop:
|
||||
enabled: true
|
||||
channel: rubocop-0-48
|
||||
channel: "rubocop-0-48"
|
||||
scss-lint:
|
||||
enabled: false
|
||||
ratings:
|
||||
paths:
|
||||
- app/**
|
||||
- lib/**
|
||||
- "**.rb"
|
||||
exclude_paths:
|
||||
- spec/**/*
|
||||
- vendor/**/*
|
||||
duplication:
|
||||
enabled: true
|
||||
exclude_patterns:
|
||||
- "db/**"
|
||||
- "config/initializers/active_record_postgresql_referential_integrity_patch.rb"
|
||||
checks:
|
||||
argument-count:
|
||||
enabled: false
|
||||
complex-logic:
|
||||
enabled: true
|
||||
file-lines:
|
||||
enabled: false
|
||||
method-complexity:
|
||||
enabled: false
|
||||
method-count:
|
||||
enabled: false
|
||||
method-lines:
|
||||
enabled: false
|
||||
nested-control-flow:
|
||||
enabled: true
|
||||
return-statements:
|
||||
enabled: true
|
||||
similar-code:
|
||||
enabled: true
|
||||
identical-code:
|
||||
enabled: true
|
||||
exclude_patterns:
|
||||
- "spec/**/*"
|
||||
- "vendor/**/*"
|
||||
|
||||
42
.github/ISSUE_TEMPLATE.md
vendored
Normal file
42
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<!--- If what you want to file is not a bug, please use the [Feature
|
||||
template](https://github.com/openfoodfoundation/openfoodnetwork/wiki/Feature-template)
|
||||
instead -->
|
||||
|
||||
<!--- Provide a general summary of the issue in the Title above -->
|
||||
|
||||
## Description
|
||||
<!--- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
|
||||
|
||||
## Expected Behavior
|
||||
<!--- Tell us what should happen -->
|
||||
|
||||
## Actual Behavior
|
||||
<!--- Tell us what happens instead -->
|
||||
|
||||
## Steps to Reproduce
|
||||
<!--- Provide an unambiguous set of steps to reproduce this bug -->
|
||||
<!--- Include code to reproduce, if relevant -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## Animated Gif/Screenshot
|
||||
<!-- Provide a screenshot or brief animated gif reproducing the bug. Linux users can use
|
||||
[Peek](https://github.com/phw/peek#ubuntu) while Mac users can use [Recordit](http://recordit.co/) -->
|
||||
|
||||
## Context
|
||||
<!--- How has this bug affected you? What were you trying to accomplish? -->
|
||||
|
||||
## Severity
|
||||
<!--- Use the [Bug severity
|
||||
guideline](https://github.com/openfoodfoundation/openfoodnetwork/wiki/Bug-severity) to assign one to this bug -->
|
||||
|
||||
## Your Environment
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
* Version used:
|
||||
* Browser name and version:
|
||||
* Operating System and version (desktop or mobile):
|
||||
|
||||
## Possible Fix
|
||||
<!--- Not obligatory, but suggest a fix or reason for the bug -->
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,5 +1,7 @@
|
||||
#### What? Why?
|
||||
|
||||
Closes #[the issue number this PR is related to]
|
||||
|
||||
[Explain why is this change needed and the solution you propose. Provide
|
||||
context for others to understand it]
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.bundle
|
||||
.rbenv-version
|
||||
.byebug_history
|
||||
.swp
|
||||
*.swo
|
||||
*.swp
|
||||
|
||||
1
.node-version
Normal file
1
.node-version
Normal file
@@ -0,0 +1 @@
|
||||
5.12.0
|
||||
12
.rubocop.yml
12
.rubocop.yml
@@ -27,6 +27,10 @@ Style/Documentation:
|
||||
Style/StringLiterals:
|
||||
Enabled: false
|
||||
|
||||
Style/HashSyntax:
|
||||
Enabled: true
|
||||
EnforcedStyle: ruby19_no_mixed_keys
|
||||
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Enabled: true
|
||||
EnforcedStyle: indented
|
||||
@@ -53,6 +57,10 @@ Lint/UselessAssignment:
|
||||
Rails/DynamicFindBy:
|
||||
Enabled: false
|
||||
|
||||
# Same as above, #find_by is not available until Rails 4
|
||||
Rails/FindBy:
|
||||
Enabled: false
|
||||
|
||||
# This should be the programmer's discretion, perhaps we should review all of
|
||||
# the uses of it an make specific exceptions though.
|
||||
Rails/SkipsModelValidations:
|
||||
@@ -143,6 +151,10 @@ Style/WordArray:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylewordarray
|
||||
|
||||
Style/SymbolArray:
|
||||
Enabled: false
|
||||
StyleGuide: https://rubocop.readthedocs.io/en/latest/cops_style/#stylesymbolarray
|
||||
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#lintambiguousregexpliteral
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,9 +22,6 @@ env:
|
||||
- CI_NODE_INDEX=3
|
||||
- CI_NODE_INDEX=4 KARMA="true" GITHUB_DEPLOY="true"
|
||||
|
||||
before_install:
|
||||
- ./script/upgrade_bundler.sh
|
||||
|
||||
before_script:
|
||||
- cp config/database.travis.yml config/database.yml
|
||||
- cp config/application.yml.example config/application.yml
|
||||
@@ -43,7 +40,6 @@ before_script:
|
||||
|
||||
script:
|
||||
- 'if [ "$KARMA" = "true" ]; then bundle exec rake karma:run; else echo "Skipping karma run"; fi'
|
||||
#- "KNAPSACK_GENERATE_REPORT=true bundle exec rspec spec"
|
||||
- "bundle exec rake 'knapsack:rspec[--tag ~performance]'"
|
||||
|
||||
after_success:
|
||||
|
||||
@@ -1,36 +1,68 @@
|
||||
See this here post on raising a github issue:
|
||||
https://community.openfoodnetwork.org/t/how-to-raise-a-github-issue/912
|
||||
|
||||
# Contributing
|
||||
We love pull requests from everyone. Any contribution is valuable, but there are two issue streams that we especially love people to work on:
|
||||
|
||||
We love pull requests from everyone. Here are some instructions for
|
||||
contributing code to Open Food Network. See the [developer wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki) for more information.
|
||||
1) Our delivery backlog, is managed via a ZenHub board (ZenHub extensions are available for most major browsers). We use a Kanban-style approach, whereby devs pick issues from the top of the backlog which has been organised according to current priorities. If you have some time and are interested in working on some issues from the backlog, please make yourself known on the [#dev](https://openfoodnetwork.slack.com/messages/C2GQ45KNU) channel on Slack and we can direct you to the most appropriate issue to pick up.
|
||||
|
||||
Fork, then clone the repo:
|
||||
2) Our list of bugs and other self-contained issues that we consider to be a good starting point for new contributors, or devs who aren’t able to commit to seeing a whole feature through. These issues are marked with the `# good first issue` label.
|
||||
|
||||
git clone git@github.com:your-username/openfoodnetwork.git
|
||||
## Set up
|
||||
|
||||
Follow the instructions in README.markdown to set up your machine.
|
||||
Set up your local development environment by following the appropriate guide from the `Development environment setup` section in the [developer wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki).
|
||||
|
||||
Make sure the tests pass:
|
||||
Add an `upstream` remote that points to the main repo:
|
||||
|
||||
rspec spec
|
||||
cd ~/location-of-your-local-ofn-repo
|
||||
git remote add upstream https://github.com/openfoodfoundation/openfoodnetwork
|
||||
|
||||
Make your change. Add tests for your change. Make the tests pass:
|
||||
If you haven't already done so, fork this repo using the `Fork` button in the top-right corner of this screen. Then ensure that your fork is listed as the `origin` remote on your local machine.
|
||||
|
||||
rspec spec
|
||||
git remote set-url origin https://github.com/your-username/openfoodnetwork
|
||||
|
||||
Push to your fork and [submit a pull request][pr].
|
||||
Fetch the latest version of `master` from `upstream` (ie. the main repo):
|
||||
|
||||
[pr]: https://github.com/openfoodfoundation/openfoodnetwork/compare/
|
||||
git fetch upstream master
|
||||
|
||||
At this point you're waiting on us. We may suggest some changes or
|
||||
improvements or alternatives.
|
||||
Create a new branch on your local machine for (based on `upstream/master`):
|
||||
|
||||
To increase the chance that your pull request is swiftly accepted:
|
||||
git checkout -b branch-name-here --no-track upstream/master
|
||||
|
||||
If you want to run the whole test suite, we recommend using a free CI service to run your tests in parallel. Running the whole suite locally in series is likely to take > 40 minutes. [TravisCI][travis] and [SemaphoreCI][semaphore] both work great in our experience. Either way, make sure the tests pass on your new branch:
|
||||
|
||||
bundle exec rspec spec
|
||||
|
||||
## Making a change
|
||||
|
||||
Make your changes to the codebase. We recommend using TDD. Add a test, make changes and get the test suite back to green.
|
||||
|
||||
bundle exec rspec spec
|
||||
|
||||
Once the tests are passing you can commit your changes. See [Making a great commit][great-commit] for more tips.
|
||||
|
||||
git add .
|
||||
git commit -m "Add a concise commit message describing your change here"
|
||||
|
||||
Push your changes to a branch on your fork:
|
||||
|
||||
git push origin branch-name-here
|
||||
|
||||
## Submitting a Pull Request
|
||||
|
||||
Use the GitHub UI to submit a [new pull request][pr] against upstream/master. To increase the chances that your pull request is swiftly accepted please have a look at our guide to [[making a great pull request]].
|
||||
|
||||
TL;DR:
|
||||
* Write tests
|
||||
* Make sure the whole test suite is passing
|
||||
* Keep your PR small, with a single focus
|
||||
* Maintain a clean commit history
|
||||
* Use a style consistent with the rest of the codebase
|
||||
* Before submitting, [rebase your work][rebase] on the current master branch
|
||||
|
||||
From here, your pull request will progress through the [Review, Test, Merge & Deploy process][process].
|
||||
|
||||
[pr]: https://github.com/openfoodfoundation/openfoodnetwork/compare/
|
||||
[great-pr]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Making-a-great-pull-request
|
||||
[great-commit]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/Making-a-great-commit
|
||||
[process]: https://github.com/openfoodfoundation/openfoodnetwork/wiki/The-process-of-review%2C-test%2C-merge-and-deploy
|
||||
[rebase]: https://www.atlassian.com/git/tutorials/merging-vs-rebasing/workflow-walkthrough
|
||||
[travis]: https://travis-ci.org/
|
||||
[semaphore]: https://semaphoreci.com/
|
||||
|
||||
44
Gemfile
44
Gemfile
@@ -1,5 +1,6 @@
|
||||
source 'https://rubygems.org'
|
||||
ruby "2.1.5"
|
||||
git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
||||
|
||||
gem 'rails', '3.2.21'
|
||||
gem 'rails-i18n', '~> 3.0.0'
|
||||
@@ -10,22 +11,27 @@ gem 'i18n-js', '~> 3.0.0'
|
||||
gem 'nokogiri', '>= 1.6.7.1'
|
||||
|
||||
gem 'pg'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: 'spree-upgrade-step1c'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: 'step-6a', ref: '86bf87f1b1e1b299edc8cd10a2486e44ba0a3987'
|
||||
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
|
||||
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '1-3-stable'
|
||||
gem 'spree_auth_devise', github: 'openfoodfoundation/spree_auth_devise', branch: 'spree-upgrade-intermediate'
|
||||
|
||||
# Our branch contains two changes
|
||||
# - Pass customer email and phone number to PayPal (merged to upstream master)
|
||||
# - Change type of password from string to password to hide it in the form
|
||||
gem 'spree_paypal_express', :github => "openfoodfoundation/better_spree_paypal_express", :branch => "hide-password"
|
||||
#gem 'spree_paypal_express', :github => "spree-contrib/better_spree_paypal_express", :branch => "1-3-stable"
|
||||
gem 'spree_paypal_express', github: "openfoodfoundation/better_spree_paypal_express", branch: "spree-upgrade-intermediate"
|
||||
#gem 'spree_paypal_express', github: "spree-contrib/better_spree_paypal_express", branch: "1-3-stable"
|
||||
gem 'stripe', '~> 3.3.1'
|
||||
gem 'activemerchant', '~> 1.71.0'
|
||||
|
||||
gem 'oauth2', '~> 1.2.0' # Used for Stripe Connect
|
||||
gem 'jwt', '~> 1.5'
|
||||
|
||||
gem 'delayed_job_active_record'
|
||||
gem 'daemons'
|
||||
|
||||
# Fix bug in simple_form preventing collection_check_boxes usage within form_for block
|
||||
# When merged, revert to upstream gem
|
||||
gem 'simple_form', :github => 'RohanM/simple_form'
|
||||
gem 'simple_form', github: 'RohanM/simple_form'
|
||||
|
||||
gem 'unicorn'
|
||||
gem 'angularjs-rails', '1.5.5'
|
||||
@@ -43,14 +49,14 @@ gem 'representative_view'
|
||||
gem 'rabl'
|
||||
gem "active_model_serializers"
|
||||
gem 'oj'
|
||||
gem 'deface', :github => 'spree/deface', :ref => '1110a13'
|
||||
gem 'deface', github: 'spree/deface', ref: '1110a13'
|
||||
gem 'paperclip'
|
||||
gem 'dalli'
|
||||
gem 'geocoder'
|
||||
gem 'gmaps4rails'
|
||||
gem 'spinjs-rails'
|
||||
gem 'rack-ssl', :require => 'rack/ssl'
|
||||
gem 'custom_error_message', :github => 'jeremydurham/custom-err-msg'
|
||||
gem 'rack-ssl', require: 'rack/ssl'
|
||||
gem 'custom_error_message', github: 'jeremydurham/custom-err-msg'
|
||||
gem 'angularjs-file-upload-rails', '~> 1.1.6'
|
||||
gem 'roadie-rails', '~> 1.0.3'
|
||||
gem 'figaro'
|
||||
@@ -96,19 +102,19 @@ gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz'
|
||||
|
||||
group :test, :development do
|
||||
# Pretty printed test output
|
||||
gem 'turn', '~> 0.8.3', :require => false
|
||||
gem 'fuubar'
|
||||
gem 'rspec-rails'
|
||||
gem 'turn', '~> 0.8.3', require: false
|
||||
gem 'fuubar', '~> 2.2.0'
|
||||
gem 'rspec-rails', ">= 3.5.2"
|
||||
gem 'shoulda-matchers'
|
||||
gem 'factory_girl_rails', :require => false
|
||||
gem 'capybara'
|
||||
gem 'database_cleaner', '0.7.1', :require => false
|
||||
gem 'factory_girl_rails', require: false
|
||||
gem 'capybara', '>= 2.15.4'
|
||||
gem 'database_cleaner', '0.7.1', require: false
|
||||
gem 'awesome_print'
|
||||
gem 'letter_opener'
|
||||
gem 'timecop'
|
||||
gem 'poltergeist'
|
||||
gem 'poltergeist', '>= 1.16.0'
|
||||
gem 'rspec-retry'
|
||||
gem 'json_spec'
|
||||
gem 'json_spec', '~> 1.1.4'
|
||||
gem 'unicorn-rails'
|
||||
gem 'atomic'
|
||||
gem 'knapsack'
|
||||
@@ -121,13 +127,15 @@ group :test do
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'pry-byebug'
|
||||
gem 'byebug', '~> 9.0.0' # 9.1 requires ruby 2.2
|
||||
gem 'pry-byebug', '>= 3.4.3'
|
||||
gem 'debugger-linecache'
|
||||
gem 'guard'
|
||||
gem 'listen', '3.0.8' # 3.1.0 requires ruby 2.2
|
||||
gem 'guard-livereload'
|
||||
gem 'rack-livereload'
|
||||
gem 'guard-rails'
|
||||
gem 'guard-rspec'
|
||||
gem 'guard-rspec', '~> 4.7.3'
|
||||
gem 'parallel_tests'
|
||||
gem 'rubocop', '>= 0.49.1'
|
||||
|
||||
|
||||
317
Gemfile.lock
317
Gemfile.lock
@@ -1,5 +1,5 @@
|
||||
GIT
|
||||
remote: git://github.com/RohanM/simple_form.git
|
||||
remote: https://github.com/RohanM/simple_form.git
|
||||
revision: 45f08a213b40f3d4bda5f5398db841137587160a
|
||||
specs:
|
||||
simple_form (2.0.2)
|
||||
@@ -7,74 +7,103 @@ GIT
|
||||
activemodel (~> 3.0)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/jeremydurham/custom-err-msg.git
|
||||
remote: https://github.com/jeremydurham/custom-err-msg.git
|
||||
revision: 3a8ec9dddc7a5b0aab7c69a6060596de300c68f4
|
||||
specs:
|
||||
custom_error_message (1.1.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/better_spree_paypal_express.git
|
||||
revision: 840d973cd5bd3250b17674a624dad494aeb09eb3
|
||||
branch: hide-password
|
||||
remote: https://github.com/openfoodfoundation/better_spree_paypal_express.git
|
||||
revision: 8d95f4544c682634812becaf50999fba0cd04df0
|
||||
branch: spree-upgrade-intermediate
|
||||
specs:
|
||||
spree_paypal_express (2.0.3)
|
||||
paypal-sdk-merchant (= 1.106.1)
|
||||
spree_core (~> 1.3.4)
|
||||
spree_core (~> 1.3.99)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/ofn-qz.git
|
||||
remote: https://github.com/openfoodfoundation/ofn-qz.git
|
||||
revision: 024680ccea429b2e5428d7b964fa67c52add34ec
|
||||
specs:
|
||||
ofn-qz (0.1.0)
|
||||
railties (~> 3.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: a4c439570b77afa50f9e36299811f293232bd281
|
||||
branch: spree-upgrade-step1c
|
||||
remote: https://github.com/openfoodfoundation/spree.git
|
||||
revision: 86bf87f1b1e1b299edc8cd10a2486e44ba0a3987
|
||||
ref: 86bf87f1b1e1b299edc8cd10a2486e44ba0a3987
|
||||
branch: step-6a
|
||||
specs:
|
||||
spree (1.3.99)
|
||||
spree_api (= 1.3.99)
|
||||
spree_backend (= 1.3.99)
|
||||
spree_cmd (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_dash (= 1.3.99)
|
||||
spree_promo (= 1.3.99)
|
||||
spree_frontend (= 1.3.99)
|
||||
spree_sample (= 1.3.99)
|
||||
spree_api (1.3.99)
|
||||
rabl (= 0.7.2)
|
||||
spree_core (= 1.3.99)
|
||||
versioncake (= 0.4.0)
|
||||
spree_backend (1.3.99)
|
||||
deface (>= 0.9.0)
|
||||
jquery-rails (~> 2.0)
|
||||
rails (~> 3.2.8)
|
||||
select2-rails (~> 3.2)
|
||||
spree_api (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
stringex (~> 1.3.2)
|
||||
spree_cmd (1.3.99)
|
||||
thor (>= 0.14.6)
|
||||
spree_core (1.3.99)
|
||||
activemerchant (~> 1.50.0)
|
||||
acts_as_list (= 0.1.4)
|
||||
activemerchant (~> 1.50)
|
||||
acts_as_list (= 0.1.9)
|
||||
awesome_nested_set (= 2.1.5)
|
||||
aws-sdk (~> 1.11.1)
|
||||
cancan (= 1.6.8)
|
||||
deface (>= 0.9.0)
|
||||
ffaker (~> 1.15.0)
|
||||
highline (= 1.6.11)
|
||||
jquery-rails (~> 2.0)
|
||||
highline (= 1.6.15)
|
||||
httparty (= 0.9.0)
|
||||
json (>= 1.5.5)
|
||||
kaminari (= 0.13.0)
|
||||
money (= 5.0.0)
|
||||
money (= 5.1.0)
|
||||
paperclip (~> 3.0)
|
||||
rabl (= 0.7.2)
|
||||
rails (~> 3.2.13)
|
||||
ransack (= 0.7.2)
|
||||
select2-rails (~> 3.2)
|
||||
state_machine (= 1.2.0)
|
||||
stringex (~> 1.3.2)
|
||||
truncate_html (= 0.9.2)
|
||||
spree_dash (1.3.99)
|
||||
httparty (~> 0.8.1)
|
||||
spree_core (= 1.3.99)
|
||||
spree_promo (1.3.99)
|
||||
httparty (~> 0.9.0)
|
||||
spree_backend (= 1.3.99)
|
||||
spree_frontend (= 1.3.99)
|
||||
spree_frontend (1.3.99)
|
||||
deface (>= 0.9.0)
|
||||
jquery-rails (~> 2.2.1)
|
||||
rails (~> 3.2.8)
|
||||
select2-rails (~> 3.2)
|
||||
spree_api (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
stringex (~> 1.3.2)
|
||||
spree_sample (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/deface.git
|
||||
remote: https://github.com/openfoodfoundation/spree_auth_devise.git
|
||||
revision: da9eecefc6fe13dedf4c6f3febec79caad839ec3
|
||||
branch: spree-upgrade-intermediate
|
||||
specs:
|
||||
spree_auth_devise (2.0.0)
|
||||
devise (~> 2.2.5)
|
||||
devise-encryptable (= 0.1.2)
|
||||
spree_backend (~> 1.3.6)
|
||||
spree_core (~> 1.3.6)
|
||||
spree_frontend (~> 1.3.6)
|
||||
|
||||
GIT
|
||||
remote: https://github.com/spree/deface.git
|
||||
revision: 1110a1336252109bce7f98f9182042e0bc2930ae
|
||||
ref: 1110a13
|
||||
specs:
|
||||
@@ -84,18 +113,7 @@ GIT
|
||||
rails (>= 3.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/spree_auth_devise.git
|
||||
revision: ba95589a85368297c844f096c2a0c121e5b08138
|
||||
branch: 1-3-stable
|
||||
specs:
|
||||
spree_auth_devise (1.3.0)
|
||||
cancan (~> 1.6.7)
|
||||
devise (~> 2.2.3)
|
||||
devise-encryptable (= 0.1.2)
|
||||
spree_core
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/spree_i18n.git
|
||||
remote: https://github.com/spree/spree_i18n.git
|
||||
revision: 752eb67204e9c5a4e22b62591a8fd55fe2285e43
|
||||
branch: 1-3-stable
|
||||
specs:
|
||||
@@ -105,7 +123,7 @@ GIT
|
||||
spree_core (>= 1.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/willrjmarshall/foundation_rails_helper.git
|
||||
remote: https://github.com/willrjmarshall/foundation_rails_helper.git
|
||||
revision: 4d5d53fdc4b1fb71e66524d298c5c635de82cfbb
|
||||
branch: rails3
|
||||
specs:
|
||||
@@ -133,8 +151,8 @@ GEM
|
||||
sprockets (~> 2.2.1)
|
||||
active_model_serializers (0.8.3)
|
||||
activemodel (>= 3.0)
|
||||
activemerchant (1.50.0)
|
||||
activesupport (>= 3.2.14, < 5.0.0)
|
||||
activemerchant (1.71.0)
|
||||
activesupport (>= 3.2.14, < 6.x)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
@@ -154,8 +172,9 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
acts-as-taggable-on (3.5.0)
|
||||
activerecord (>= 3.2, < 5)
|
||||
acts_as_list (0.1.4)
|
||||
addressable (2.3.3)
|
||||
acts_as_list (0.1.9)
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
andand (1.3.3)
|
||||
angular-rails-templates (0.2.0)
|
||||
railties (>= 3.1)
|
||||
@@ -174,33 +193,28 @@ GEM
|
||||
json (~> 1.4)
|
||||
nokogiri (>= 1.4.4)
|
||||
uuidtools (~> 2.1)
|
||||
bcrypt (3.1.7)
|
||||
bcrypt (3.1.11)
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
blockenspiel (0.4.5)
|
||||
bugsnag (4.1.0)
|
||||
builder (3.0.4)
|
||||
byebug (2.7.0)
|
||||
columnize (~> 0.3)
|
||||
debugger-linecache (~> 1.2)
|
||||
byebug (9.0.6)
|
||||
cancan (1.6.8)
|
||||
capybara (2.7.1)
|
||||
capybara (2.15.4)
|
||||
addressable
|
||||
mime-types (>= 1.16)
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
celluloid (0.15.2)
|
||||
timers (~> 1.1.0)
|
||||
chronic (0.10.2)
|
||||
chunky_png (1.3.4)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
climate_control (0.1.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coderay (1.1.2)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
@@ -208,8 +222,7 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.10.0)
|
||||
colorize (0.7.7)
|
||||
columnize (0.9.0)
|
||||
colorize (0.8.1)
|
||||
compass (1.0.3)
|
||||
chunky_png (~> 1.2)
|
||||
compass-core (~> 1.0.2)
|
||||
@@ -226,8 +239,8 @@ GEM
|
||||
compass (~> 1.0.0)
|
||||
sass-rails (<= 5.0.1)
|
||||
sprockets (< 2.13)
|
||||
crack (0.4.1)
|
||||
safe_yaml (~> 0.9.0)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
css_parser (1.3.5)
|
||||
addressable
|
||||
css_splitter (0.4.5)
|
||||
@@ -252,11 +265,11 @@ GEM
|
||||
warden (~> 1.2.1)
|
||||
devise-encryptable (0.1.2)
|
||||
devise (>= 2.1.0)
|
||||
diff-lcs (1.2.4)
|
||||
diff-lcs (1.3)
|
||||
diffy (3.1.0)
|
||||
em-websocket (0.5.0)
|
||||
em-websocket (0.5.1)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.5.3)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.2.3)
|
||||
excon (0.45.4)
|
||||
@@ -266,8 +279,10 @@ GEM
|
||||
factory_girl_rails (3.3.0)
|
||||
factory_girl (~> 3.3.0)
|
||||
railties (>= 3.0.0)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffaker (1.15.0)
|
||||
ffi (1.9.3)
|
||||
ffi (1.9.18)
|
||||
figaro (0.7.0)
|
||||
bundler (~> 1.0)
|
||||
rails (>= 3, < 5)
|
||||
@@ -388,32 +403,39 @@ GEM
|
||||
foundation-rails (5.5.0.0)
|
||||
railties (>= 3.1.0)
|
||||
sass (>= 3.2.0, < 3.4)
|
||||
fuubar (1.3.3)
|
||||
rspec (>= 2.14.0, < 3.1.0)
|
||||
fuubar (2.2.0)
|
||||
rspec-core (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
geocoder (1.1.8)
|
||||
gmaps4rails (1.5.6)
|
||||
guard (2.2.4)
|
||||
guard (2.14.1)
|
||||
formatador (>= 0.2.4)
|
||||
listen (~> 2.1)
|
||||
listen (>= 2.7, < 4.0)
|
||||
lumberjack (~> 1.0)
|
||||
nenv (~> 0.1)
|
||||
notiffany (~> 0.0)
|
||||
pry (>= 0.9.12)
|
||||
shellany (~> 0.0)
|
||||
thor (>= 0.18.1)
|
||||
guard-livereload (2.0.1)
|
||||
guard-compat (1.2.1)
|
||||
guard-livereload (2.5.2)
|
||||
em-websocket (~> 0.5)
|
||||
guard (~> 2.0)
|
||||
guard (~> 2.8)
|
||||
guard-compat (~> 1.0)
|
||||
multi_json (~> 1.8)
|
||||
guard-rails (0.4.7)
|
||||
guard (>= 0.2.2)
|
||||
guard-rspec (4.0.4)
|
||||
guard (>= 2.1.1)
|
||||
rspec (~> 2.14)
|
||||
guard-rails (0.7.2)
|
||||
guard (~> 2.11)
|
||||
guard-compat (~> 1.0)
|
||||
guard-rspec (4.7.3)
|
||||
guard (~> 2.1)
|
||||
guard-compat (~> 1.1)
|
||||
rspec (>= 2.99.0, < 4.0)
|
||||
haml (4.0.4)
|
||||
tilt
|
||||
highline (1.6.11)
|
||||
highline (1.6.15)
|
||||
hike (1.2.3)
|
||||
http_parser.rb (0.5.3)
|
||||
httparty (0.8.3)
|
||||
http_parser.rb (0.6.0)
|
||||
httparty (0.9.0)
|
||||
multi_json (~> 1.0)
|
||||
multi_xml
|
||||
i18n (0.6.11)
|
||||
@@ -426,13 +448,14 @@ GEM
|
||||
ipaddress (0.8.0)
|
||||
journey (1.0.4)
|
||||
jquery-migrate-rails (1.2.1)
|
||||
jquery-rails (2.3.0)
|
||||
jquery-rails (2.2.2)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
json_spec (1.1.1)
|
||||
json (1.8.6)
|
||||
json_spec (1.1.5)
|
||||
multi_json (~> 1.0)
|
||||
rspec (~> 2.0)
|
||||
rspec (>= 2.0, < 4.0)
|
||||
jwt (1.5.4)
|
||||
kaminari (0.13.0)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -446,27 +469,37 @@ GEM
|
||||
letter_opener (1.0.0)
|
||||
launchy (>= 2.0.4)
|
||||
libv8 (3.16.14.11)
|
||||
listen (2.2.0)
|
||||
celluloid (>= 0.15.2)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
lumberjack (1.0.4)
|
||||
listen (3.0.8)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
lumberjack (1.0.12)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
method_source (0.8.2)
|
||||
method_source (0.9.0)
|
||||
mime-types (1.25.1)
|
||||
mini_portile2 (2.0.0)
|
||||
mini_mime (0.1.4)
|
||||
mini_portile2 (2.1.0)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
money (5.0.0)
|
||||
i18n (~> 0.4)
|
||||
json
|
||||
money (5.1.0)
|
||||
i18n (~> 0.6.0)
|
||||
multi_json (1.12.1)
|
||||
multi_xml (0.5.5)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
nenv (0.3.0)
|
||||
newrelic_rpm (3.12.0.288)
|
||||
nokogiri (1.6.7.2)
|
||||
mini_portile2 (~> 2.0.0.rc2)
|
||||
nokogiri (1.6.8.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
notiffany (0.1.1)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
oauth2 (1.2.0)
|
||||
faraday (>= 0.8, < 0.10)
|
||||
jwt (~> 1.0)
|
||||
multi_json (~> 1.3)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 3)
|
||||
oj (2.1.2)
|
||||
orm_adapter (0.5.0)
|
||||
paper_trail (3.0.8)
|
||||
@@ -488,29 +521,28 @@ GEM
|
||||
paypal-sdk-merchant (1.106.1)
|
||||
paypal-sdk-core (~> 0.2.3)
|
||||
pg (0.13.2)
|
||||
poltergeist (1.9.0)
|
||||
poltergeist (1.16.0)
|
||||
capybara (~> 2.1)
|
||||
cliver (~> 0.3.1)
|
||||
multi_json (~> 1.0)
|
||||
websocket-driver (>= 0.2.0)
|
||||
polyamorous (0.5.0)
|
||||
activerecord (~> 3.0)
|
||||
polyglot (0.3.5)
|
||||
powerpack (0.1.1)
|
||||
pry (0.9.12.2)
|
||||
coderay (~> 1.0.5)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pry-byebug (1.3.2)
|
||||
byebug (~> 2.7)
|
||||
pry (~> 0.9.12)
|
||||
pry (0.11.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
pry-byebug (3.4.3)
|
||||
byebug (>= 9.0, < 9.1)
|
||||
pry (~> 0.10)
|
||||
public_suffix (3.0.0)
|
||||
rabl (0.7.2)
|
||||
activesupport (>= 2.3.14)
|
||||
multi_json (~> 1.0)
|
||||
rack (1.4.7)
|
||||
rack-cache (1.6.1)
|
||||
rack-cache (1.7.0)
|
||||
rack (>= 0.4)
|
||||
rack-livereload (0.3.15)
|
||||
rack-livereload (0.3.16)
|
||||
rack
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
@@ -537,14 +569,14 @@ GEM
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
raindrops (0.13.0)
|
||||
rake (11.3.0)
|
||||
rake (10.5.0)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
polyamorous (~> 0.5.0)
|
||||
rb-fsevent (0.9.3)
|
||||
rb-inotify (0.9.2)
|
||||
ffi (>= 0.5.0)
|
||||
rb-fsevent (0.10.2)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
redcarpet (3.2.3)
|
||||
@@ -566,23 +598,29 @@ GEM
|
||||
roo (2.7.1)
|
||||
nokogiri (~> 1)
|
||||
rubyzip (~> 1.1, < 2.0.0)
|
||||
rspec (2.14.1)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
rspec-core (2.14.4)
|
||||
rspec-expectations (2.14.0)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
rspec-mocks (2.14.2)
|
||||
rspec-rails (2.14.0)
|
||||
rspec (3.7.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-core (3.7.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-expectations (3.7.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-mocks (3.7.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-rails (3.7.1)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 2.14.0)
|
||||
rspec-expectations (~> 2.14.0)
|
||||
rspec-mocks (~> 2.14.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-retry (0.4.2)
|
||||
rspec-core
|
||||
rspec-support (3.7.0)
|
||||
rubocop (0.49.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
@@ -592,7 +630,7 @@ GEM
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-progressbar (1.8.1)
|
||||
rubyzip (1.2.0)
|
||||
safe_yaml (0.9.5)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.3.14)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
@@ -600,9 +638,9 @@ GEM
|
||||
tilt (~> 1.3)
|
||||
select2-rails (3.5.10)
|
||||
thor (~> 0.14)
|
||||
shellany (0.0.1)
|
||||
shoulda-matchers (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
slop (3.4.5)
|
||||
spinjs-rails (1.3)
|
||||
rails (>= 3.1)
|
||||
sprockets (2.2.3)
|
||||
@@ -612,23 +650,24 @@ GEM
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
state_machine (1.2.0)
|
||||
stringex (1.3.3)
|
||||
stripe (3.3.1)
|
||||
faraday (~> 0.9)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.19.1)
|
||||
thor (0.20.0)
|
||||
tilt (1.4.1)
|
||||
timecop (0.8.1)
|
||||
timers (1.1.0)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
truncate_html (0.5.5)
|
||||
truncate_html (0.9.2)
|
||||
turbo-sprockets-rails3 (0.3.6)
|
||||
railties (> 3.2.8, < 4.0.0)
|
||||
sprockets (>= 2.0.0)
|
||||
turn (0.8.3)
|
||||
ansi
|
||||
tzinfo (0.3.49)
|
||||
tzinfo (0.3.53)
|
||||
uglifier (2.7.1)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
@@ -645,12 +684,12 @@ GEM
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
warden (1.2.3)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
webmock (1.13.0)
|
||||
webmock (1.8.11)
|
||||
addressable (>= 2.2.7)
|
||||
crack (>= 0.3.2)
|
||||
websocket-driver (0.6.3)
|
||||
crack (>= 0.1.7)
|
||||
websocket-driver (0.7.0)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
whenever (0.9.2)
|
||||
@@ -658,8 +697,8 @@ GEM
|
||||
chronic (>= 0.6.3)
|
||||
wicked_pdf (1.1.0)
|
||||
wkhtmltopdf-binary (0.12.3.1)
|
||||
xml-simple (1.1.4)
|
||||
xpath (2.0.0)
|
||||
xml-simple (1.1.5)
|
||||
xpath (2.1.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
@@ -667,6 +706,7 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
active_model_serializers
|
||||
activemerchant (~> 1.71.0)
|
||||
acts-as-taggable-on (~> 3.4)
|
||||
andand
|
||||
angular-rails-templates (~> 0.2.0)
|
||||
@@ -677,7 +717,8 @@ DEPENDENCIES
|
||||
aws-sdk
|
||||
blockenspiel
|
||||
bugsnag
|
||||
capybara
|
||||
byebug (~> 9.0.0)
|
||||
capybara (>= 2.15.4)
|
||||
coffee-rails (~> 3.2.1)
|
||||
compass-rails
|
||||
css_splitter
|
||||
@@ -697,33 +738,36 @@ DEPENDENCIES
|
||||
foundation-icons-sass-rails
|
||||
foundation-rails
|
||||
foundation_rails_helper!
|
||||
fuubar
|
||||
fuubar (~> 2.2.0)
|
||||
geocoder
|
||||
gmaps4rails
|
||||
guard
|
||||
guard-livereload
|
||||
guard-rails
|
||||
guard-rspec
|
||||
guard-rspec (~> 4.7.3)
|
||||
haml
|
||||
i18n (~> 0.6.11)
|
||||
i18n-js (~> 3.0.0)
|
||||
immigrant
|
||||
jquery-migrate-rails
|
||||
jquery-rails
|
||||
json_spec
|
||||
json_spec (~> 1.1.4)
|
||||
jwt (~> 1.5)
|
||||
knapsack
|
||||
letter_opener
|
||||
listen (= 3.0.8)
|
||||
momentjs-rails
|
||||
newrelic_rpm
|
||||
nokogiri (>= 1.6.7.1)
|
||||
oauth2 (~> 1.2.0)
|
||||
ofn-qz!
|
||||
oj
|
||||
paper_trail (~> 3.0.8)
|
||||
paperclip
|
||||
parallel_tests
|
||||
pg
|
||||
poltergeist
|
||||
pry-byebug
|
||||
poltergeist (>= 1.16.0)
|
||||
pry-byebug (>= 3.4.3)
|
||||
rabl
|
||||
rack-livereload
|
||||
rack-ssl
|
||||
@@ -733,7 +777,7 @@ DEPENDENCIES
|
||||
representative_view
|
||||
roadie-rails (~> 1.0.3)
|
||||
roo (~> 2.7.0)
|
||||
rspec-rails
|
||||
rspec-rails (>= 3.5.2)
|
||||
rspec-retry
|
||||
rubocop (>= 0.49.1)
|
||||
sass (~> 3.3)
|
||||
@@ -745,6 +789,7 @@ DEPENDENCIES
|
||||
spree_auth_devise!
|
||||
spree_i18n!
|
||||
spree_paypal_express!
|
||||
stripe (~> 3.3.1)
|
||||
therubyracer
|
||||
timecop
|
||||
truncate_html
|
||||
@@ -762,4 +807,4 @@ RUBY VERSION
|
||||
ruby 2.1.5p273
|
||||
|
||||
BUNDLED WITH
|
||||
1.15.2
|
||||
1.16.0
|
||||
|
||||
46
README.md
46
README.md
@@ -45,45 +45,23 @@ You can download the source with the command:
|
||||
|
||||
### Get it running
|
||||
|
||||
For those new to Rails, the following tutorial will help get you up to speed with configuring a Rails environment: http://guides.rubyonrails.org/getting_started.html .
|
||||
For those new to Rails, the following tutorial will help get you up to speed with configuring a [Rails environment](http://guides.rubyonrails.org/getting_started.html).
|
||||
|
||||
First, check your dependencies: Ensure that you have Ruby 2.1.5 installed:
|
||||
When ready, run `script/setup`. If the script succeeds you're ready to start developing. If not, take a look at the output as it should be informative enough to help you troubleshoot.
|
||||
|
||||
ruby --version
|
||||
If you run into any other issues getting your local environment up and running please consult [the wiki](https://github.com/openfoodfoundation/openfoodnetwork/wiki).
|
||||
|
||||
Install the project's gem dependencies:
|
||||
|
||||
cd openfoodnetwork
|
||||
./script/upgrade_bundler.sh
|
||||
bundle install
|
||||
|
||||
Configure the site:
|
||||
|
||||
cp config/application.yml.example config/application.yml
|
||||
edit config/application.yml
|
||||
|
||||
Create a PostgreSQL user:
|
||||
|
||||
* Login as your system postrgresql priviledged user: `sudo -i -u postgres` (this may vary on your OS). Now your prompt looks like: `[postgres@your_host ~]$`
|
||||
* Create the `ofn` database superuser and give it the password `f00d`:
|
||||
If still you get stuck do not hesitate to open an issue reporting the full output of the script.
|
||||
|
||||
Now, your dreams of spinning up a development server can be realised:
|
||||
```
|
||||
createuser -s -P ofn
|
||||
bundle exec rails server
|
||||
```
|
||||
To login as Spree default user, use:
|
||||
```
|
||||
email: spree@example.com
|
||||
password: spree123
|
||||
```
|
||||
|
||||
Create the development and test databases, using the settings specified in `config/database.yml`, and populate them with a schema and seed data:
|
||||
|
||||
rake db:setup
|
||||
|
||||
Load some default data for your environment:
|
||||
|
||||
rake openfoodnetwork:dev:load_sample_data
|
||||
|
||||
At long last, your dreams of spinning up a development server can be realised:
|
||||
|
||||
rails server
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
Tests, both unit and integration, are based on RSpec. To run the test suite, first prepare the test database:
|
||||
@@ -123,7 +101,7 @@ Do not forget to run `rake tmp:cache:clear` after locales are updated to reload
|
||||
* Maikel Linke (https://github.com/mkllnk)
|
||||
* Lynne Davis (https://github.com/lin-d-hop)
|
||||
* Paul Mackay (https://github.com/pmackay)
|
||||
* Steve Petitt (https://github.com/stveep)
|
||||
* Steve Pettitt (https://github.com/stveep)
|
||||
|
||||
|
||||
## Licence
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
//= require angular-resource
|
||||
//= require angular-animate
|
||||
//= require angular-sanitize
|
||||
//= require admin/spree_core
|
||||
//= require admin/spree_backend
|
||||
//= require admin/spree_auth
|
||||
//= require admin/spree_promo
|
||||
//= require admin/spree_paypal_express
|
||||
//= require ../shared/ng-infinite-scroll.min.js
|
||||
//= require ../shared/ng-tags-input.min.js
|
||||
@@ -50,6 +49,14 @@
|
||||
//= require textAngular.min.js
|
||||
//= require i18n/translations
|
||||
//= require darkswarm/i18n.translate.js
|
||||
|
||||
//
|
||||
//= require moment
|
||||
//= require moment/en-gb.js
|
||||
//= require moment/es.js
|
||||
//= require moment/fr.js
|
||||
//= require moment/it.js
|
||||
//= require moment/nb.js
|
||||
//= require moment/pt-br.js
|
||||
//= require moment/sv.js
|
||||
|
||||
//= require_tree .
|
||||
|
||||
@@ -32,7 +32,6 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
$scope.filteredProducts = []
|
||||
$scope.currentFilters = []
|
||||
$scope.limit = 15
|
||||
$scope.productsWithUnsavedVariants = []
|
||||
$scope.query = ""
|
||||
$scope.DisplayProperties = DisplayProperties
|
||||
|
||||
@@ -114,7 +113,6 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
display_name: null
|
||||
on_hand: null
|
||||
price: null
|
||||
$scope.productsWithUnsavedVariants.push product
|
||||
DisplayProperties.setShowVariants product.id, true
|
||||
|
||||
|
||||
@@ -196,7 +194,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
filters: $scope.currentFilters
|
||||
).success((data) ->
|
||||
DirtyProducts.clear()
|
||||
BulkProducts.updateVariantLists(data.products, $scope.productsWithUnsavedVariants)
|
||||
BulkProducts.updateVariantLists(data.products || [])
|
||||
$timeout -> $scope.displaySuccess()
|
||||
).error (data, status) ->
|
||||
if status == 400 && data.errors? && data.errors.length > 0
|
||||
|
||||
@@ -1 +1 @@
|
||||
angular.module("admin.dropdown", ['templates'])
|
||||
angular.module("admin.dropdown", ['admin.utils'])
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
angular.module("admin.enterpriseRoles", [])
|
||||
@@ -4,10 +4,8 @@ angular.module("admin.enterprises")
|
||||
$scope.PaymentMethods = EnterprisePaymentMethods.paymentMethods
|
||||
$scope.ShippingMethods = EnterpriseShippingMethods.shippingMethods
|
||||
$scope.navClear = NavigationCheck.clear
|
||||
$scope.pristineEmail = $scope.Enterprise.email
|
||||
$scope.menu = SideMenu
|
||||
$scope.newManager = { id: '', email: (t('add_manager')) }
|
||||
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'enterprise_form.$dirty', (newValue) ->
|
||||
@@ -36,6 +34,8 @@ angular.module("admin.enterprises")
|
||||
|
||||
$scope.removeManager = (manager) ->
|
||||
if manager.id?
|
||||
if manager.id == $scope.Enterprise.owner.id or manager.id == parseInt($scope.receivesNotifications)
|
||||
return
|
||||
for i, user of $scope.Enterprise.users when user.id == manager.id
|
||||
$scope.Enterprise.users.splice i, 1
|
||||
if $scope.enterprise_form?
|
||||
@@ -46,6 +46,7 @@ angular.module("admin.enterprises")
|
||||
manager =
|
||||
id: manager.id
|
||||
email: manager.email
|
||||
confirmed: manager.confirmed
|
||||
if (user for user in $scope.Enterprise.users when user.id == manager.id).length == 0
|
||||
$scope.Enterprise.users.push manager
|
||||
else
|
||||
|
||||
@@ -22,7 +22,7 @@ angular.module("admin.enterprises")
|
||||
{ name: 'users', label: t('users'), icon_class: "icon-user" }
|
||||
]
|
||||
|
||||
$scope.select(0)
|
||||
SideMenu.init()
|
||||
|
||||
$scope.showItem = (item) ->
|
||||
if item.show?
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
angular.module("admin.paymentMethods").controller "StripeController", ($scope, $http, shops) ->
|
||||
$scope.shops = shops
|
||||
$scope.stripe_account = {}
|
||||
|
||||
$scope.$watch "paymentMethod.preferred_enterprise_id", (newID, oldID) ->
|
||||
return unless newID?
|
||||
$scope.stripe_account = {}
|
||||
$http.get("/admin/stripe_accounts/status.json?enterprise_id=#{newID}").success (data) ->
|
||||
angular.extend($scope.stripe_account, data)
|
||||
.error (response) ->
|
||||
$scope.stripe_account.status = "request_failed"
|
||||
|
||||
$scope.current_enterprise_stripe_path = ->
|
||||
return unless $scope.paymentMethod.preferred_enterprise_id?
|
||||
permalink = shops.filter((shop) ->
|
||||
shop.id == $scope.paymentMethod.preferred_enterprise_id
|
||||
)[0].permalink
|
||||
"/admin/enterprises/#{permalink}/edit#/payment_methods"
|
||||
33
app/assets/javascripts/admin/payments/new.js
Normal file
33
app/assets/javascripts/admin/payments/new.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// Override of Spree's logic in the file of the same name
|
||||
// Changes made as per https://github.com/spree/spree/commit/8a3a80b08abf80fbed2fcee4b429ba1caf68baf1
|
||||
// which allows the form partial in admin/payments/new to be switched using radio buttons
|
||||
// We can remove this file when we reach 2.3.0
|
||||
|
||||
$(document).ready(function() {
|
||||
if ($("#new_payment").is("*")) {
|
||||
$('.payment_methods_radios').click(
|
||||
function() {
|
||||
$('.payment-methods').hide();
|
||||
if (this.checked) {
|
||||
$('#payment_method_' + this.value).show();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('.payment_methods_radios').each(
|
||||
function() {
|
||||
if (this.checked) {
|
||||
$('#payment_method_' + this.value).show();
|
||||
} else {
|
||||
$('#payment_method_' + this.value).hide();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$(".card_new").radioControlsVisibilityOfElement('.card_form');
|
||||
|
||||
$('select.jump_menu').change(function(){
|
||||
window.location = this.options[this.selectedIndex].value;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -12,11 +12,10 @@ angular.module("admin.products").factory "VariantUnitManager", ->
|
||||
|
||||
@variantUnitOptions: ->
|
||||
options = for unit_type, scale_with_name of @unitNames
|
||||
unit_type_cap = unit_type[0].toUpperCase() + unit_type[1..-1]
|
||||
for scale in @unitScales(unit_type)
|
||||
name = @getUnitName(scale, unit_type)
|
||||
["#{unit_type_cap} (#{name})", "#{unit_type}_#{scale}"]
|
||||
options.push [['Items', 'items']]
|
||||
["#{I18n.t(unit_type)} (#{name})", "#{unit_type}_#{scale}"]
|
||||
options.push [[I18n.t('items'), 'items']]
|
||||
[].concat options...
|
||||
|
||||
@getScale: (value, unitType) ->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module("admin.resources").factory 'LineItemResource', ($resource) ->
|
||||
$resource('/admin/:orders/:order_number/line_items/:id.json', {}, {
|
||||
$resource('/admin/bulk_line_items/:id.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
isArray: true
|
||||
|
||||
@@ -26,7 +26,7 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
save: (lineItem) ->
|
||||
deferred = $q.defer()
|
||||
lineItem.errors = {}
|
||||
lineItem.$update({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
|
||||
lineItem.$update({id: lineItem.id})
|
||||
.then( (data) =>
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
deferred.resolve(data)
|
||||
@@ -54,7 +54,7 @@ angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
|
||||
delete: (lineItem, callback=null) ->
|
||||
deferred = $q.defer()
|
||||
lineItem.$delete({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
|
||||
lineItem.$delete({id: lineItem.id})
|
||||
.then( (data) =>
|
||||
delete @byID[lineItem.id]
|
||||
delete @pristineByID[lineItem.id]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher) ->
|
||||
angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher, $http) ->
|
||||
new class BulkProducts
|
||||
products: []
|
||||
|
||||
@@ -11,20 +11,14 @@ angular.module("ofn.admin").factory "BulkProducts", (PagedFetcher, dataFetcher)
|
||||
PagedFetcher.fetch url, (data) => @addProducts data.products
|
||||
|
||||
cloneProduct: (product) ->
|
||||
dataFetcher("/admin/products/" + product.permalink_live + "/clone.json").then (data) =>
|
||||
# Ideally we would use Spree's built in respond_override helper here to redirect the
|
||||
# user after a successful clone with .json in the accept headers
|
||||
# However, at the time of writing there appears to be an issue which causes the
|
||||
# respond_with block in the destroy action of Spree::Admin::Product to break
|
||||
# when a respond_overrride for the clone action is used.
|
||||
id = data.product.id
|
||||
dataFetcher("/api/products/" + id + "?template=bulk_show").then (newProduct) =>
|
||||
$http.post("/api/products/" + product.id + "/clone").success (data) =>
|
||||
dataFetcher("/api/products/" + data.id + "?template=bulk_show").then (newProduct) =>
|
||||
@unpackProduct newProduct
|
||||
@insertProductAfter(product, newProduct)
|
||||
|
||||
updateVariantLists: (serverProducts, productsWithUnsavedVariants) ->
|
||||
for product in productsWithUnsavedVariants
|
||||
server_product = @findProductInList(product.id, serverProducts)
|
||||
updateVariantLists: (serverProducts) ->
|
||||
for server_product in serverProducts
|
||||
product = @findProductInList(server_product.id, @products)
|
||||
product.variants = server_product.variants
|
||||
@loadVariantUnitValues product
|
||||
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
angular.module("admin.side_menu")
|
||||
.factory "SideMenu", ->
|
||||
.factory "SideMenu", ($location) ->
|
||||
new class SideMenu
|
||||
items: []
|
||||
selected: null
|
||||
|
||||
|
||||
# Checks for path and uses it to set the view
|
||||
# If no path, loads first view
|
||||
init: =>
|
||||
path = $location.path()?.match(/^\/\w+$/)?[0]
|
||||
index = if path
|
||||
name = path[1..]
|
||||
@items.indexOf(@find_by_name(name))
|
||||
else
|
||||
0
|
||||
@select(index)
|
||||
|
||||
setItems: (items) =>
|
||||
@items = items
|
||||
item.visible = true for item in @items
|
||||
@@ -13,6 +25,7 @@ angular.module("admin.side_menu")
|
||||
@selected.selected = false if @selected
|
||||
@selected = @items[index]
|
||||
@selected.selected = true
|
||||
$location.path(@selected.name)
|
||||
|
||||
find_by_name: (name) =>
|
||||
for item in @items when item.name is name
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout, $filter) ->
|
||||
angular.module("admin.utils").directive "ofnSelect2", ($sanitize, $timeout, $filter) ->
|
||||
require: 'ngModel'
|
||||
restrict: 'C'
|
||||
scope:
|
||||
@@ -23,7 +23,16 @@
|
||||
#
|
||||
#= require angular-backstretch.js
|
||||
#= require angular-flash.min.js
|
||||
#
|
||||
#= require moment
|
||||
#= require moment/en-gb.js
|
||||
#= require moment/es.js
|
||||
#= require moment/fr.js
|
||||
#= require moment/it.js
|
||||
#= require moment/nb.js
|
||||
#= require moment/pt-br.js
|
||||
#= require moment/sv.js
|
||||
#
|
||||
#= require modernizr
|
||||
#
|
||||
#= require foundation
|
||||
|
||||
@@ -10,4 +10,11 @@ Darkswarm.controller "LoginCtrl", ($scope, $http, $window, AuthenticationService
|
||||
$window.location.href = $window.location.origin + $window.location.pathname # Strips out hash fragments
|
||||
.error (data) ->
|
||||
Loading.clear()
|
||||
$scope.errors = data.message
|
||||
$scope.errors = data.message || data.error
|
||||
$scope.user_unconfirmed = (data.error == t('devise.failure.unconfirmed'))
|
||||
|
||||
$scope.resend_confirmation = ->
|
||||
$http.post("/user/spree_user/confirmation", {spree_user: $scope.spree_user}).success (data)->
|
||||
$scope.messages = t('devise.confirmations.send_instructions')
|
||||
.error (data) ->
|
||||
$scope.errors = t('devise.confirmations.failed_to_send')
|
||||
@@ -1,15 +1,15 @@
|
||||
Darkswarm.controller "SignupCtrl", ($scope, $http, $window, $location, Redirections, AuthenticationService) ->
|
||||
$scope.path = "/signup"
|
||||
|
||||
$scope.spree_user.password_confirmation = ''
|
||||
|
||||
$scope.errors =
|
||||
email: null
|
||||
password: null
|
||||
|
||||
$scope.submit = ->
|
||||
$http.post("/user/spree_user", {spree_user: $scope.spree_user}).success (data)->
|
||||
if Redirections.after_login
|
||||
$window.location.href = $window.location.origin + Redirections.after_login
|
||||
else
|
||||
$window.location.href = $window.location.origin + $window.location.pathname # Strips out hash fragments
|
||||
$scope.errors = {email: null, password: null}
|
||||
$scope.messages = t('devise.user_registrations.spree_user.signed_up_but_unconfirmed')
|
||||
.error (data) ->
|
||||
$scope.errors = data
|
||||
|
||||
@@ -3,23 +3,23 @@ Darkswarm.controller "AccordionCtrl", ($scope, localStorageService, $timeout, $d
|
||||
value = if localStorageService.get(key) then {} else { details: true, billing: false, shipping: false, payment: false }
|
||||
localStorageService.bind $scope, "accordion", value, key
|
||||
$scope.accordionSections = ["details", "billing", "shipping", "payment"]
|
||||
# Scrolling is confused by our position:fixed top bar - add an offset to scroll
|
||||
# to the correct location, plus 5px buffer
|
||||
offset_height = $("nav.top-bar").height() + 5
|
||||
|
||||
$scope.show = (section)->
|
||||
$scope.accordion[section] = true
|
||||
# If we call scrollTo() directly after show(), when one of the accordions above the
|
||||
# scroll location is closed by show(), scrollTo() will scroll to the old location of
|
||||
# the element. Putting this in a 50 ms timeout is enough delay for the DOM to
|
||||
# have updated.
|
||||
$timeout ->
|
||||
$document.scrollTo($("##{section}"), offset_height, 500)
|
||||
, 50
|
||||
|
||||
$scope.$on 'purchaseFormInvalid', (event, form) ->
|
||||
# Scroll to first invalid section
|
||||
for section in $scope.accordionSections
|
||||
if not form[section].$valid
|
||||
$scope.show section
|
||||
|
||||
# If we call scrollTo() directly after show(), when one of the accordions above the
|
||||
# scroll location is closed by show(), scrollTo() will scroll to the old location of
|
||||
# the element. Putting this in a zero-length timeout is enough delay for the DOM to
|
||||
# have updated.
|
||||
$timeout ->
|
||||
# Scrolling is confused by our position:fixed top bar - add an offset to scroll
|
||||
# to the correct location, plus 5px buffer
|
||||
offset_height = $("nav.top-bar").height() + 5
|
||||
$document.scrollTo $("##{section}"), offset_height, 500
|
||||
break
|
||||
|
||||
@@ -22,6 +22,6 @@ Darkswarm.controller "CheckoutCtrl", ($scope, localStorageService, Checkout, Cur
|
||||
event.preventDefault()
|
||||
$scope.submitted = true
|
||||
if form.$valid
|
||||
$scope.Checkout.submit()
|
||||
$scope.Checkout.purchase()
|
||||
else
|
||||
$scope.$broadcast 'purchaseFormInvalid', form
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
Darkswarm.controller "PaymentCtrl", ($scope, $timeout) ->
|
||||
Darkswarm.controller "PaymentCtrl", ($scope, $timeout, savedCreditCards, Dates) ->
|
||||
angular.extend(this, new FieldsetMixin($scope))
|
||||
|
||||
$scope.savedCreditCards = savedCreditCards
|
||||
$scope.name = "payment"
|
||||
$scope.months = Dates.months
|
||||
$scope.years = Dates.years
|
||||
|
||||
$scope.months = [
|
||||
{key: t("january"), value: "1"},
|
||||
{key: t("february"), value: "2"},
|
||||
{key: t("march"), value: "3"},
|
||||
{key: t("april"), value: "4"},
|
||||
{key: t("may"), value: "5"},
|
||||
{key: t("june"), value: "6"},
|
||||
{key: t("july"), value: "7"},
|
||||
{key: t("august"), value: "8"},
|
||||
{key: t("september"), value: "9"},
|
||||
{key: t("october"), value: "10"},
|
||||
{key: t("november"), value: "11"},
|
||||
{key: t("december"), value: "12"},
|
||||
]
|
||||
|
||||
$scope.years = [moment().year()..(moment().year()+15)]
|
||||
$scope.secrets.card_month = "1"
|
||||
$scope.secrets.card_year = moment().year()
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Darkswarm.controller "CreditCardsCtrl", ($scope, $timeout, CreditCard, CreditCards, Dates) ->
|
||||
angular.extend(this, new FieldsetMixin($scope))
|
||||
$scope.savedCreditCards = CreditCards.saved
|
||||
$scope.CreditCard = CreditCard
|
||||
$scope.secrets = CreditCard.secrets
|
||||
$scope.showForm = CreditCard.show
|
||||
$scope.storeCard = ->
|
||||
if $scope.new_card_form.$valid
|
||||
CreditCard.requestToken()
|
||||
|
||||
$scope.allow_name_change = true
|
||||
$scope.disable_fields = false
|
||||
@@ -1,9 +0,0 @@
|
||||
Darkswarm.controller "DistributorNodeCtrl", ($scope, HashNavigation, $anchorScroll) ->
|
||||
$scope.toggle = ->
|
||||
HashNavigation.toggle $scope.distributor.hash
|
||||
|
||||
$scope.open = ->
|
||||
HashNavigation.active($scope.distributor.hash)
|
||||
|
||||
if $scope.open()
|
||||
$anchorScroll()
|
||||
@@ -6,10 +6,9 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location
|
||||
$scope.openModal = EnterpriseModal.open
|
||||
$scope.activeTaxons = []
|
||||
$scope.show_profiles = false
|
||||
$scope.show_closed = false
|
||||
$scope.filtersActive = false
|
||||
$scope.distanceMatchesShown = false
|
||||
$scope.filterExpression = {active: true}
|
||||
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
Enterprises.flagMatching query
|
||||
@@ -36,7 +35,7 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location
|
||||
# When filter settings change, this could change which name match is at the top, or even
|
||||
# result in no matches. This affects the reference point that the distance matches are
|
||||
# calculated from, so we need to recalculate distances.
|
||||
$scope.$watch '[activeTaxons, activeProperties, shippingTypes, show_profiles]', ->
|
||||
$scope.$watch '[activeTaxons, activeProperties, shippingTypes, show_profiles, show_closed]', ->
|
||||
$timeout ->
|
||||
Enterprises.calculateDistance $scope.query, $scope.firstNameMatch()
|
||||
$rootScope.$broadcast 'enterprisesChanged'
|
||||
@@ -74,9 +73,9 @@ Darkswarm.controller "EnterprisesCtrl", ($scope, $rootScope, $timeout, $location
|
||||
undefined
|
||||
|
||||
$scope.showClosedShops = ->
|
||||
delete $scope.filterExpression['active']
|
||||
$scope.show_closed = true
|
||||
$location.search('show_closed', '1')
|
||||
|
||||
$scope.hideClosedShops = ->
|
||||
$scope.filterExpression['active'] = true
|
||||
$scope.show_closed = false
|
||||
$location.search('show_closed', null)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Darkswarm.controller "OrdersCtrl", ($scope, $rootScope, $timeout, Orders, Search, $document, HashNavigation, FilterSelectorsService, EnterpriseModal, enterpriseMatchesNameQueryFilter, distanceWithinKmFilter) ->
|
||||
Darkswarm.controller "OrdersCtrl", ($scope, Orders) ->
|
||||
$scope.Orders = Orders
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
Darkswarm.controller "RegistrationFormCtrl", ($scope, RegistrationService, EnterpriseRegistrationService) ->
|
||||
$scope.submitted = false
|
||||
$scope.isDisabled = false
|
||||
|
||||
$scope.valid = (form) ->
|
||||
$scope.submitted = !form.$valid
|
||||
form.$valid
|
||||
|
||||
$scope.create = (form) ->
|
||||
EnterpriseRegistrationService.create() if $scope.valid(form)
|
||||
$scope.disableButton()
|
||||
EnterpriseRegistrationService.create($scope.enableButton) if $scope.valid(form)
|
||||
|
||||
$scope.update = (nextStep, form) ->
|
||||
EnterpriseRegistrationService.update(nextStep) if $scope.valid(form)
|
||||
|
||||
$scope.selectIfValid = (nextStep, form) ->
|
||||
RegistrationService.select(nextStep) if $scope.valid(form)
|
||||
|
||||
$scope.disableButton = ->
|
||||
$scope.isDisabled = true
|
||||
|
||||
$scope.enableButton = ->
|
||||
$scope.isDisabled = false
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Darkswarm.controller "ShopNodeCtrl", ($scope, HashNavigation, $anchorScroll) ->
|
||||
$scope.toggle = ->
|
||||
HashNavigation.toggle $scope.shop.hash
|
||||
|
||||
$scope.open = ->
|
||||
HashNavigation.active($scope.shop.hash)
|
||||
|
||||
if $scope.open()
|
||||
$anchorScroll()
|
||||
@@ -0,0 +1,35 @@
|
||||
Darkswarm.directive "stripeElements", ($injector, StripeElements) ->
|
||||
restrict: 'E'
|
||||
template: "<label for='card-element'>\
|
||||
<div id='card-element'></div>\
|
||||
<div id='card-errors' class='error'></div>\
|
||||
</label>"
|
||||
|
||||
link: (scope, elem, attr)->
|
||||
if $injector.has('stripeObject')
|
||||
stripe = $injector.get('stripeObject')
|
||||
|
||||
card = stripe.elements().create 'card',
|
||||
hidePostalCode: false
|
||||
style:
|
||||
base:
|
||||
fontFamily: "Roboto, Arial, sans-serif"
|
||||
fontSize: '16px'
|
||||
color: '#5c5c5c'
|
||||
'::placeholder':
|
||||
color: '#6c6c6c'
|
||||
card.mount('#card-element')
|
||||
|
||||
# Elements validates user input as it is typed. To help your customers
|
||||
# catch mistakes, you should listen to change events on the card Element
|
||||
# and display any errors:
|
||||
card.addEventListener 'change', (event) ->
|
||||
displayError = document.getElementById('card-errors')
|
||||
if event.error
|
||||
displayError.textContent = event.error.message
|
||||
else
|
||||
displayError.textContent = ''
|
||||
return
|
||||
|
||||
StripeElements.stripe = stripe
|
||||
StripeElements.card = card
|
||||
12
app/assets/javascripts/darkswarm/directives/tab.js.coffee
Normal file
12
app/assets/javascripts/darkswarm/directives/tab.js.coffee
Normal file
@@ -0,0 +1,12 @@
|
||||
Darkswarm.directive "tab", ->
|
||||
restrict: "C"
|
||||
require: "^^tabsetCtrl"
|
||||
scope:
|
||||
name: "@"
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
element.on "click", ->
|
||||
scope.$apply ->
|
||||
ctrl.toggle(scope.name)
|
||||
|
||||
ctrl.registerSelectionListener (prefix, selection) ->
|
||||
element.toggleClass('selected', selection == scope.name)
|
||||
15
app/assets/javascripts/darkswarm/directives/tab_view.coffee
Normal file
15
app/assets/javascripts/darkswarm/directives/tab_view.coffee
Normal file
@@ -0,0 +1,15 @@
|
||||
Darkswarm.directive "tabView", ->
|
||||
restrict: "C"
|
||||
require: "^^tabsetCtrl"
|
||||
template: "<div ng-include='template'></div>"
|
||||
scope:
|
||||
templates: "="
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
scope.template = null
|
||||
|
||||
ctrl.registerSelectionListener (prefix, selection) ->
|
||||
if selection?
|
||||
selection = "#{prefix}/#{selection}" if prefix?
|
||||
scope.template = "#{selection}.html"
|
||||
else
|
||||
scope.template = null
|
||||
@@ -0,0 +1,28 @@
|
||||
Darkswarm.directive "tabsetCtrl", (Tabsets, $location) ->
|
||||
restrict: "C"
|
||||
scope:
|
||||
id: "@"
|
||||
selected: "@"
|
||||
navigate: "="
|
||||
prefix: "@?"
|
||||
controller: ($scope, $element) ->
|
||||
if $scope.navigate
|
||||
path = $location.path()?.match(/^\/\w+$/)?[0]
|
||||
$scope.selected = path[1..] if path
|
||||
|
||||
this.toggle = (name) ->
|
||||
Tabsets.toggle($scope.id, name)
|
||||
|
||||
this.select = (selection) ->
|
||||
$scope.$broadcast("selection:changed", selection)
|
||||
$element.toggleClass("expanded", selection?)
|
||||
$location.path(selection) if $scope.navigate
|
||||
|
||||
this.registerSelectionListener = (callback) ->
|
||||
$scope.$on "selection:changed", (event, selection) ->
|
||||
callback($scope.prefix, selection)
|
||||
|
||||
this
|
||||
|
||||
link: (scope, element, attrs, ctrl) ->
|
||||
Tabsets.register(ctrl, scope.id, scope.selected)
|
||||
@@ -0,0 +1,7 @@
|
||||
Darkswarm.filter 'closedShops', ->
|
||||
(enterprises, show_closed) ->
|
||||
enterprises ||= []
|
||||
show_closed ?= false
|
||||
|
||||
enterprises.filter (enterprise) =>
|
||||
show_closed or enterprise.active or !enterprise.is_distributor
|
||||
@@ -3,13 +3,12 @@ Darkswarm.filter "localizeCurrency", (currencyConfig)->
|
||||
(amount) ->
|
||||
# Set country code (eg. "US").
|
||||
currency_code = if currencyConfig.display_currency then " " + currencyConfig.currency else ""
|
||||
# Set decimal points, 2 or 0 if hide_cents.
|
||||
# Set decimal points, 2 or 0 if hide_cents.
|
||||
decimals = if currencyConfig.hide_cents == "true" then 0 else 2
|
||||
# We need to use parseFloat before toFixed as the amount should come in as a string.
|
||||
amount_fixed = parseFloat(amount).toFixed(decimals)
|
||||
# Set format if the currency symbol should come after the number, otherwise (default) use the locale setting.
|
||||
format = if currencyConfig.symbol_position == "after" then "%n %u" else undefined
|
||||
# We need to use parseFloat as the amount should come in as a string.
|
||||
amount = parseFloat(amount)
|
||||
|
||||
# Build the final price string. TODO use spree decimal point and spacer character settings.
|
||||
if currencyConfig.symbol_position == 'before'
|
||||
currencyConfig.symbol + amount_fixed + currency_code
|
||||
else
|
||||
amount_fixed + " " + currencyConfig.symbol + currency_code
|
||||
# Build the final price string.
|
||||
I18n.toCurrency(amount, {precision: decimals, unit: currencyConfig.symbol, format: format}) + currency_code
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# Old aliases before i18n-js was introduced.
|
||||
# TODO - delete it after everything is moved to i18n-js
|
||||
|
||||
# Declares the translation function t.
|
||||
# You can use translate('login') or t('login') in Javascript.
|
||||
window.translate = (key, options = {}) ->
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
window.FieldsetMixin = ($scope)->
|
||||
$scope.next = (event = false)->
|
||||
event.preventDefault() if event
|
||||
return unless $scope.nextPanel
|
||||
$scope.show $scope.nextPanel
|
||||
|
||||
$scope.onTimeout = ->
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
Darkswarm.factory 'Checkout', (CurrentOrder, ShippingMethods, PaymentMethods, $http, Navigation, CurrentHub, RailsFlashLoader, Loading)->
|
||||
Darkswarm.factory 'Checkout', ($injector, CurrentOrder, ShippingMethods, StripeElements, PaymentMethods, $http, Navigation, CurrentHub, RailsFlashLoader, Loading)->
|
||||
new class Checkout
|
||||
errors: {}
|
||||
secrets: {}
|
||||
order: CurrentOrder.order
|
||||
|
||||
submit: ->
|
||||
purchase: ->
|
||||
if @paymentMethod()?.method_type == 'stripe' && !@secrets.selected_card
|
||||
StripeElements.requestToken(@secrets, @submit)
|
||||
else
|
||||
@submit()
|
||||
|
||||
submit: =>
|
||||
Loading.message = t 'submitting_order'
|
||||
$http.put('/checkout', {order: @preprocess()}).success (data, status)=>
|
||||
$http.put('/checkout.json', {order: @preprocess()}).success (data, status)=>
|
||||
Navigation.go data.path
|
||||
.error (response, status)=>
|
||||
if response.path
|
||||
@@ -53,6 +59,23 @@ Darkswarm.factory 'Checkout', (CurrentOrder, ShippingMethods, PaymentMethods, $h
|
||||
last_name: @order.bill_address.lastname
|
||||
}
|
||||
|
||||
if @paymentMethod()?.method_type == 'stripe'
|
||||
if @secrets.selected_card
|
||||
angular.extend munged_order, {
|
||||
existing_card_id: @secrets.selected_card
|
||||
}
|
||||
else
|
||||
angular.extend munged_order.payments_attributes[0], {
|
||||
source_attributes:
|
||||
gateway_payment_profile_id: @secrets.token
|
||||
cc_type: @secrets.cc_type
|
||||
last_digits: @secrets.card.last4
|
||||
month: @secrets.card.exp_month
|
||||
year: @secrets.card.exp_year
|
||||
first_name: @order.bill_address.firstname
|
||||
last_name: @order.bill_address.lastname
|
||||
save_requested_by_customer: @secrets.save_requested_by_customer
|
||||
}
|
||||
munged_order
|
||||
|
||||
shippingMethod: ->
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
Darkswarm.factory 'CreditCard', ($injector, $rootScope, CreditCards, StripeElements, Navigation, $http, RailsFlashLoader, Loading)->
|
||||
new class CreditCard
|
||||
visible: false
|
||||
errors: {}
|
||||
secrets: {}
|
||||
|
||||
requestToken: =>
|
||||
@setFullName()
|
||||
StripeElements.requestToken(@secrets, @submit, t("saving_credit_card"))
|
||||
|
||||
submit: =>
|
||||
params = @process_params()
|
||||
$http.put('/credit_cards/new_from_token', params )
|
||||
.success (data, status) =>
|
||||
Loading.clear()
|
||||
@reset()
|
||||
CreditCards.add(data)
|
||||
.error (response, status) =>
|
||||
if response.path
|
||||
Navigation.go response.path
|
||||
else
|
||||
Loading.clear()
|
||||
@errors = response.errors
|
||||
RailsFlashLoader.loadFlash(response.flash)
|
||||
|
||||
setFullName: ->
|
||||
@secrets.name = "#{@secrets.first_name} #{@secrets.last_name}"
|
||||
|
||||
process_params: ->
|
||||
{"exp_month": @secrets.card.exp_month,
|
||||
"exp_year": @secrets.card.exp_year,
|
||||
"last4": @secrets.card.last4,
|
||||
"token": @secrets.token,
|
||||
"cc_type": @secrets.cc_type}
|
||||
|
||||
show: => @visible = true
|
||||
|
||||
reset: =>
|
||||
@visible = false
|
||||
delete @secrets[k] for k, v of @secrets
|
||||
delete @errors[k] for k, v of @errors
|
||||
@@ -0,0 +1,6 @@
|
||||
Darkswarm.factory 'CreditCards', (savedCreditCards)->
|
||||
new class CreditCard
|
||||
saved: savedCreditCards
|
||||
|
||||
add: (card) ->
|
||||
@saved.push card
|
||||
18
app/assets/javascripts/darkswarm/services/dates.js.coffee
Normal file
18
app/assets/javascripts/darkswarm/services/dates.js.coffee
Normal file
@@ -0,0 +1,18 @@
|
||||
Darkswarm.factory "Dates", ->
|
||||
new class Dates
|
||||
months: [
|
||||
{key: t("january"), value: "1"},
|
||||
{key: t("february"), value: "2"},
|
||||
{key: t("march"), value: "3"},
|
||||
{key: t("april"), value: "4"},
|
||||
{key: t("may"), value: "5"},
|
||||
{key: t("june"), value: "6"},
|
||||
{key: t("july"), value: "7"},
|
||||
{key: t("august"), value: "8"},
|
||||
{key: t("september"), value: "9"},
|
||||
{key: t("october"), value: "10"},
|
||||
{key: t("november"), value: "11"},
|
||||
{key: t("december"), value: "12"},
|
||||
]
|
||||
|
||||
years: [moment().year()..(moment().year()+15)]
|
||||
@@ -2,7 +2,6 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
|
||||
new class EnterpriseRegistrationService
|
||||
enterprise:
|
||||
user_ids: [CurrentUser.id]
|
||||
email: CurrentUser.email
|
||||
email_address: CurrentUser.email
|
||||
address: {}
|
||||
country: availableCountries[0]
|
||||
@@ -11,7 +10,11 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
|
||||
for key, value of enterpriseAttributes
|
||||
@enterprise[key] = value
|
||||
|
||||
create: =>
|
||||
# Creates the enterprise and redirects to the about step on success.
|
||||
#
|
||||
# @param callback [Function] executed at the end of the operation both in
|
||||
# case of success or failure.
|
||||
create: (callback) =>
|
||||
Loading.message = t('creating') + " " + @enterprise.name
|
||||
$http(
|
||||
method: "POST"
|
||||
@@ -33,6 +36,7 @@ Darkswarm.factory "EnterpriseRegistrationService", ($http, RegistrationService,
|
||||
else
|
||||
alert(t('failed_to_create_enterprise_unknown'))
|
||||
)
|
||||
callback.call() if callback?
|
||||
|
||||
update: (step) =>
|
||||
Loading.message = t('updating') + " " + @enterprise.name
|
||||
|
||||
@@ -21,3 +21,6 @@ Darkswarm.factory 'Navigation', ($location, $window) ->
|
||||
$window.location.href = path
|
||||
else
|
||||
$window.location.pathname = path
|
||||
|
||||
reload: ->
|
||||
$window.location.reload()
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub, Taxons, Dereferencer, visibleFilter, Matcher, Geo, $rootScope)->
|
||||
Darkswarm.factory 'Orders', (orders, shops, currencyConfig)->
|
||||
new class Orders
|
||||
all: orders
|
||||
changeable: []
|
||||
shops: shops
|
||||
shopsByID: {}
|
||||
currencySymbol = currencyConfig.symbol
|
||||
|
||||
constructor: ->
|
||||
# Populate Orders.orders from json in page.
|
||||
@orders_by_distributor = orders_by_distributor
|
||||
@changeable_orders = []
|
||||
@currency_symbol = currencyConfig.symbol
|
||||
for shop in @shops
|
||||
shop.orders = []
|
||||
shop.balance = 0.0
|
||||
@shopsByID[shop.id] = shop
|
||||
|
||||
for distributor in @orders_by_distributor
|
||||
@findChangeableOrders(distributor.distributed_orders)
|
||||
@updateRunningBalance(distributor.distributed_orders)
|
||||
for order in @all by -1
|
||||
shop = @shopsByID[order.shop_id]
|
||||
shop.orders.unshift order
|
||||
|
||||
@changeable.unshift(order) if order.changes_allowed
|
||||
|
||||
updateRunningBalance: (orders) ->
|
||||
for order, i in orders
|
||||
balances = orders.slice(i,orders.length).map (o) -> parseFloat(o.outstanding_balance)
|
||||
running_balance = balances.reduce (a,b) -> a+b
|
||||
order.running_balance = running_balance.toFixed(2)
|
||||
@updateRunningBalance(shop, order)
|
||||
|
||||
findChangeableOrders: (orders) ->
|
||||
for order in orders when order.changes_allowed
|
||||
@changeable_orders.push(order)
|
||||
updateRunningBalance: (shop, order) ->
|
||||
shop.balance += parseFloat(order.outstanding_balance)
|
||||
order.runningBalance = shop.balance.toFixed(2)
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
Darkswarm.factory 'RailsFlashLoader', (flash, railsFlash)->
|
||||
new class RailsFlashLoader
|
||||
# The 'flash' service requires type key to
|
||||
# be one of: success, info, warn, error
|
||||
typePairings:
|
||||
success: 'success'
|
||||
error: 'error'
|
||||
notice: 'success'
|
||||
info: 'info'
|
||||
warn: 'warn'
|
||||
|
||||
initFlash: ->
|
||||
@loadFlash railsFlash
|
||||
|
||||
loadFlash: (rails_flash)->
|
||||
for type, message of rails_flash
|
||||
type = @typePairings[type]
|
||||
flash[type] = message
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
Darkswarm.factory 'StripeElements', ($rootScope, Loading, RailsFlashLoader) ->
|
||||
new class StripeElements
|
||||
# TODO: add locale here for translations of error messages etc. from Stripe
|
||||
|
||||
# These are both set from the StripeElements directive
|
||||
stripe: null
|
||||
card: null
|
||||
|
||||
# New Stripe Elements method
|
||||
requestToken: (secrets, submit, loading_message = t("processing_payment")) ->
|
||||
return unless @stripe? && @card?
|
||||
|
||||
Loading.message = loading_message
|
||||
cardData = @makeCardData(secrets)
|
||||
|
||||
@stripe.createToken(@card, cardData).then (response) =>
|
||||
if(response.error)
|
||||
Loading.clear()
|
||||
RailsFlashLoader.loadFlash({error: t("error") + ": #{response.error.message}"})
|
||||
else
|
||||
secrets.token = response.token.id
|
||||
secrets.cc_type = @mapCC(response.token.card.brand)
|
||||
secrets.card = response.token.card
|
||||
submit()
|
||||
|
||||
# Maps the brand returned by Stripe to that required by activemerchant
|
||||
mapCC: (ccType) ->
|
||||
if ccType == 'MasterCard'
|
||||
return 'master'
|
||||
else if ccType == 'Visa'
|
||||
return 'visa'
|
||||
else if ccType == 'American Express'
|
||||
return 'american_express'
|
||||
else if ccType == 'Discover'
|
||||
return 'discover'
|
||||
else if ccType == 'JCB'
|
||||
return 'jcb'
|
||||
else if ccType == 'Diners Club'
|
||||
return 'diners_club'
|
||||
return
|
||||
|
||||
# It doesn't matter if any of these are nil, all are optional.
|
||||
makeCardData: (secrets) ->
|
||||
{'name': secrets.name,
|
||||
'address1': secrets.address1,
|
||||
'city': secrets.city,
|
||||
'zipcode': secrets.zipcode}
|
||||
22
app/assets/javascripts/darkswarm/services/tabsets.js.coffee
Normal file
22
app/assets/javascripts/darkswarm/services/tabsets.js.coffee
Normal file
@@ -0,0 +1,22 @@
|
||||
Darkswarm.factory 'Tabsets', ->
|
||||
new class Tabsets
|
||||
tabsets: []
|
||||
|
||||
register: (ctrl, id, selected=null) ->
|
||||
if ctrl? && id?
|
||||
@tabsets.push { ctrl: ctrl, id: id, selected: selected }
|
||||
ctrl.select(selected) if selected?
|
||||
|
||||
toggle: (id, name, state=null) ->
|
||||
tabset = @findTabsetByObject(id)
|
||||
if tabset.selected == name
|
||||
@select(tabset, null) unless state == "open"
|
||||
else
|
||||
@select(tabset, name) unless state == "closed"
|
||||
|
||||
select: (tabset, name) ->
|
||||
tabset.selected = name
|
||||
tabset.ctrl.select(name)
|
||||
|
||||
findTabsetByObject: (id) ->
|
||||
(tabset for tabset in @tabsets when tabset.id == id)[0]
|
||||
@@ -6,8 +6,7 @@
|
||||
//
|
||||
|
||||
//= require 'jquery'
|
||||
//= require store/spree_core
|
||||
//= require store/spree_frontend
|
||||
//= require store/spree_auth
|
||||
//= require store/spree_promo
|
||||
|
||||
//= require_tree .
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
%h2 {{ addressType === 'bill_address' ? "#{t('admin.customers.index.edit_bill_address')}" : "#{t('admin.customers.index.edit_ship_address')}" }}
|
||||
%form{ name: 'edit_address_form', novalidate: true, ng: { submit: 'updateAddress()'}}
|
||||
.row
|
||||
= t('admin.customers.index.required_fileds')
|
||||
{{ 'admin.customers.index.required_fileds' | t }}
|
||||
(
|
||||
%span.required *
|
||||
)
|
||||
@@ -11,62 +11,62 @@
|
||||
%table.no-borders
|
||||
%tr
|
||||
%td{style: 'width: 30%'}
|
||||
= t('spree.firstname')
|
||||
{{ 'spree.firstname' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'firstname', required: true, ng: { model: 'address.firstname'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.lastname')
|
||||
{{ 'spree.lastname' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'lastname', required: true, ng: { model: 'address.lastname'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.street_address')
|
||||
{{ 'spree.street_address' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'address1', required: true, ng: { model: 'address.address1'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.street_address_1')
|
||||
{{ 'spree.street_address_1' | t }}
|
||||
%td
|
||||
%input{ type: 'text', name: 'address2', ng: { model: 'address.address2'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.city')
|
||||
{{ 'spree.city' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'city', required: true, ng: { model: 'address.city'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.zipcode')
|
||||
{{ 'spree.zipcode' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'zipcode', required: true, ng: { model: 'address.zipcode'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.country')
|
||||
{{ 'spree.country' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%select{ name: 'country', required: true, ng: { model: 'address.country_id' } }
|
||||
%option{value: ''}
|
||||
= t('admin.customers.index.select_country')
|
||||
{{ 'admin.customers.index.select_country' | t }}
|
||||
%option{ ng: { repeat: 'country in availableCountries' }, value: '{{country.id}}' }
|
||||
{{country.name}}
|
||||
%tr
|
||||
%td
|
||||
= t('spree.state')
|
||||
{{ 'spree.state' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%select{ name: 'state', required: true, ng: { model: 'address.state_id' } }
|
||||
%option{value: ''}
|
||||
= t('admin.customers.index.select_state')
|
||||
{{ 'admin.customers.index.select_state' | t }}
|
||||
%option{ ng: { repeat: 'state in states' }, value: '{{state.id}}' }
|
||||
{{state.name}}
|
||||
%tr
|
||||
%td
|
||||
= t('spree.phone')
|
||||
{{ 'spree.phone' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'phone', required: true, ng: { model: 'address.phone'} }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.ofn-drop-down
|
||||
%span
|
||||
%i.icon-check
|
||||
= t('admin.actions')
|
||||
{{ 'admin.actions' | t }}
|
||||
%i{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
%div.menu{ 'ng-show' => "expanded" }
|
||||
%a.menu_item{ 'ng-repeat' => "link in links", href: '{{link.url}}', target: "{{link.target || '_self'}}", data: { method: "{{ link.method || 'get' }}", confirm: "{{link.confirm}}" } }
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
#tag-rule-help
|
||||
.margin-bottom-30.text-center
|
||||
.text-big
|
||||
= t('js.admin.modals.tag_rule_help.title')
|
||||
{{ 'js.admin.modals.tag_rule_help.title' | t }}
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.overview')
|
||||
%p= t('js.admin.modals.tag_rule_help.overview_text')
|
||||
.text-normal
|
||||
{{ 'js.admin.modals.tag_rule_help.overview' | t }}
|
||||
%p
|
||||
{{ 'js.admin.modals.tag_rule_help.overview_text' | t }}
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.by_default_rules')
|
||||
%p= t('js.admin.modals.tag_rule_help.by_default_rules_text')
|
||||
.text-normal
|
||||
{{ 'js.admin.modals.tag_rule_help.by_default_rules' | t }}
|
||||
%p
|
||||
{{ 'js.admin.modals.tag_rule_help.by_default_rules_text' | t }}
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.customer_tagged_rules')
|
||||
%p= t('js.admin.modals.tag_rule_help.customer_tagged_rules_text')
|
||||
.text-normal
|
||||
{{ 'js.admin.modals.tag_rule_help.customer_tagged_rules' | t }}
|
||||
%p
|
||||
{{ 'js.admin.modals.tag_rule_help.customer_tagged_rules_text' | t }}
|
||||
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'button', value: t('js.admin.modals.got_it'), ng: { click: 'close()' } }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#new-customer-dialog
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
= t('admin.customers.index.add_a_new_customer_for', shop_name: "{{ CurrentShop.shop.name }}:")
|
||||
{{ 'admin.customers.index.add_a_new_customer_for' | t:{ shop_name: CurrentShop.shop.name } }}
|
||||
|
||||
%form{ name: 'new_customer_form', novalidate: true, ng: { submit: "addCustomer()" }}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
%input.fullwidth{ type: 'email', name: 'email', required: true, placeholder: t('admin.customers.index.customer_placeholder'), ng: { model: "email" } }
|
||||
%div{ ng: { show: "submitted && new_customer_form.$pristine" } }
|
||||
.error{ ng: { show: "(new_customer_form.email.$error.email || new_customer_form.email.$error.required)" } }
|
||||
= t('admin.customers.index.valid_email_error')
|
||||
{{ 'admin.customers.index.valid_email_error' | t }}
|
||||
.error{ ng: { repeat: "error in errors", bind: "error" } }
|
||||
|
||||
.text-center
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#new-tag-rule-dialog
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
= t('js.admin.new_tag_rule_dialog.select_rule_type')
|
||||
{{ 'js.admin.new_tag_rule_dialog.select_rule_type' | t }}
|
||||
|
||||
.text-center.margin-bottom-30
|
||||
-# %select.fullwidth{ 'select2-min-search' => 5, 'ng-model' => 'newRuleType', 'ng-options' => 'ruleType.id as ruleType.name for ruleType in availableRuleTypes' }
|
||||
|
||||
@@ -2,128 +2,162 @@
|
||||
.alpha.eight.columns
|
||||
%div{ ng: { if: "!enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_profile')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.hub_profile' | t }}
|
||||
|
||||
%p
|
||||
%strong= t('js.admin.panels.enterprise_package.hub_profile_cost')
|
||||
%strong
|
||||
{{ 'js.admin.panels.enterprise_package.hub_profile_cost' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.hub_profile_text1')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.hub_profile_text1' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.hub_profile_text2')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.hub_profile_text2' | t }}
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_shop')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop' | t }}
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text1')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop_text1' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text2')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop_text2' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text3')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop_text3' | t }}
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
%h3
|
||||
= t('js.admin.panels.enterprise_package.choose_package')
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package' | t }}
|
||||
%i.icon-arrow-right
|
||||
|
||||
%p
|
||||
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
|
||||
%strong
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package_text1' | t }}
|
||||
|
||||
%p
|
||||
= t('js.admin.panels.enterprise_package.choose_package_text2')
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package_text2' | t }}
|
||||
|
||||
%div{ ng: { if: "enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%h3= t('js.admin.panels.enterprise_package.profile_only')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
|
||||
|
||||
%p
|
||||
%strong= t('js.admin.panels.enterprise_package.profile_only_cost')
|
||||
%strong
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only_cost' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text1')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only_text1' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text2')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only_text2' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text3')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only_text3' | t }}
|
||||
|
||||
.info{ ng: { switch: { when: "own" } } }
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_shop')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_shop' | t }}
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.producer_shop_text1')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.producer_shop_text1' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.producer_shop_text2')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.producer_shop_text2' | t }}
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_hub')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub' | t }}
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text1')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub_text1' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text2')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub_text2' | t }}
|
||||
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text3')
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub_text3' | t }}
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
%h3
|
||||
= t('js.admin.panels.enterprise_package.choose_package')
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package' | t }}
|
||||
%i.icon-arrow-right
|
||||
|
||||
%p
|
||||
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
|
||||
%strong
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package_text1' | t }}
|
||||
|
||||
%p
|
||||
= t('js.admin.panels.enterprise_package.choose_package_text2')
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package_text2' | t }}
|
||||
|
||||
.omega.eight.columns{ ng: { switch: "enterprise.is_primary_producer" } }
|
||||
%div{ ng: { switch: { when: "false" } } }
|
||||
%a.button.selector.hub-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3= t('js.admin.panels.enterprise_package.profile_only')
|
||||
%p= t('js.admin.panels.enterprise_package.get_listing')
|
||||
.bottom= t('js.admin.panels.enterprise_package.always_free')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.get_listing' | t }}
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_package.always_free' | t }}
|
||||
%a.button.selector.hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_shop')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_produce_others')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.sell_produce_others' | t }}
|
||||
.bottom
|
||||
%monthly-pricing-description{ joiner: "newline" }
|
||||
|
||||
%div{ ng: { switch: { when: "true" } } }
|
||||
%a.button.selector.producer-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3= t('js.admin.panels.enterprise_package.profile_only')
|
||||
%p= t('js.admin.panels.enterprise_package.get_listing')
|
||||
.bottom= t('js.admin.panels.enterprise_package.always_free')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.get_listing' | t }}
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_package.always_free' | t }}
|
||||
%a.button.selector.producer-shop{ ng: { click: "enterprise.owned && (enterprise.sells='own')", class: "{selected: enterprise.sells=='own', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_shop')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_own_produce')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_shop' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.sell_own_produce' | t }}
|
||||
.bottom
|
||||
%monthly-pricing-description{ joiner: "newline" }
|
||||
|
||||
%a.button.selector.producer-hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_hub')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_both')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.sell_both' | t }}
|
||||
.bottom
|
||||
%monthly-pricing-description{ joiner: "newline" }
|
||||
|
||||
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
|
||||
%span{ ng: {hide: "saved() || saving" } }
|
||||
= t('js.admin.panels.save')
|
||||
{{ 'js.admin.panels.save' | t }}
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
= t('js.admin.panels.saved')
|
||||
{{ 'js.admin.panels.saved' | t }}
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
= t('js.admin.panels.saving')
|
||||
{{ 'js.admin.panels.saving' | t }}
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -1,37 +1,47 @@
|
||||
.row.enterprise_producer_panel{ ng: { controller: 'indexProducerPanelCtrl' } }
|
||||
.alpha.eight.columns
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==true" } }
|
||||
%h3= t('js.admin.panels.enterprise_producer.producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.producer_text1')
|
||||
|
||||
%p= t('js.admin.panels.enterprise_producer.producer_text2')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.producer' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_producer.producer_text1' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_producer.producer_text2' | t }}
|
||||
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==false" } }
|
||||
%h3= t('js.admin.panels.enterprise_producer.non_producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_text1')
|
||||
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_text2')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer_text1' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer_text2' | t }}
|
||||
|
||||
.omega.eight.columns
|
||||
%a.button.selector.producer{ ng: { click: 'enterprise.owned && changeToProducer()', class: "{selected: enterprise.is_primary_producer==true, disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3= t('js.admin.panels.enterprise_producer.producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.producer_desc')
|
||||
.bottom= t('js.admin.panels.enterprise_producer.producer_example')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.producer' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_producer.producer_desc' | t }}
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_producer.producer_example' | t }}
|
||||
|
||||
%a.button.selector.non-producer{ ng: { click: 'enterprise.owned && changeToNonProducer()', class: "{selected: enterprise.is_primary_producer==false, disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3= t('js.admin.panels.enterprise_producer.non_producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_desc')
|
||||
.bottom= t('js.admin.panels.enterprise_producer.non_producer_example')
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer_desc' | t }}
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer_example' | t }}
|
||||
|
||||
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
|
||||
%span{ ng: {hide: "saved() || saving" } }
|
||||
= t('js.admin.panels.save')
|
||||
{{ 'js.admin.panels.save' | t }}
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
= t('js.admin.panels.saved')
|
||||
{{ 'js.admin.panels.saved' | t }}
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
= t('js.admin.panels.saving')
|
||||
{{ 'js.admin.panels.saving' | t }}
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
.alpha.omega.sixteen.columns
|
||||
%h4.status-ok.text-center{ ng: { show: "issues.length == 0 && warnings.length == 0" } }
|
||||
%i.icon-ok-sign
|
||||
= t('js.admin.panels.enterprise_status.status_title', name: '{{ object.name }}')
|
||||
{{ 'js.admin.panels.enterprise_status.status_title' | t:{ name: object.name } }}
|
||||
|
||||
%table{ ng: { show: "issues.length > 0 || warnings.length > 0" } }
|
||||
%thead
|
||||
%th.severity
|
||||
= t('js.admin.panels.enterprise_status.severity')
|
||||
{{ 'js.admin.panels.enterprise_status.severity' | t }}
|
||||
%th.description
|
||||
= t('js.admin.panels.enterprise_status.description')
|
||||
{{ 'js.admin.panels.enterprise_status.description' | t }}
|
||||
%th.resolve
|
||||
= t('js.admin.panels.enterprise_status.resolve')
|
||||
{{ 'js.admin.panels.enterprise_status.resolve' | t }}
|
||||
%tr{ ng: { repeat: "issue in issues"} }
|
||||
%td.severity
|
||||
%i.icon-warning-sign.issue
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
'ng-model' => 'exchange.select_all_variants',
|
||||
'ng-change' => 'setExchangeVariants(exchange, incomingExchangeVariantsFor(exchange.enterprise_id), exchange.select_all_variants)',
|
||||
'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants' }
|
||||
= t('admin.select_all')
|
||||
{{ 'admin.select_all' | t }}
|
||||
|
||||
.exchange-products
|
||||
-# Scope product list based on permissions the current user has to view variants in this exchange
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
'ng-model' => 'exchange.select_all_variants',
|
||||
'ng-change' => 'setExchangeVariants(exchange, suppliedVariants(exchange.enterprise_id), exchange.select_all_variants)',
|
||||
'id' => 'order_cycle_incoming_exchange_{{ $index }}_select_all_variants' }
|
||||
= t('admin.select_all')
|
||||
{{ 'admin.select_all' | t }}
|
||||
|
||||
.exchange-products
|
||||
-# No need to scope product list based on permissions, because if an incoming exchange is visible,
|
||||
@@ -36,7 +36,7 @@
|
||||
'ofn-sync-distributions' => '{{ product.master_id }}',
|
||||
'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}',
|
||||
'ng-disabled' => '!order_cycle.editable_variants_for_incoming_exchanges.hasOwnProperty(exchange.enterprise_id) || order_cycle.editable_variants_for_incoming_exchanges[exchange.enterprise_id].indexOf(product.master_id) < 0' }
|
||||
= t('admin.obsolete_master')
|
||||
{{ 'admin.obsolete_master' | t }}
|
||||
|
||||
.exchange-product-variant{'ng-repeat' => 'variant in product.variants'}
|
||||
%label
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.row.exchange-tags
|
||||
.sixteen.columns.alpha.omega
|
||||
%span.text-normal
|
||||
= t('admin.tags')
|
||||
{{ 'admin.tags' | t }}
|
||||
%br
|
||||
%tags-with-translation.fullwidth{ object: 'object' }
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
{{$getDisplayText()}}
|
||||
%span.tag-with-rules{ ng: { if: "data.rules == 1" } }
|
||||
—
|
||||
= t('admin.has_one_rule')
|
||||
{{ 'admin.has_one_rule' | t }}
|
||||
%span.tag-with-rules{ ng: { if: "data.rules > 1" } }
|
||||
—
|
||||
= t('admin.has_n_rules', { num: '{{data.rules}}' })
|
||||
{{ 'admin.has_n_rules' | t:{ num: data.rules } }}
|
||||
%span{ ng: { if: "!data.rules" } }
|
||||
{{$getDisplayText()}}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
%tags-input{ template: 'admin/tag.html',
|
||||
"placeholder" => t('admin.order_cycles.form.add_a_tag'),
|
||||
ng: { model: 'object[tagsAttr]', class: "{'limit-reached': limitReached}"},
|
||||
on: { tag: { added: 'tagAdded()', removed:'tagRemoved()' } } }
|
||||
%auto-complete{ ng: { if: "findTags" }, source: "findTags({query: $query})",
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
.large-12.columns
|
||||
.alert-box.alert{"ng-show" => "errors != null"}
|
||||
{{ errors }}
|
||||
%a{ng: {show: 'user_unconfirmed', click: 'resend_confirmation()'}}
|
||||
= t('devise.confirmations.resend_confirmation_email')
|
||||
.alert-box.success{ng: {show: 'messages != null'}}
|
||||
{{ messages }}
|
||||
.row
|
||||
.large-12.columns
|
||||
%label{for: "email"} {{'email' | t}}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
%a.close-reveal-modal{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
|
||||
%h3= t('js.out_of_stock.reduced_stock_available')
|
||||
%h3
|
||||
{{ 'js.out_of_stock.reduced_stock_available' | t }}
|
||||
|
||||
%p= t('js.out_of_stock.out_of_stock_text')
|
||||
%p
|
||||
{{ 'js.out_of_stock.out_of_stock_text' | t }}
|
||||
|
||||
%p{'ng-repeat' => "v in variants"}
|
||||
%em {{ v.name_to_display }} - {{ v.unit_to_display }}
|
||||
%span{'ng-if' => "v.count_on_hand == 0"}
|
||||
= t('js.out_of_stock.now_out_of_stock')
|
||||
{{ 'js.out_of_stock.now_out_of_stock' | t }}
|
||||
%span{'ng-if' => "v.count_on_hand > 0"}
|
||||
= t('js.out_of_stock.only_n_remainging', num: '{{ v.count_on_hand }}')
|
||||
{{ 'js.out_of_stock.only_n_remainging' | t:{ num: v.count_on_hand } }}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
%a.cta-hub{"ng-href" => "{{::enterprise.path}}",
|
||||
"ng-class" => "{primary: enterprise.active, secondary: !enterprise.active}",
|
||||
"ofn-change-hub" => "enterprise"}
|
||||
%i.ofn-i_033-open-sign{"ng-if" => "::enterprise.active"}
|
||||
%i.ofn-i_032-closed-sign{"ng-if" => "::!enterprise.active"}
|
||||
.hub-name{"ng-bind" => "::enterprise.name"}
|
||||
%span{"ng-if" => "::enterprise.active"} ({{'maps_open' | t}})
|
||||
%span{"ng-if" => "::!enterprise.active"} ({{'maps_closed' | t}})
|
||||
.button-address{"ng-bind" => "::[enterprise.address.city, enterprise.address.state_name] | printArray"}
|
||||
/ %i.ofn-i_007-caret-right
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
%a.cta-hub{"ng-repeat" => "hub in enterprise.hubs | filter:{id: '!'+enterprise.id} | orderBy:'-active'",
|
||||
"ng-href" => "{{::hub.path}}", "ofn-empties-cart" => "hub",
|
||||
"ng-class" => "::{primary: hub.active, secondary: !hub.active}"}
|
||||
%i.ofn-i_033-open-sign{"ng-if" => "::hub.active"}
|
||||
%i.ofn-i_032-closed-sign{"ng-if" => "::!hub.active"}
|
||||
.hub-name{"ng-bind" => "::hub.name"}
|
||||
%span{"ng-if" => "::hub.active"} ({{'maps_open' | t}})
|
||||
%span{"ng-if" => "::!hub.active"} ({{'maps_closed' | t}})
|
||||
.button-address{"ng-bind" => "::[hub.address.city, hub.address.state_name] | printArray"}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
%tab#sign-up-content{ heading: "{{'label_signup' | t}}", active: 'tabs.signup.active', select: "select(path)"}
|
||||
%form{ ng: { controller: "SignupCtrl", submit: "submit()" } }
|
||||
.row
|
||||
.large-12.columns
|
||||
.alert-box.success{ng: {show: 'messages != null'}}
|
||||
{{ messages }}
|
||||
.row
|
||||
.large-12.columns
|
||||
%label{for: "email"} {{'signup_email' | t}}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
%li.more
|
||||
%a.dropdown{ data: { dropdown: "{{ 'show-more-' + selectorName }}" }, ng: { class: "{active: selectedOverFlowSelectors().length > 0}" } }
|
||||
%span
|
||||
= t('js.more_items', count: "{{ overFlowSelectors().length }}")
|
||||
{{ 'js.more_items' | t:{ count: overFlowSelectors().length } }}
|
||||
%i.ofn-i_052-point-down
|
||||
.f-dropdown.text-right.content{ ng: { attr: { id: "{{ 'show-more-' + selectorName }}" } } }
|
||||
%ul
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
|
||||
*= require admin/spree_core
|
||||
*= require admin/spree_backend
|
||||
*= require admin/spree_auth
|
||||
*= require admin/spree_promo
|
||||
|
||||
*= require shared/jquery-ui-timepicker-addon
|
||||
*= require shared/textAngular
|
||||
|
||||
80
app/assets/stylesheets/admin/components/alert-box.css.scss
Normal file
80
app/assets/stylesheets/admin/components/alert-box.css.scss
Normal file
@@ -0,0 +1,80 @@
|
||||
@import "../../darkswarm/mixins";
|
||||
|
||||
.alert-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
background-color: #eff5dc;
|
||||
border: 1px solid #9fc820;
|
||||
color: #666;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
@include border-radius(3px);
|
||||
|
||||
transition: opacity 300ms ease-out;
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
a.close {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
&.ok {
|
||||
border: 1px solid #9fc820;
|
||||
background-color: #fbffee;
|
||||
color: #9fc820;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #a7c44d;
|
||||
&:hover {
|
||||
background-color: #9fc820;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #9fc820;
|
||||
}
|
||||
}
|
||||
|
||||
&.error {
|
||||
border: 1px solid #c82020;
|
||||
background-color: #f5dcdc;
|
||||
color: #c82020;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #c85252;
|
||||
&:hover {
|
||||
background-color: #c82020;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #c82020;
|
||||
}
|
||||
}
|
||||
|
||||
&.warning {
|
||||
border: 1px solid #e6912e;
|
||||
background-color: #fff4e6;
|
||||
color: #e6912e;
|
||||
font-weight: bold;
|
||||
|
||||
a.button {
|
||||
padding: 3px 10px;
|
||||
background-color: #db9350;
|
||||
&:hover {
|
||||
background-color: #e6912e;
|
||||
}
|
||||
}
|
||||
|
||||
a.close {
|
||||
color: #e6912e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,6 @@ light: #ccc
|
||||
}
|
||||
}
|
||||
|
||||
/*.ui-dialog .ui-icon-closethick{background:url(/static/assets/dialogCloseButton.png);}*/
|
||||
|
||||
.ui-dialog .ui-widget-header{
|
||||
background-image: none;
|
||||
background-color: #ffffff;
|
||||
@@ -42,21 +40,18 @@ light: #ccc
|
||||
.ui-dialog .ui-corner-all{
|
||||
border-radius: 8px;
|
||||
}
|
||||
.ui-dialog {
|
||||
.ui-state-hover, .ui-state-focus{
|
||||
border: none;
|
||||
background: none;
|
||||
color: #545454;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-state-hover, .ui-widget-header .ui-state-hover, .ui-widget-content .ui-state-hover {
|
||||
background-color: #ffffff;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar-close {
|
||||
.ui-dialog .ui-dialog-titlebar .ui-dialog-titlebar-close {
|
||||
float: right;
|
||||
|
||||
border: none;
|
||||
background: none;
|
||||
|
||||
&:before {
|
||||
color: #000000;
|
||||
font-size: 2em;
|
||||
@@ -76,9 +71,18 @@ light: #ccc
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-button-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-widget-overlay {
|
||||
background: #000000;
|
||||
opacity: 0.5;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,27 +1,5 @@
|
||||
@import "../darkswarm/mixins";
|
||||
|
||||
.alert-box {
|
||||
position: relative;
|
||||
display: block;
|
||||
background-color: #eff5dc;
|
||||
border: 1px solid #9fc820;
|
||||
color: #666;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
@include border-radius(3px);
|
||||
|
||||
transition: opacity 300ms ease-out;
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
a.close {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 0px;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard_item.single-ent {
|
||||
.header {
|
||||
padding: 0.77778em 1.33333em 0.77778em 0.77778em;
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
form[name="enterprise_form"] div.row.warning {
|
||||
color: #DA7F52;
|
||||
form[name="enterprise_form"] {
|
||||
div.row.warning {
|
||||
color: #DA7F52;
|
||||
}
|
||||
|
||||
table.managers {
|
||||
i.role {
|
||||
float: right;
|
||||
margin-left: 0.5em;
|
||||
font-size: 1.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
i.confirmation {
|
||||
margin-left: 0.2em;
|
||||
font-size: 1.2em;
|
||||
cursor: pointer;
|
||||
vertical-align: bottom;
|
||||
|
||||
&.confirmed {
|
||||
color: #1ece1e;
|
||||
}
|
||||
|
||||
&.unconfirmed {
|
||||
color: #ed9524;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,13 @@ input.red {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
a.button.red {
|
||||
&:not(:hover) {
|
||||
color: #fff;
|
||||
background-color: #DA5354;
|
||||
}
|
||||
}
|
||||
|
||||
input.orange {
|
||||
background-color: #FF9848;
|
||||
margin-right: 5px;
|
||||
|
||||
@@ -69,4 +69,10 @@ table#listing_products.bulk {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
td.left-actions {
|
||||
a.view-variants, a.add-variant {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
text-align: right
|
||||
p
|
||||
max-width: 400px
|
||||
h4 i
|
||||
margin-right: 0.3rem
|
||||
@media all and (max-width: 640px)
|
||||
float: left
|
||||
clear: left
|
||||
|
||||
@@ -5,9 +5,32 @@
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
.credit_cards {
|
||||
.saved_cards {
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.saved_cards, .no_cards {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.new_card {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.4s linear;
|
||||
transition: opacity 0.4s linear;
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
input.ng-invalid {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.orders {
|
||||
margin-top: 50px;
|
||||
margin-bottom: 100px;
|
||||
|
||||
a {
|
||||
@@ -24,6 +47,10 @@
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.active_table {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.active_table_row {
|
||||
h3 {
|
||||
margin-top: 0.5em;
|
||||
|
||||
@@ -68,7 +68,11 @@
|
||||
margin-right: 0;
|
||||
|
||||
&, & > a.row {
|
||||
display: block;
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +100,7 @@
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
// color: $dark-grey
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,3 +81,6 @@ checkout
|
||||
display: inline
|
||||
span.accordion-down
|
||||
display: none
|
||||
|
||||
.error
|
||||
color: #c82020
|
||||
|
||||
@@ -88,6 +88,10 @@ footer {
|
||||
|
||||
@include panepadding;
|
||||
|
||||
div.row a img {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.row {
|
||||
&, p, h1, h2, h3, h4, h5, h6 {
|
||||
color: $disabled-med;
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
overflow-y: visible;
|
||||
|
||||
i {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.active_table_row {
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
//Generic text link style
|
||||
@@ -30,7 +38,7 @@
|
||||
//Closed & Open column
|
||||
.open_closed {
|
||||
i {
|
||||
font-size: 2rem;
|
||||
font-size: 1.75rem;
|
||||
float: right;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
@@ -36,10 +36,15 @@ nav {
|
||||
.top-bar-section .has-dropdown > a {
|
||||
padding-right: ($topbar-height / 3) !important;
|
||||
|
||||
i.ofn-i_022-cog {
|
||||
i.ofn-i_022-cog, .ofn-i_071-globe {
|
||||
font-size: 24px;
|
||||
line-height: $topbar-height;
|
||||
}
|
||||
|
||||
i.ofn-i_071-globe {
|
||||
color: #666;
|
||||
font-size: 27px
|
||||
}
|
||||
}
|
||||
|
||||
.top-bar-section .has-dropdown > a:after {
|
||||
@@ -95,6 +100,11 @@ nav {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.off-canvas-list li.language-switcher ul li {
|
||||
list-style-type: none;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.off-canvas-wrap.move-right .tab-bar .menu-icon {
|
||||
@include box-shadow(inset 0 0 6px 2px rgba(0, 0, 0, 0.5));
|
||||
}
|
||||
|
||||
@@ -160,13 +160,6 @@
|
||||
color: $clr-brick;
|
||||
}
|
||||
|
||||
i.ofn-i_033-open-sign, i.ofn-i_032-closed-sign {
|
||||
margin-right: 0.1rem;
|
||||
font-size: 2rem;
|
||||
padding: 0.15rem 0.25rem 0.35rem 0.25rem;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.hub-name {
|
||||
margin-top: 0.75rem;
|
||||
margin-bottom: 0.2rem;
|
||||
|
||||
@@ -10,4 +10,16 @@
|
||||
background: #fff;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.alert-box {
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
app/assets/stylesheets/darkswarm/stripe-elements.css.scss
Normal file
16
app/assets/stylesheets/darkswarm/stripe-elements.css.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
stripe-elements {
|
||||
margin-bottom: 15px;
|
||||
display: block;
|
||||
|
||||
#card-element {
|
||||
background: white;
|
||||
box-sizing: border-box;
|
||||
font-weight: 400;
|
||||
padding: 0.6rem 0.5rem;
|
||||
border: 1px solid #cccccc;
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 0px;
|
||||
height: 42px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -233,3 +233,6 @@
|
||||
.ofn-i_070-shop-map-reversed:before {
|
||||
content: "\e645";
|
||||
}
|
||||
.ofn-i_071-globe:before {
|
||||
content: "\e646";
|
||||
}
|
||||
|
||||
71
app/assets/stylesheets/darkswarm/tabset.css.scss
Normal file
71
app/assets/stylesheets/darkswarm/tabset.css.scss
Normal file
@@ -0,0 +1,71 @@
|
||||
@import "typography";
|
||||
@import "mixins";
|
||||
@import "branding";
|
||||
|
||||
.tabset-ctrl {
|
||||
.tab-view {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
text-align: center;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
a {
|
||||
@include headingFont;
|
||||
|
||||
background: transparent;
|
||||
text-transform: uppercase;
|
||||
font-size: 1.5em;
|
||||
text-shadow: 0 -1px 1px #ffffff;
|
||||
padding: 1em;
|
||||
border: none;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
padding: 0.35em 0 0.65em 0;
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
border-bottom: 4px solid transparent;
|
||||
|
||||
&:hover, &:focus, &:active {
|
||||
transition: all 0.4s ease-in-out;
|
||||
border-bottom: 4px solid $clr-brick-bright;
|
||||
cursor: pointer;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
transition: none;
|
||||
color: white;
|
||||
background-color: $clr-brick-bright;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $clr-brick-bright;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border-bottom: 4px solid $clr-brick;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
background-color: $clr-brick;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $clr-brick;
|
||||
|
||||
@media all and (max-width: 640px) {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -408,3 +408,12 @@ ul {
|
||||
display: inline-block;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix overlapping table header on second page of long invoices.
|
||||
* Problem description: https://github.com/openfoodfoundation/openfoodnetwork/issues/1738
|
||||
* Solution: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1770#issuecomment-73530576
|
||||
*/
|
||||
thead { display: table-header-group }
|
||||
tfoot { display: table-row-group }
|
||||
tr { page-break-inside: avoid }
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
|
||||
*= require store/spree_core
|
||||
*= require store/spree_frontend
|
||||
*= require store/spree_auth
|
||||
*= require store/spree_promo
|
||||
|
||||
*= require_self
|
||||
*= require_tree .
|
||||
|
||||
68
app/controllers/admin/bulk_line_items_controller.rb
Normal file
68
app/controllers/admin/bulk_line_items_controller.rb
Normal file
@@ -0,0 +1,68 @@
|
||||
module Admin
|
||||
class BulkLineItemsController < Spree::Admin::BaseController
|
||||
# GET /admin/bulk_line_items.json
|
||||
#
|
||||
def index
|
||||
order_params = params[:q].andand.delete :order
|
||||
orders = OpenFoodNetwork::Permissions.new(spree_current_user).editable_orders.ransack(order_params).result
|
||||
line_items = OpenFoodNetwork::Permissions.new(spree_current_user).editable_line_items.where(order_id: orders).ransack(params[:q])
|
||||
render_as_json line_items.result.reorder('order_id ASC, id ASC')
|
||||
end
|
||||
|
||||
# PUT /admin/bulk_line_items/:id.json
|
||||
#
|
||||
def update
|
||||
load_line_item
|
||||
authorize_update!
|
||||
|
||||
# `with_lock` acquires an exclusive row lock on order so no other
|
||||
# requests can update it until the transaction is commited.
|
||||
# See https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/locking/pessimistic.rb#L69
|
||||
# and https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE
|
||||
order.with_lock do
|
||||
if @line_item.update_attributes(params[:line_item])
|
||||
order.update_distribution_charge!
|
||||
render nothing: true, status: 204 # No Content, does not trigger ng resource auto-update
|
||||
else
|
||||
render json: { errors: @line_item.errors }, status: 412
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /admin/bulk_line_items/:id.json
|
||||
#
|
||||
def destroy
|
||||
load_line_item
|
||||
authorize! :update, order
|
||||
|
||||
@line_item.destroy
|
||||
render nothing: true, status: 204 # No Content, does not trigger ng resource auto-update
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_line_item
|
||||
@line_item = Spree::LineItem.find(params[:id])
|
||||
end
|
||||
|
||||
def model_class
|
||||
Spree::LineItem
|
||||
end
|
||||
|
||||
# Returns the appropriate serializer for this controller
|
||||
#
|
||||
# @return [Api::Admin::LineItemSerializer]
|
||||
def serializer(_ams_prefix)
|
||||
Api::Admin::LineItemSerializer
|
||||
end
|
||||
|
||||
def authorize_update!
|
||||
authorize! :update, order
|
||||
authorize! :read, order
|
||||
end
|
||||
|
||||
def order
|
||||
@line_item.order
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -39,6 +39,7 @@ module Admin
|
||||
invoke_callbacks(:update, :before)
|
||||
tag_rules_attributes = params[object_name].delete :tag_rules_attributes
|
||||
update_tag_rules(tag_rules_attributes) if tag_rules_attributes.present?
|
||||
update_enterprise_notifications
|
||||
if @object.update_attributes(params[object_name])
|
||||
invoke_callbacks(:update, :after)
|
||||
flash[:success] = flash_message_for(@object, :successfully_updated)
|
||||
@@ -198,6 +199,12 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def update_enterprise_notifications
|
||||
if params.key? :receives_notifications
|
||||
@enterprise.update_contact params[:receives_notifications]
|
||||
end
|
||||
end
|
||||
|
||||
def create_calculator_for(rule, attrs)
|
||||
if attrs[:calculator_type].present? && attrs[:calculator_attributes].present?
|
||||
rule.update_attributes(calculator_type: attrs[:calculator_type])
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user