mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Compare commits
563 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7f99c3185 | ||
|
|
ce85027b79 | ||
|
|
94b6a61665 | ||
|
|
f84acf44f3 | ||
|
|
386d651678 | ||
|
|
23a6e2dd8f | ||
|
|
6c69eebcbf | ||
|
|
d8a158c56d | ||
|
|
dfda30f4cb | ||
|
|
d26970d04c | ||
|
|
63e453e2c7 | ||
|
|
c7ed27286a | ||
|
|
e5340cb53a | ||
|
|
7079952f6b | ||
|
|
f79dcaba15 | ||
|
|
33a1d97d5e | ||
|
|
28ea23965b | ||
|
|
fbdbbb980f | ||
|
|
fc5b339e2a | ||
|
|
4acb3f1962 | ||
|
|
7bb58342fc | ||
|
|
b277ff03ea | ||
|
|
5061d0c4cd | ||
|
|
931a5be162 | ||
|
|
e437cba155 | ||
|
|
ec53d9df7a | ||
|
|
3330e9b219 | ||
|
|
884743ce97 | ||
|
|
b482d1e57c | ||
|
|
78f5002be5 | ||
|
|
a42799dff4 | ||
|
|
1196cd7df4 | ||
|
|
3c1eae1f47 | ||
|
|
ba27d63f9c | ||
|
|
0083733c4c | ||
|
|
a1ffc869f3 | ||
|
|
7a07e8fa16 | ||
|
|
699da16049 | ||
|
|
18c7b03f3d | ||
|
|
8b560e6cee | ||
|
|
7974ac45f2 | ||
|
|
41b5cf10dd | ||
|
|
b6955cb98c | ||
|
|
6c36c269c8 | ||
|
|
b879ea5a96 | ||
|
|
a6ed4a2c6a | ||
|
|
6972822c49 | ||
|
|
db63f30a76 | ||
|
|
848193434b | ||
|
|
570f0344da | ||
|
|
38c25c412f | ||
|
|
3b4ffe1f70 | ||
|
|
4699c654fc | ||
|
|
c1c5d00f45 | ||
|
|
220693f4e3 | ||
|
|
fcce858ea4 | ||
|
|
1f9698f7a2 | ||
|
|
1766da9d60 | ||
|
|
15ee62aaa8 | ||
|
|
6fc4a297a0 | ||
|
|
74d8dc48b4 | ||
|
|
b6f4ce373e | ||
|
|
c9f186f48f | ||
|
|
daab0dfd7a | ||
|
|
22b5dafad2 | ||
|
|
110f74eee8 | ||
|
|
61cb78fc93 | ||
|
|
38d3b446cc | ||
|
|
e47e10d267 | ||
|
|
77c8c85775 | ||
|
|
fab6d70832 | ||
|
|
9586666248 | ||
|
|
f5ab9a3445 | ||
|
|
1ac8c85113 | ||
|
|
56c2350d36 | ||
|
|
6eafed00f5 | ||
|
|
74661c0b77 | ||
|
|
c4fbcb19d0 | ||
|
|
08e391856c | ||
|
|
8c8b40c5a8 | ||
|
|
c3eda435eb | ||
|
|
5eadb33db9 | ||
|
|
f977a05b08 | ||
|
|
217eda8362 | ||
|
|
579f3bf90a | ||
|
|
348ab81c42 | ||
|
|
3df629bc6e | ||
|
|
07b2f0a7c2 | ||
|
|
c0445d46f3 | ||
|
|
6c90b4e6d0 | ||
|
|
e79a23a554 | ||
|
|
314ccc2f27 | ||
|
|
68c8759af1 | ||
|
|
314e9a4f15 | ||
|
|
0029a1b6cf | ||
|
|
bfcde72855 | ||
|
|
3d0ada803f | ||
|
|
840c936a6f | ||
|
|
7ea74ccf4a | ||
|
|
b55036e165 | ||
|
|
47011e11ff | ||
|
|
ae28d7a96b | ||
|
|
0dd8959bf7 | ||
|
|
316b0915e4 | ||
|
|
e21bfd95f4 | ||
|
|
893331c7bb | ||
|
|
b94bcd697f | ||
|
|
b0ff7ca767 | ||
|
|
493a537f2c | ||
|
|
cda43f075b | ||
|
|
5d9f92eaa7 | ||
|
|
c6afa1849c | ||
|
|
eec3a21c89 | ||
|
|
768240a5ba | ||
|
|
5af8668560 | ||
|
|
630b8a2577 | ||
|
|
12a6f652ad | ||
|
|
db4a528ba3 | ||
|
|
479c7ba24b | ||
|
|
1f08729df3 | ||
|
|
811671661e | ||
|
|
936df71d0d | ||
|
|
f3f6714472 | ||
|
|
3bce2eb7b5 | ||
|
|
bf05866f92 | ||
|
|
219ad4a3a7 | ||
|
|
a7d8028d5a | ||
|
|
d49469a3e6 | ||
|
|
4835ef067f | ||
|
|
4112c3cc75 | ||
|
|
0fe4030d71 | ||
|
|
e8d2d4d96f | ||
|
|
88c3f414fb | ||
|
|
c0d6b68233 | ||
|
|
65f62c42b9 | ||
|
|
fe7bd5e2cd | ||
|
|
e1b40142b8 | ||
|
|
963b4617a9 | ||
|
|
95ddfc4e40 | ||
|
|
01746ed470 | ||
|
|
f25e3bc6f7 | ||
|
|
e63f1c2991 | ||
|
|
29e2886b05 | ||
|
|
a97bcf74de | ||
|
|
1e6f4aa73d | ||
|
|
7c7933f8bb | ||
|
|
dc69c6e825 | ||
|
|
41e91765ca | ||
|
|
19569f9316 | ||
|
|
d91c3d1241 | ||
|
|
b302deb7a3 | ||
|
|
2fae467e9a | ||
|
|
6a5e4bb592 | ||
|
|
c72d17dc83 | ||
|
|
78ffdec693 | ||
|
|
49c19a1d6a | ||
|
|
e854eb0426 | ||
|
|
4a9c17cb28 | ||
|
|
0d1547f439 | ||
|
|
fa5ed529cb | ||
|
|
accb3076e9 | ||
|
|
a4e4e1ec68 | ||
|
|
507e12adba | ||
|
|
4809237ecc | ||
|
|
81877fedb6 | ||
|
|
1f2c6f2a85 | ||
|
|
4fe5e60967 | ||
|
|
f4eb9cb790 | ||
|
|
775f9b3ada | ||
|
|
188b33921c | ||
|
|
20c033317f | ||
|
|
e7a5d063ac | ||
|
|
1fda781d7e | ||
|
|
45fc801a08 | ||
|
|
5fa45c0716 | ||
|
|
21337a5b50 | ||
|
|
ec36a843cf | ||
|
|
e99dbaf4d8 | ||
|
|
c83ad2ecc4 | ||
|
|
80d8d18eb2 | ||
|
|
903d1afb53 | ||
|
|
cd55d2e2ff | ||
|
|
05cf8c4351 | ||
|
|
b04d815408 | ||
|
|
7b370a2eb6 | ||
|
|
5808b601b8 | ||
|
|
fdcd3dc3e3 | ||
|
|
c4bd085393 | ||
|
|
0e91d01412 | ||
|
|
fcb9e9fa56 | ||
|
|
3591354cb1 | ||
|
|
b38eab11eb | ||
|
|
c43dea60b7 | ||
|
|
268bea25d0 | ||
|
|
e94ae20b31 | ||
|
|
a94961c0a7 | ||
|
|
0d5fde919b | ||
|
|
429ef4e2ba | ||
|
|
e8999d23e1 | ||
|
|
209c9242d9 | ||
|
|
6defb09d2e | ||
|
|
2774c09d7a | ||
|
|
c62a044598 | ||
|
|
f73fbe7f23 | ||
|
|
5e1e4c1d19 | ||
|
|
cc5a335fb7 | ||
|
|
91fc3f33a0 | ||
|
|
648753b412 | ||
|
|
24fcc3dd34 | ||
|
|
14fb40a996 | ||
|
|
f4511fc74d | ||
|
|
3d0f192490 | ||
|
|
6b7cdf3a37 | ||
|
|
052d6c6b02 | ||
|
|
6e5c878491 | ||
|
|
c0c6cd1a60 | ||
|
|
2ad433590d | ||
|
|
2cb3da56ab | ||
|
|
8582e6d6b4 | ||
|
|
170101cbfe | ||
|
|
8107f49373 | ||
|
|
7ef0964af2 | ||
|
|
18472ea8c3 | ||
|
|
36e0f45a89 | ||
|
|
bea0b2b1e5 | ||
|
|
9a69951136 | ||
|
|
e19bab1aa2 | ||
|
|
8e2a111a0b | ||
|
|
70707969f3 | ||
|
|
2fe25c6219 | ||
|
|
cc1ef5b28b | ||
|
|
3fc2070b2c | ||
|
|
d22f5678be | ||
|
|
0429906eed | ||
|
|
88a09da325 | ||
|
|
963f0d601f | ||
|
|
8570471c00 | ||
|
|
7925af30d6 | ||
|
|
6f59751582 | ||
|
|
2d2792225a | ||
|
|
a079a64cbe | ||
|
|
656be690a3 | ||
|
|
167045f695 | ||
|
|
dbe968afbb | ||
|
|
179b995fa0 | ||
|
|
4791086207 | ||
|
|
be6b09a6e0 | ||
|
|
f235099859 | ||
|
|
ff8ca521ff | ||
|
|
98f7d52493 | ||
|
|
4815405839 | ||
|
|
42a6e35185 | ||
|
|
408a57479e | ||
|
|
beaf54107c | ||
|
|
e45d1d42b4 | ||
|
|
bc442c7819 | ||
|
|
6a361f2d7b | ||
|
|
a62998e5f1 | ||
|
|
ebcb8ff3e7 | ||
|
|
da8c107331 | ||
|
|
5870927518 | ||
|
|
e008a154e5 | ||
|
|
a2d01b5144 | ||
|
|
8afd5c509b | ||
|
|
311f72e4cb | ||
|
|
78563a7d75 | ||
|
|
9284dd9b63 | ||
|
|
92981e4fcd | ||
|
|
9235727d45 | ||
|
|
fc4ead9b05 | ||
|
|
b8622e95b7 | ||
|
|
f8341dccd4 | ||
|
|
b8ed7789f0 | ||
|
|
6d19613ecc | ||
|
|
0d56cbf169 | ||
|
|
67730e82c3 | ||
|
|
940ca7ade1 | ||
|
|
05f9747f15 | ||
|
|
27903ab744 | ||
|
|
931e528e14 | ||
|
|
6bed94a09b | ||
|
|
165b437f31 | ||
|
|
b526307ad1 | ||
|
|
a7bfddfcb5 | ||
|
|
52e4722dcb | ||
|
|
017916b193 | ||
|
|
02e5ba4dfd | ||
|
|
651626eb4f | ||
|
|
20d01c3047 | ||
|
|
a391b6f076 | ||
|
|
ade73f66c8 | ||
|
|
44970a13bb | ||
|
|
d80f080af5 | ||
|
|
6ec7276cfc | ||
|
|
2444d3b547 | ||
|
|
e899633aff | ||
|
|
a9f01c0f0d | ||
|
|
e021afdd8a | ||
|
|
88dea0f2b8 | ||
|
|
5150025641 | ||
|
|
fc400741b4 | ||
|
|
5cb2194f5e | ||
|
|
64f6a794fc | ||
|
|
764c95488c | ||
|
|
6cabba4cd8 | ||
|
|
bd1cd527d3 | ||
|
|
d17f9dc504 | ||
|
|
f62c583130 | ||
|
|
b1e27e0dad | ||
|
|
6ae1272281 | ||
|
|
e0cb6ed60a | ||
|
|
8aeec74fed | ||
|
|
7cd7e7367b | ||
|
|
4f4fe90db4 | ||
|
|
7a7cd3a937 | ||
|
|
bfc01e7c89 | ||
|
|
bc5672b5eb | ||
|
|
d77f775c4c | ||
|
|
7531c8cbc9 | ||
|
|
38fe0afc03 | ||
|
|
252f876827 | ||
|
|
6d9bae8ef9 | ||
|
|
0b2281dfe2 | ||
|
|
72cff0688a | ||
|
|
9793450ed0 | ||
|
|
c8f0502e71 | ||
|
|
b075ed373a | ||
|
|
eef308c4f6 | ||
|
|
70225afa13 | ||
|
|
0a67876815 | ||
|
|
b59e5ad248 | ||
|
|
287e0b5b55 | ||
|
|
c6a1560845 | ||
|
|
45dc1341d3 | ||
|
|
7d7197da58 | ||
|
|
066f42070a | ||
|
|
cad3464f56 | ||
|
|
bbcaef20a8 | ||
|
|
43726a0b23 | ||
|
|
6e6efea328 | ||
|
|
a2a6ce1b3e | ||
|
|
3a69c958ef | ||
|
|
14ee7a06ae | ||
|
|
6cd8289b27 | ||
|
|
d0509b54bf | ||
|
|
ee905cad5f | ||
|
|
01efb63ad3 | ||
|
|
7981feefa1 | ||
|
|
d4fd66461e | ||
|
|
071ba5285d | ||
|
|
6795237a2d | ||
|
|
57363e2da5 | ||
|
|
da9a3ce9f3 | ||
|
|
c4318030d3 | ||
|
|
44a301edb1 | ||
|
|
dabac50128 | ||
|
|
6030e9a294 | ||
|
|
9b656eaf4f | ||
|
|
22080a9a08 | ||
|
|
d93fe3cf2c | ||
|
|
1ea4f4274c | ||
|
|
bd11c6ce14 | ||
|
|
e8848451a5 | ||
|
|
f4f38b4183 | ||
|
|
27283c50b8 | ||
|
|
3e77534dcf | ||
|
|
5e214a32b3 | ||
|
|
7498b7f098 | ||
|
|
268c8dbcdd | ||
|
|
dbbd52cace | ||
|
|
1770a67cd9 | ||
|
|
3678d4d018 | ||
|
|
3de69987e6 | ||
|
|
cbbb047fc1 | ||
|
|
338d3cbc38 | ||
|
|
4c438ff101 | ||
|
|
631b19084a | ||
|
|
63e815c7fc | ||
|
|
b7e9ffc9da | ||
|
|
d8ce0e7d58 | ||
|
|
a115f2a268 | ||
|
|
c0c8b07add | ||
|
|
5913004e14 | ||
|
|
f4034b1065 | ||
|
|
db93b74490 | ||
|
|
d574b8943b | ||
|
|
46fcf7b62e | ||
|
|
3e565ad7cb | ||
|
|
0e01350107 | ||
|
|
7d79fffa33 | ||
|
|
4117b32ebd | ||
|
|
7a68cc7da1 | ||
|
|
20e6b703d9 | ||
|
|
a1535d6c04 | ||
|
|
f33df883a0 | ||
|
|
48acf80c85 | ||
|
|
d8f8c0df16 | ||
|
|
8ce917a422 | ||
|
|
6546d2763b | ||
|
|
d3a3b2da9a | ||
|
|
fdd6400cb8 | ||
|
|
225e436293 | ||
|
|
0e354f8fc1 | ||
|
|
a6a0bdb063 | ||
|
|
6753320336 | ||
|
|
a3b91dabe5 | ||
|
|
257441c9be | ||
|
|
1497d2c3bb | ||
|
|
8f0bc367d0 | ||
|
|
764219b9ed | ||
|
|
7f7ee25e27 | ||
|
|
1765ba0422 | ||
|
|
32d2adc8a2 | ||
|
|
d890770104 | ||
|
|
376c4c3e0e | ||
|
|
a0b740f52d | ||
|
|
0d4c4f20df | ||
|
|
ab707cf312 | ||
|
|
9989b76b7d | ||
|
|
04a714426f | ||
|
|
b66cf14bcb | ||
|
|
b78739f777 | ||
|
|
fb08759bec | ||
|
|
a4755865ca | ||
|
|
5318aaedcf | ||
|
|
3e56571e59 | ||
|
|
e57a25d05f | ||
|
|
b59a1cc232 | ||
|
|
720ca17533 | ||
|
|
d48b00c77c | ||
|
|
77f43e3ca7 | ||
|
|
23b8fbbbc7 | ||
|
|
b0402daf32 | ||
|
|
079788b4eb | ||
|
|
21ed37189a | ||
|
|
80d755da0d | ||
|
|
8d534041b2 | ||
|
|
e91c313f1e | ||
|
|
2f241485a2 | ||
|
|
f14ca87eb5 | ||
|
|
1caf648fe5 | ||
|
|
ac39c93bbf | ||
|
|
63617f80c5 | ||
|
|
a94a30f422 | ||
|
|
63dc48a075 | ||
|
|
bc798504e0 | ||
|
|
fd32152e88 | ||
|
|
1877bea68d | ||
|
|
f7523ad88c | ||
|
|
ae2357d309 | ||
|
|
8afbdcaf79 | ||
|
|
3e590f92ff | ||
|
|
a6cfa061e4 | ||
|
|
d59db1cd97 | ||
|
|
7cfb25ace9 | ||
|
|
51f97f5b28 | ||
|
|
33d940c736 | ||
|
|
08b9b50f33 | ||
|
|
7c3968b64e | ||
|
|
c59cd21698 | ||
|
|
92694c729f | ||
|
|
7b2b285ba7 | ||
|
|
caeb8f08e7 | ||
|
|
499237715e | ||
|
|
7eb2dfba48 | ||
|
|
815cf16822 | ||
|
|
a3722dee80 | ||
|
|
79ea2fd39d | ||
|
|
b349c28b9b | ||
|
|
40ca2ccee4 | ||
|
|
84b4a9bcbe | ||
|
|
1742367b36 | ||
|
|
8a1d34e711 | ||
|
|
fba72498e3 | ||
|
|
c533f6a15e | ||
|
|
23a216004e | ||
|
|
7d149ed198 | ||
|
|
e8f96e4818 | ||
|
|
3ca42ae055 | ||
|
|
c0db23af90 | ||
|
|
db583df198 | ||
|
|
306bd25dd9 | ||
|
|
f98b25b719 | ||
|
|
1bc477f6b1 | ||
|
|
c37bf3d077 | ||
|
|
3a2e0b7eff | ||
|
|
38c63fc88b | ||
|
|
8ec2ebbf94 | ||
|
|
e00846776e | ||
|
|
8339d247f8 | ||
|
|
ed2522f6d2 | ||
|
|
63ef5de0e5 | ||
|
|
38d5682762 | ||
|
|
4c40219352 | ||
|
|
7eeee78c4e | ||
|
|
0760d4cc1f | ||
|
|
261a574da9 | ||
|
|
da55eb6d27 | ||
|
|
be51a55f16 | ||
|
|
b2e14711ac | ||
|
|
1059c170d1 | ||
|
|
08465a531d | ||
|
|
58e0b95cf6 | ||
|
|
7b5e8fa603 | ||
|
|
c70993ce75 | ||
|
|
aa6e7cba30 | ||
|
|
4529ced3f2 | ||
|
|
509564819a | ||
|
|
24d0e4fcf8 | ||
|
|
308c24caf4 | ||
|
|
10b076562f | ||
|
|
701c047a0a | ||
|
|
fa30e28335 | ||
|
|
5b964ef502 | ||
|
|
b0eebc2e45 | ||
|
|
7b2f65a965 | ||
|
|
0dc12d8791 | ||
|
|
88b9514090 | ||
|
|
e5d7b545c9 | ||
|
|
c4f81b019e | ||
|
|
528af8759d | ||
|
|
c34e9c046b | ||
|
|
baeabdd668 | ||
|
|
1de2300099 | ||
|
|
53e8056450 | ||
|
|
5773876cbc | ||
|
|
ed1f05e674 | ||
|
|
98f3e15d87 | ||
|
|
95c152420c | ||
|
|
bdb2b5cce8 | ||
|
|
22ccbd5556 | ||
|
|
81d9ec71d9 | ||
|
|
45e3f8ab3a | ||
|
|
5b40c745f3 | ||
|
|
69addf056b | ||
|
|
34d5df69a5 | ||
|
|
d160142945 | ||
|
|
8234956a61 | ||
|
|
225bed9990 | ||
|
|
7f203f5491 | ||
|
|
add39f7401 | ||
|
|
ca0c3a028d | ||
|
|
b08a642377 | ||
|
|
37ace77734 | ||
|
|
8645144231 | ||
|
|
4d1a5c6ffc | ||
|
|
f8898bc722 | ||
|
|
2b7da4738c | ||
|
|
5fb5ef1974 | ||
|
|
12df5de43c | ||
|
|
4da7668dfc | ||
|
|
9c29e56fc3 | ||
|
|
e253590c1c | ||
|
|
43b5216002 | ||
|
|
e7adacc541 | ||
|
|
fa52712e35 | ||
|
|
36093c0f64 | ||
|
|
02d8f52426 | ||
|
|
5b22e19ec9 | ||
|
|
99d22649a2 | ||
|
|
98548e15c5 | ||
|
|
f37f89dd07 | ||
|
|
ed37604bc2 |
@@ -1,11 +1,8 @@
|
||||
engines:
|
||||
rubocop:
|
||||
enabled: true
|
||||
exclude_fingerprints:
|
||||
- ac41db8d4ec4cbf508c353d9b65a024f
|
||||
- 8e3b6322aef5be9f38700b3fd0cd347e
|
||||
scss-lint:
|
||||
enabled: true
|
||||
enabled: false
|
||||
ratings:
|
||||
paths:
|
||||
- app/**
|
||||
|
||||
160
.rubocop.yml
160
.rubocop.yml
@@ -1,4 +1,9 @@
|
||||
inherit_from:
|
||||
- .rubocop_todo.yml
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.1
|
||||
TargetRailsVersion: 3.2
|
||||
Include:
|
||||
- '**/Rakefile'
|
||||
- '**/config.ru'
|
||||
@@ -6,24 +11,163 @@ AllCops:
|
||||
- 'db/**/*'
|
||||
- 'config/**/*'
|
||||
- 'script/**/*'
|
||||
- 'spec/**/*'
|
||||
- !ruby/regexp /old_and_unused\.rb$/
|
||||
|
||||
Documentation:
|
||||
# OFN SETTINGS
|
||||
# Cop settings that have been agreed upon by the OFN community
|
||||
|
||||
Rails:
|
||||
Enabled: true
|
||||
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
Style/EmptyLinesAroundClassBody:
|
||||
Style/StringLiterals:
|
||||
Enabled: false
|
||||
|
||||
Style/BracesAroundHashParameters:
|
||||
# TEMPORARY/CONTESTED SETTINGS
|
||||
# These are still to be decided upon, but recommended for inclusion by
|
||||
# oeoeaio after scrutinising offenses the codebase
|
||||
|
||||
# Don't think this is a big issue, mostly picking up RPSEC scope definitions
|
||||
# with lamdas and RSpec '.to change{}' blocks
|
||||
Lint/AmbiguousBlockAssociation:
|
||||
Enabled: false
|
||||
|
||||
|
||||
# Heaps of offences (> 100) in specs, mostly in situations where two or more
|
||||
# instances of a model are required, but only one is referenced. Difficult to
|
||||
# fix without making the spec look messy or rewriting it.
|
||||
# Should definitely fix at some point.
|
||||
Lint/UselessAssignment:
|
||||
Exclude:
|
||||
- spec/**/*
|
||||
|
||||
# AFAIK, there is no good alternative to dynamic matchers until we upgrade
|
||||
# to Rails 4 and can use #find_by. If there is a better approach, let's do it.
|
||||
Rails/DynamicFindBy:
|
||||
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:
|
||||
Enabled: false
|
||||
|
||||
# Relaxed.Ruby.Style SETTINGS
|
||||
# These styles are a starting point for the conversation around conventions
|
||||
# They should be removed or tweaked and moved above as decisions are made
|
||||
# NOTE: Cops which did not fail at the time of writing were removed
|
||||
|
||||
Layout/DotPosition:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styledotposition
|
||||
|
||||
Layout/SpaceBeforeBlockBraces:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylespacebeforeblockbraces
|
||||
|
||||
Layout/SpaceInsideParens:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylespaceinsideparens
|
||||
|
||||
Style/Alias:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylealias
|
||||
|
||||
Style/BlockDelimiters:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleblockdelimiters
|
||||
|
||||
Style/CommentAnnotation:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylecommentannotation
|
||||
|
||||
Style/DoubleNegation:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styledoublenegation
|
||||
|
||||
Style/FormatString:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleformatstring
|
||||
|
||||
Style/IfUnlessModifier:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleifunlessmodifier
|
||||
|
||||
Style/Lambda:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylelambda
|
||||
|
||||
Style/MultilineBlockChain:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylemultilineblockchain
|
||||
|
||||
Style/NegatedIf:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylenegatedif
|
||||
|
||||
Style/NegatedWhile:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylenegatedwhile
|
||||
|
||||
Style/ParallelAssignment:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styleparallelassignment
|
||||
|
||||
Style/PercentLiteralDelimiters:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylepercentliteraldelimiters
|
||||
|
||||
Style/Semicolon:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylesemicolon
|
||||
|
||||
Style/SingleLineMethods:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylesinglelinemethods
|
||||
|
||||
Style/TrailingCommaInArguments:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styletrailingcommainarguments
|
||||
|
||||
Style/TrailingCommaInLiteral:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#styletrailingcommainliteral
|
||||
|
||||
Style/WordArray:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#stylewordarray
|
||||
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#lintambiguousregexpliteral
|
||||
|
||||
Lint/AssignmentInCondition:
|
||||
Enabled: false
|
||||
StyleGuide: http://relaxed.ruby.style/#lintassignmentincondition
|
||||
|
||||
Metrics/AbcSize:
|
||||
Enabled: false
|
||||
|
||||
Metrics/BlockNesting:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ClassLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ModuleLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/CyclomaticComplexity:
|
||||
Enabled: false
|
||||
|
||||
Metrics/LineLength:
|
||||
Enabled: false
|
||||
Max: 120
|
||||
|
||||
MethodLength:
|
||||
Metrics/MethodLength:
|
||||
Enabled: false
|
||||
|
||||
StringLiterals:
|
||||
Metrics/ParameterLists:
|
||||
Enabled: false
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Enabled: false
|
||||
|
||||
2187
.rubocop_todo.yml
Normal file
2187
.rubocop_todo.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,6 @@
|
||||
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. Here are some instructions for
|
||||
|
||||
9
Gemfile
9
Gemfile
@@ -9,7 +9,7 @@ gem 'i18n', '~> 0.6.11'
|
||||
gem 'nokogiri', '>= 1.6.7.1'
|
||||
|
||||
gem 'pg'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: '1-3-stable'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: 'spree-upgrade-step1c'
|
||||
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
|
||||
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '1-3-stable'
|
||||
|
||||
@@ -50,7 +50,7 @@ gem 'gmaps4rails'
|
||||
gem 'spinjs-rails'
|
||||
gem 'rack-ssl', :require => 'rack/ssl'
|
||||
gem 'custom_error_message', :github => 'jeremydurham/custom-err-msg'
|
||||
gem 'angularjs-file-upload-rails', '~> 1.1.0'
|
||||
gem 'angularjs-file-upload-rails', '~> 1.1.6'
|
||||
gem 'roadie-rails', '~> 1.0.3'
|
||||
gem 'figaro'
|
||||
gem 'blockenspiel'
|
||||
@@ -63,6 +63,7 @@ gem 'wkhtmltopdf-binary'
|
||||
|
||||
gem 'foreigner'
|
||||
gem 'immigrant'
|
||||
gem 'roo', '~> 2.7.0'
|
||||
|
||||
gem 'whenever', require: false
|
||||
|
||||
@@ -87,8 +88,10 @@ gem "foundation-rails"
|
||||
gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: "rails3"
|
||||
|
||||
gem 'jquery-rails'
|
||||
gem 'jquery-migrate-rails'
|
||||
gem 'css_splitter'
|
||||
|
||||
gem 'ofn-qz', github: 'openfoodfoundation/ofn-qz'
|
||||
|
||||
group :test, :development do
|
||||
# Pretty printed test output
|
||||
@@ -112,7 +115,6 @@ end
|
||||
|
||||
group :test do
|
||||
gem 'webmock'
|
||||
|
||||
# See spec/spec_helper.rb for instructions
|
||||
#gem 'perftools.rb'
|
||||
end
|
||||
@@ -127,4 +129,5 @@ group :development do
|
||||
gem 'guard-zeus'
|
||||
gem 'guard-rspec'
|
||||
gem 'parallel_tests'
|
||||
gem 'rubocop', '>= 0.49.1'
|
||||
end
|
||||
|
||||
145
Gemfile.lock
145
Gemfile.lock
@@ -22,46 +22,56 @@ GIT
|
||||
spree_core (~> 1.3.4)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: 6e3edfe40a5de8eba0095b2c5f3db9ea54c3afda
|
||||
branch: 1-3-stable
|
||||
remote: git://github.com/openfoodfoundation/ofn-qz.git
|
||||
revision: 024680ccea429b2e5428d7b964fa67c52add34ec
|
||||
specs:
|
||||
spree (1.3.6.beta)
|
||||
spree_api (= 1.3.6.beta)
|
||||
spree_cmd (= 1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_promo (= 1.3.6.beta)
|
||||
spree_sample (= 1.3.6.beta)
|
||||
spree_api (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
ofn-qz (0.1.0)
|
||||
railties (~> 3.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: a4c439570b77afa50f9e36299811f293232bd281
|
||||
branch: spree-upgrade-step1c
|
||||
specs:
|
||||
spree (1.3.99)
|
||||
spree_api (= 1.3.99)
|
||||
spree_cmd (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_dash (= 1.3.99)
|
||||
spree_promo (= 1.3.99)
|
||||
spree_sample (= 1.3.99)
|
||||
spree_api (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
versioncake (= 0.4.0)
|
||||
spree_cmd (1.3.6.beta)
|
||||
spree_cmd (1.3.99)
|
||||
thor (>= 0.14.6)
|
||||
spree_core (1.3.6.beta)
|
||||
activemerchant (~> 1.34)
|
||||
spree_core (1.3.99)
|
||||
activemerchant (~> 1.50.0)
|
||||
acts_as_list (= 0.1.4)
|
||||
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.18)
|
||||
jquery-rails (~> 2.2.0)
|
||||
highline (= 1.6.11)
|
||||
jquery-rails (~> 2.0)
|
||||
json (>= 1.5.5)
|
||||
kaminari (= 0.14.1)
|
||||
money (= 5.1.1)
|
||||
kaminari (= 0.13.0)
|
||||
money (= 5.0.0)
|
||||
paperclip (~> 3.0)
|
||||
rabl (= 0.7.2)
|
||||
rails (~> 3.2.16)
|
||||
rails (~> 3.2.13)
|
||||
ransack (= 0.7.2)
|
||||
select2-rails (= 3.5.9.3)
|
||||
state_machine (= 1.1.2)
|
||||
select2-rails (~> 3.2)
|
||||
state_machine (= 1.2.0)
|
||||
stringex (~> 1.3.2)
|
||||
truncate_html (~> 0.5.5)
|
||||
spree_promo (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_sample (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_dash (1.3.99)
|
||||
httparty (~> 0.8.1)
|
||||
spree_core (= 1.3.99)
|
||||
spree_promo (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_sample (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/deface.git
|
||||
@@ -123,8 +133,8 @@ GEM
|
||||
sprockets (~> 2.2.1)
|
||||
active_model_serializers (0.8.3)
|
||||
activemodel (>= 3.0)
|
||||
activemerchant (1.57.0)
|
||||
activesupport (>= 3.2.14, < 5.1)
|
||||
activemerchant (1.50.0)
|
||||
activesupport (>= 3.2.14, < 5.0.0)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
@@ -151,10 +161,11 @@ GEM
|
||||
railties (>= 3.1)
|
||||
sprockets (~> 2)
|
||||
tilt
|
||||
angularjs-file-upload-rails (1.1.0)
|
||||
angularjs-file-upload-rails (1.1.6)
|
||||
angularjs-rails (1.5.5)
|
||||
ansi (1.4.2)
|
||||
arel (3.0.3)
|
||||
ast (2.3.0)
|
||||
atomic (1.1.99)
|
||||
awesome_nested_set (2.1.5)
|
||||
activerecord (>= 3.0.0)
|
||||
@@ -167,9 +178,7 @@ GEM
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
blockenspiel (0.4.5)
|
||||
bugsnag (1.5.2)
|
||||
httparty (>= 0.6, < 1.0)
|
||||
multi_json (~> 1.0)
|
||||
bugsnag (4.1.0)
|
||||
builder (3.0.4)
|
||||
byebug (2.7.0)
|
||||
columnize (~> 0.3)
|
||||
@@ -189,7 +198,7 @@ GEM
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.7)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
@@ -404,12 +413,12 @@ GEM
|
||||
zeus
|
||||
haml (4.0.4)
|
||||
tilt
|
||||
highline (1.6.18)
|
||||
highline (1.6.11)
|
||||
hike (1.2.3)
|
||||
http_parser.rb (0.5.3)
|
||||
httparty (0.13.1)
|
||||
json (~> 1.8)
|
||||
multi_xml (>= 0.5.2)
|
||||
httparty (0.8.3)
|
||||
multi_json (~> 1.0)
|
||||
multi_xml
|
||||
i18n (0.6.11)
|
||||
immigrant (0.1.6)
|
||||
activerecord (>= 3.0)
|
||||
@@ -417,16 +426,18 @@ GEM
|
||||
inflecto (0.0.2)
|
||||
ipaddress (0.8.0)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.2.2)
|
||||
jquery-migrate-rails (1.2.1)
|
||||
jquery-rails (2.3.0)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
json_spec (1.1.1)
|
||||
multi_json (~> 1.0)
|
||||
rspec (~> 2.0)
|
||||
kaminari (0.14.1)
|
||||
kaminari (0.13.0)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
railties (>= 3.0.0)
|
||||
kgio (2.9.3)
|
||||
knapsack (1.5.1)
|
||||
rake
|
||||
@@ -449,8 +460,9 @@ GEM
|
||||
mini_portile2 (2.0.0)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
money (5.1.1)
|
||||
i18n (~> 0.6.0)
|
||||
money (5.0.0)
|
||||
i18n (~> 0.4)
|
||||
json
|
||||
multi_json (1.12.1)
|
||||
multi_xml (0.5.5)
|
||||
newrelic_rpm (3.12.0.288)
|
||||
@@ -466,9 +478,11 @@ GEM
|
||||
activesupport (>= 3.0.0)
|
||||
cocaine (~> 0.5.3)
|
||||
mime-types
|
||||
parallel (1.4.1)
|
||||
parallel_tests (1.3.7)
|
||||
parallel (1.11.2)
|
||||
parallel_tests (2.14.1)
|
||||
parallel
|
||||
parser (2.4.0.0)
|
||||
ast (~> 2.2)
|
||||
paypal-sdk-core (0.2.10)
|
||||
multi_json (~> 1.0)
|
||||
xml-simple
|
||||
@@ -483,6 +497,7 @@ GEM
|
||||
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)
|
||||
@@ -494,7 +509,7 @@ GEM
|
||||
activesupport (>= 2.3.14)
|
||||
multi_json (~> 1.0)
|
||||
rack (1.4.7)
|
||||
rack-cache (1.2)
|
||||
rack-cache (1.6.1)
|
||||
rack (>= 0.4)
|
||||
rack-livereload (0.3.15)
|
||||
rack
|
||||
@@ -520,8 +535,10 @@ GEM
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
raindrops (0.13.0)
|
||||
rake (10.4.2)
|
||||
rake (11.3.0)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -547,6 +564,9 @@ GEM
|
||||
roadie-rails (1.0.3)
|
||||
rails (>= 3.0, < 4.2)
|
||||
roadie (~> 3.0)
|
||||
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)
|
||||
@@ -564,14 +584,22 @@ GEM
|
||||
rspec-mocks (~> 2.14.0)
|
||||
rspec-retry (0.4.2)
|
||||
rspec-core
|
||||
ruby-progressbar (1.7.1)
|
||||
rubocop (0.49.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 1.99.1, < 3.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-progressbar (1.8.1)
|
||||
rubyzip (1.2.0)
|
||||
safe_yaml (0.9.5)
|
||||
sass (3.3.14)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
select2-rails (3.5.9.3)
|
||||
select2-rails (3.5.10)
|
||||
thor (~> 0.14)
|
||||
shoulda-matchers (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -583,14 +611,14 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
state_machine (1.1.2)
|
||||
state_machine (1.2.0)
|
||||
stringex (1.3.3)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.19.1)
|
||||
tilt (1.4.1)
|
||||
timecop (0.6.2.2)
|
||||
timecop (0.8.1)
|
||||
timers (1.1.0)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
@@ -601,10 +629,11 @@ GEM
|
||||
sprockets (>= 2.0.0)
|
||||
turn (0.8.3)
|
||||
ansi
|
||||
tzinfo (0.3.44)
|
||||
tzinfo (0.3.49)
|
||||
uglifier (2.7.1)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
unicode-display_width (1.3.0)
|
||||
unicorn (4.9.0)
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
@@ -628,9 +657,8 @@ GEM
|
||||
whenever (0.9.2)
|
||||
activesupport (>= 2.3.4)
|
||||
chronic (>= 0.6.3)
|
||||
wicked_pdf (0.11.0)
|
||||
rails
|
||||
wkhtmltopdf-binary (0.9.9.3)
|
||||
wicked_pdf (1.1.0)
|
||||
wkhtmltopdf-binary (0.12.3.1)
|
||||
xml-simple (1.1.4)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
@@ -645,7 +673,7 @@ DEPENDENCIES
|
||||
acts-as-taggable-on (~> 3.4)
|
||||
andand
|
||||
angular-rails-templates (~> 0.2.0)
|
||||
angularjs-file-upload-rails (~> 1.1.0)
|
||||
angularjs-file-upload-rails (~> 1.1.6)
|
||||
angularjs-rails (= 1.5.5)
|
||||
atomic
|
||||
awesome_print
|
||||
@@ -682,6 +710,7 @@ DEPENDENCIES
|
||||
haml
|
||||
i18n (~> 0.6.11)
|
||||
immigrant
|
||||
jquery-migrate-rails
|
||||
jquery-rails
|
||||
json_spec
|
||||
knapsack
|
||||
@@ -689,6 +718,7 @@ DEPENDENCIES
|
||||
momentjs-rails
|
||||
newrelic_rpm
|
||||
nokogiri (>= 1.6.7.1)
|
||||
ofn-qz!
|
||||
oj
|
||||
paper_trail (~> 3.0.8)
|
||||
paperclip
|
||||
@@ -704,8 +734,10 @@ DEPENDENCIES
|
||||
redcarpet
|
||||
representative_view
|
||||
roadie-rails (~> 1.0.3)
|
||||
roo (~> 2.7.0)
|
||||
rspec-rails
|
||||
rspec-retry
|
||||
rubocop (>= 0.49.1)
|
||||
sass (~> 3.3)
|
||||
sass-rails (~> 3.2.3)
|
||||
shoulda-matchers
|
||||
@@ -728,5 +760,8 @@ DEPENDENCIES
|
||||
wicked_pdf
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.1.5p273
|
||||
|
||||
BUNDLED WITH
|
||||
1.12.5
|
||||
1.15.1
|
||||
|
||||
@@ -47,4 +47,3 @@ end
|
||||
#watch(%r{^spec/acceptance/(.+)\.feature$})
|
||||
#watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
||||
#end
|
||||
|
||||
|
||||
@@ -98,6 +98,14 @@ The site is configured to use
|
||||
startup time while Rails loads. See the Zeus github page for
|
||||
usage instructions.
|
||||
|
||||
Once [npm dependencies are
|
||||
installed](https://github.com/openfoodfoundation/openfoodnetwork/wiki/Karma), AngularJS tests can be run with:
|
||||
|
||||
./script/karma run
|
||||
|
||||
If you want karma to automatically rerun the tests on file modification, use:
|
||||
|
||||
./script/karma start
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
//= require jquery
|
||||
//= require jquery-migrate-min
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui
|
||||
//= require shared/jquery-ui-timepicker-addon
|
||||
@@ -36,6 +37,7 @@
|
||||
//= require ./order_cycles/order_cycles
|
||||
//= require ./payment_methods/payment_methods
|
||||
//= require ./products/products
|
||||
//= require ./resources/resources
|
||||
//= require ./shipping_methods/shipping_methods
|
||||
//= require ./side_menu/side_menu
|
||||
//= require ./tag_rules/tag_rules
|
||||
|
||||
@@ -22,7 +22,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
|
||||
|
||||
$scope.producers = producers
|
||||
$scope.taxons = Taxons.taxons
|
||||
$scope.taxons = Taxons.all
|
||||
$scope.tax_categories = tax_categories
|
||||
$scope.filterProducers = [{id: "0", name: ""}].concat $scope.producers
|
||||
$scope.filterTaxons = [{id: "0", name: ""}].concat $scope.taxons
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filter, Customers, TagRuleResource, CurrentShop, RequestMonitor, Columns, pendingChanges, shops) ->
|
||||
angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filter, Customers, TagRuleResource, CurrentShop, RequestMonitor, Columns, pendingChanges, shops, availableCountries) ->
|
||||
$scope.shops = shops
|
||||
$scope.availableCountries = availableCountries
|
||||
$scope.RequestMonitor = RequestMonitor
|
||||
$scope.submitAll = pendingChanges.submitAll
|
||||
$scope.add = Customers.add
|
||||
$scope.deleteCustomer = Customers.remove
|
||||
$scope.customerLimit = 20
|
||||
$scope.customers = Customers.all
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
$scope.confirmRefresh = (event) ->
|
||||
@@ -16,10 +16,13 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, $filt
|
||||
Customers.index({enterprise_id: $scope.shop_id}).then (data) ->
|
||||
pendingChanges.removeAll()
|
||||
$scope.customers_form.$setPristine()
|
||||
$scope.customers = data
|
||||
|
||||
$scope.shop_id = shops[0].id if shops.length == 1
|
||||
|
||||
$scope.deleteCustomer = (customer) ->
|
||||
if confirm(t('admin.customers.index.confirm_delete'))
|
||||
Customers.remove(customer)
|
||||
|
||||
$scope.checkForDuplicateCodes = ->
|
||||
delete this.customer.code unless this.customer.code
|
||||
this.duplicate = $scope.isDuplicateCode(this.customer.code)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
angular.module("admin.customers").directive 'editAddressDialog', ($compile, $templateCache, $filter, DialogDefaults, Customers, StatusMessage) ->
|
||||
restrict: 'A'
|
||||
scope: true
|
||||
link: (scope, element, attr) ->
|
||||
scope.errors = []
|
||||
|
||||
scope.$watch 'address.country_id', (newVal) ->
|
||||
if newVal
|
||||
scope.states = scope.filter_states(newVal)
|
||||
|
||||
scope.updateAddress = ->
|
||||
scope.edit_address_form.$setPristine()
|
||||
if scope.edit_address_form.$valid
|
||||
Customers.update(scope.address, scope.customer, scope.addressType).$promise.then (data) ->
|
||||
scope.customer = data
|
||||
template.dialog('close')
|
||||
StatusMessage.display('success', t('admin.customers.index.update_address_success'))
|
||||
else
|
||||
scope.errors.push(t('admin.customers.index.update_address_error'))
|
||||
|
||||
|
||||
template = $compile($templateCache.get('admin/edit_address_dialog.html'))(scope)
|
||||
template.dialog(DialogDefaults)
|
||||
|
||||
element.bind 'click', (e) ->
|
||||
if e.target.id == 'bill-address-link'
|
||||
scope.addressType = 'bill_address'
|
||||
else
|
||||
scope.addressType = 'ship_address'
|
||||
scope.address = scope.customer[scope.addressType]
|
||||
|
||||
template.dialog('open')
|
||||
scope.$apply()
|
||||
|
||||
scope.filter_states = (countryID) ->
|
||||
$filter('filter')(scope.availableCountries, {id: countryID})[0].states
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.customers").directive 'newCustomerDialog', ($compile, $injector, $templateCache, DialogDefaults, CurrentShop, Customers) ->
|
||||
angular.module("admin.customers").directive 'newCustomerDialog', ($compile, $templateCache, DialogDefaults, CurrentShop, Customers) ->
|
||||
restrict: 'A'
|
||||
scope: true
|
||||
link: (scope, element, attr) ->
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
angular.module("admin.customers").factory "Customers", ($q, InfoDialog, RequestMonitor, CustomerResource, CurrentShop) ->
|
||||
new class Customers
|
||||
customers: []
|
||||
|
||||
add: (email) ->
|
||||
params =
|
||||
enterprise_id: CurrentShop.shop.id
|
||||
email: email
|
||||
CustomerResource.create params, (customer) =>
|
||||
@customers.unshift customer if customer.id
|
||||
|
||||
remove: (customer) ->
|
||||
params = id: customer.id
|
||||
CustomerResource.destroy params, =>
|
||||
i = @customers.indexOf customer
|
||||
@customers.splice i, 1 unless i < 0
|
||||
, (response) =>
|
||||
errors = response.data.errors
|
||||
if errors?
|
||||
InfoDialog.open 'error', errors[0]
|
||||
else
|
||||
InfoDialog.open 'error', "Could not delete customer: #{customer.email}"
|
||||
|
||||
index: (params) ->
|
||||
request = CustomerResource.index(params, (data) => @customers = data)
|
||||
RequestMonitor.load(request.$promise)
|
||||
request.$promise
|
||||
@@ -11,7 +11,7 @@ angular.module("admin.enterprises")
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'enterprise_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t('admin.unsaved_changes') if newValue
|
||||
|
||||
$scope.setFormDirty = ->
|
||||
$scope.$apply ->
|
||||
@@ -24,13 +24,12 @@ angular.module("admin.enterprises")
|
||||
$scope.navClear()
|
||||
enterprise_form.submit()
|
||||
|
||||
|
||||
# Provide a callback for generating warning messages displayed before leaving the page. This is passed in
|
||||
# from a directive "nav-check" in the page - if we pass it here it will be called in the test suite,
|
||||
# and on all new uses of this contoller, and we might not want that .
|
||||
# and on all new uses of this contoller, and we might not want that.
|
||||
enterpriseNavCallback = ->
|
||||
if $scope.Enterprise.$dirty
|
||||
"Your changes to the enterprise are not saved yet."
|
||||
if $scope.enterprise_form.$dirty
|
||||
t('admin.unsaved_confirm_leave')
|
||||
|
||||
# Register the NavigationCheck callback
|
||||
NavigationCheck.register(enterpriseNavCallback)
|
||||
@@ -39,6 +38,8 @@ angular.module("admin.enterprises")
|
||||
if manager.id?
|
||||
for i, user of $scope.Enterprise.users when user.id == manager.id
|
||||
$scope.Enterprise.users.splice i, 1
|
||||
if $scope.enterprise_form?
|
||||
$scope.enterprise_form.$setDirty()
|
||||
|
||||
$scope.addManager = (manager) ->
|
||||
if manager.id? and manager.email?
|
||||
|
||||
@@ -6,7 +6,6 @@ angular.module("admin.enterprises")
|
||||
|
||||
$scope.menu.setItems [
|
||||
{ name: 'primary_details', label: t('primary_details'), icon_class: "icon-home" }
|
||||
{ name: 'users', label: t('users'), icon_class: "icon-user" }
|
||||
{ name: 'address', label: t('address'), icon_class: "icon-map-marker" }
|
||||
{ name: 'contact', label: t('contact'), icon_class: "icon-phone" }
|
||||
{ name: 'social', label: t('social'), icon_class: "icon-twitter" }
|
||||
@@ -20,11 +19,11 @@ angular.module("admin.enterprises")
|
||||
{ name: 'inventory_settings', label: t('inventory_settings'), icon_class: "icon-list-ol", show: "enterpriseIsShop()" }
|
||||
{ name: 'tag_rules', label: t('tag_rules'), icon_class: "icon-random", show: "enterpriseIsShop()" }
|
||||
{ name: 'shop_preferences', label: t('shop_preferences'), icon_class: "icon-shopping-cart", show: "enterpriseIsShop()" }
|
||||
{ name: 'users', label: t('users'), icon_class: "icon-user" }
|
||||
]
|
||||
|
||||
$scope.select(0)
|
||||
|
||||
|
||||
$scope.showItem = (item) ->
|
||||
if item.show?
|
||||
$parse(item.show)($scope)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
angular.module('admin.enterprises').directive 'enterpriseSwitcher', (NavigationCheck) ->
|
||||
restrict: 'A'
|
||||
require: 'ngModel'
|
||||
link: (scope, element, attr, ngModel) ->
|
||||
initial = element[0].getAttribute('data-initial')
|
||||
|
||||
element.on 'change', ->
|
||||
if not NavigationCheck.confirmLeave()
|
||||
# Reset the current dropdown selection if staying on page
|
||||
ngModel.$setViewValue initial
|
||||
ngModel.$render()
|
||||
element.select2 'val', initial
|
||||
return
|
||||
|
||||
NavigationCheck.clear() # Don't ask twice if leaving
|
||||
window.location = element[0].querySelector('option[selected]').getAttribute('data-url')
|
||||
@@ -3,19 +3,42 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
|
||||
restrict: 'C'
|
||||
scope:
|
||||
data: "="
|
||||
minSearch: "@?"
|
||||
text: "@?"
|
||||
minSearch: "@"
|
||||
text: "@"
|
||||
blank: "=?"
|
||||
filter: "=?"
|
||||
onSelecting: "=?"
|
||||
multiple: '@'
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
scope.text ||= 'name'
|
||||
scope.filter ||= -> true
|
||||
scope.text ?= 'name'
|
||||
scope.multiple ?= false
|
||||
scope.filter ?= -> true
|
||||
|
||||
if scope.data.$promise
|
||||
scope.data.$promise.then -> init()
|
||||
else
|
||||
init()
|
||||
|
||||
element.on "select2-opening", scope.onSelecting || angular.noop
|
||||
|
||||
attrs.$observe 'disabled', (value) ->
|
||||
element.select2('enable', !value)
|
||||
|
||||
ngModel.$formatters.push (value) ->
|
||||
element.select2('val', value)
|
||||
value
|
||||
|
||||
ngModel.$parsers.push (value) ->
|
||||
return value.split(",") if scope.multiple
|
||||
value
|
||||
|
||||
init = ->
|
||||
scope.data.unshift(scope.blank) if scope.blank? && typeof scope.blank is "object"
|
||||
|
||||
item.name = $sanitize(item.name) for item in scope.data
|
||||
element.select2
|
||||
multiple: scope.multiple
|
||||
minimumResultsForSearch: scope.minSearch || 0
|
||||
data: ->
|
||||
filtered = $filter('filter')(scope.data,scope.filter)
|
||||
@@ -24,12 +47,3 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
|
||||
item[scope.text]
|
||||
formatResult: (item) ->
|
||||
item[scope.text]
|
||||
|
||||
element.on "select2-opening", scope.onSelecting || angular.noop
|
||||
|
||||
attrs.$observe 'disabled', (value) ->
|
||||
element.select2('enable', !value)
|
||||
|
||||
ngModel.$formatters.push (value) ->
|
||||
element.select2('val', value)
|
||||
value
|
||||
|
||||
@@ -1 +1 @@
|
||||
angular.module("admin.indexUtils", ['ngResource', 'ngSanitize', 'templates', 'admin.utils']).config ($httpProvider) ->
|
||||
angular.module("admin.indexUtils", ['admin.resources', 'ngSanitize', 'templates', 'admin.utils']).config ($httpProvider) ->
|
||||
@@ -3,7 +3,8 @@ angular.module("admin.indexUtils").factory 'Dereferencer', ->
|
||||
dereference: (array, data)->
|
||||
if array
|
||||
for object, i in array
|
||||
array[i] = data[object.id]
|
||||
match = data[object.id]
|
||||
array[i] = match if match?
|
||||
|
||||
dereferenceAttr: (array, attr, data)->
|
||||
if array
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module("admin.indexUtils").factory "switchClass", ($timeout) ->
|
||||
return (element,classToAdd,removeClasses,timeout) ->
|
||||
return (element, classToAdd, removeClasses, timeout) ->
|
||||
$timeout.cancel element.timeout if element.timeout
|
||||
element.removeClass className for className in removeClasses
|
||||
element.addClass classToAdd
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, blankOption, VariantUnitManager, RequestMonitor) ->
|
||||
angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, VariantUnitManager, RequestMonitor) ->
|
||||
$scope.initialized = false
|
||||
$scope.RequestMonitor = RequestMonitor
|
||||
$scope.filteredLineItems = []
|
||||
@@ -15,31 +15,31 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
|
||||
|
||||
$scope.resetSelectFilters = ->
|
||||
$scope.distributorFilter = blankOption().id
|
||||
$scope.supplierFilter = blankOption().id
|
||||
$scope.orderCycleFilter = blankOption().id
|
||||
$scope.distributorFilter = 0
|
||||
$scope.supplierFilter = 0
|
||||
$scope.orderCycleFilter = 0
|
||||
$scope.quickSearch = ""
|
||||
|
||||
$scope.refreshData = ->
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == "0"
|
||||
$scope.startDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].first_order
|
||||
$scope.endDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].last_order
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == 0
|
||||
$scope.startDate = OrderCycles.byID[$scope.orderCycleFilter].first_order
|
||||
$scope.endDate = OrderCycles.byID[$scope.orderCycleFilter].last_order
|
||||
|
||||
RequestMonitor.load $scope.orders = Orders.index("q[state_not_eq]": "canceled", "q[completed_at_not_null]": "true", "q[completed_at_gt]": "#{parseDate($scope.startDate)}", "q[completed_at_lt]": "#{parseDate($scope.endDate)}")
|
||||
RequestMonitor.load $scope.lineItems = LineItems.index("q[order][state_not_eq]": "canceled", "q[order][completed_at_not_null]": "true", "q[order][completed_at_gt]": "#{parseDate($scope.startDate)}", "q[order][completed_at_lt]": "#{parseDate($scope.endDate)}")
|
||||
|
||||
unless $scope.initialized
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(includeBlank: true, ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
|
||||
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise]).then ->
|
||||
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.enterprisesByID
|
||||
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.orderCyclesByID
|
||||
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.byID
|
||||
Dereferencer.dereferenceAttr $scope.orders, "order_cycle", OrderCycles.byID
|
||||
|
||||
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.suppliers.$promise, $scope.lineItems.$promise]).then ->
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.enterprisesByID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.ordersByID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.byID
|
||||
Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.byID
|
||||
$scope.bulk_order_form.$setPristine()
|
||||
StatusMessage.clear()
|
||||
unless $scope.initialized
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
angular.module("admin.lineItems").filter "selectFilter", (blankOption, RequestMonitor) ->
|
||||
angular.module("admin.lineItems").filter "selectFilter", (RequestMonitor) ->
|
||||
return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) ->
|
||||
filtered = []
|
||||
unless RequestMonitor.loading
|
||||
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) &&
|
||||
(angular.equals(selectedDistributor,"0") || lineItem.order.distributor.id == selectedDistributor) &&
|
||||
(angular.equals(selectedOrderCycle,"0") || lineItem.order.order_cycle.id == selectedOrderCycle)
|
||||
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,0) || lineItem.supplier.id == selectedSupplier) &&
|
||||
(angular.equals(selectedDistributor,0) || lineItem.order.distributor.id == selectedDistributor) &&
|
||||
(angular.equals(selectedOrderCycle,0) || lineItem.order.order_cycle.id == selectedOrderCycle)
|
||||
filtered
|
||||
|
||||
@@ -12,7 +12,10 @@ angular.module('admin.orderCycles')
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
|
||||
@@ -13,7 +13,10 @@ angular.module('admin.orderCycles')
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
@@ -68,6 +71,7 @@ angular.module('admin.orderCycles')
|
||||
$scope.removeCoordinatorFee = ($event, index) ->
|
||||
$event.preventDefault()
|
||||
OrderCycle.removeCoordinatorFee(index)
|
||||
$scope.order_cycle_form.$dirty = true
|
||||
|
||||
$scope.addExchangeFee = ($event, exchange) ->
|
||||
$event.preventDefault()
|
||||
@@ -76,6 +80,7 @@ angular.module('admin.orderCycles')
|
||||
$scope.removeExchangeFee = ($event, exchange, index) ->
|
||||
$event.preventDefault()
|
||||
OrderCycle.removeExchangeFee(exchange, index)
|
||||
$scope.order_cycle_form.$dirty = true
|
||||
|
||||
$scope.removeDistributionOfVariant = (variant_id) ->
|
||||
OrderCycle.removeDistributionOfVariant(variant_id)
|
||||
|
||||
@@ -8,7 +8,10 @@ angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl"
|
||||
$scope.enterprise_fees = EnterpriseFee.index(coordinator_id: ocInstance.coordinator_id)
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.init = (enterprises) ->
|
||||
enterprise = enterprises[Object.keys(enterprises)[0]]
|
||||
|
||||
@@ -10,7 +10,10 @@ angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl",
|
||||
$scope.init()
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module('admin.orderCycles', ['ngResource', 'admin.utils', 'admin.indexUtils', 'ngTagsInput'])
|
||||
angular.module('admin.orderCycles', ['admin.utils', 'admin.indexUtils', 'ngTagsInput'])
|
||||
|
||||
.config ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
angular.module("admin.orders").directive 'customerSearchOverride', ->
|
||||
restrict: 'C'
|
||||
link: (scope, element, attr) ->
|
||||
formatCustomerResult = (customer) ->
|
||||
customerTemplate
|
||||
customer: customer
|
||||
bill_address: customer.bill_address
|
||||
ship_address: customer.ship_address
|
||||
|
||||
element.select2
|
||||
placeholder: Spree.translations.choose_a_customer
|
||||
ajax:
|
||||
url: '/admin/search/customers.json'
|
||||
datatype: 'json'
|
||||
data: (term, page) ->
|
||||
{
|
||||
q: term
|
||||
distributor_id: $('#distributor_id').val() # modified
|
||||
}
|
||||
results: (data, page) ->
|
||||
{ results: data }
|
||||
dropdownCssClass: 'customer_search'
|
||||
formatResult: formatCustomerResult
|
||||
formatSelection: (customer) ->
|
||||
_.each [
|
||||
'bill_address'
|
||||
'ship_address'
|
||||
], (address) ->
|
||||
data = customer[address]
|
||||
address_parts = [
|
||||
'firstname'
|
||||
'lastname'
|
||||
'company'
|
||||
'address1'
|
||||
'address2'
|
||||
'city'
|
||||
'zipcode'
|
||||
'phone'
|
||||
]
|
||||
attribute_wrapper = '#order_' + address + '_attributes_'
|
||||
if data # modified
|
||||
_.each address_parts, (part) ->
|
||||
$(attribute_wrapper + part).val data[part]
|
||||
return
|
||||
$(attribute_wrapper + 'state_id').select2 'val', data['state_id']
|
||||
$(attribute_wrapper + 'country_id').select2 'val', data['country_id']
|
||||
else
|
||||
_.each address_parts, (part) ->
|
||||
$(attribute_wrapper + part).val ''
|
||||
return
|
||||
$(attribute_wrapper + 'state_id').select2 'val', ''
|
||||
$(attribute_wrapper + 'country_id').select2 'val', ''
|
||||
return
|
||||
$('#order_email').val customer.email
|
||||
$('#user_id').val customer.user_id # modified
|
||||
$('#guest_checkout_true').prop 'checked', false
|
||||
$('#guest_checkout_false').prop 'checked', true
|
||||
$('#guest_checkout_false').prop 'disabled', false
|
||||
customer.email
|
||||
@@ -1,3 +1,3 @@
|
||||
angular.module("admin.paymentMethods").controller "paymentMethodsCtrl", ($scope, PaymentMethods) ->
|
||||
$scope.findPaymentMethodByID = (id) ->
|
||||
$scope.PaymentMethod = PaymentMethods.findByID(id)
|
||||
$scope.PaymentMethod = PaymentMethods.byID[id]
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
angular.module("admin.paymentMethods")
|
||||
.factory "PaymentMethods", (paymentMethods) ->
|
||||
new class PaymentMethods
|
||||
paymentMethods: paymentMethods
|
||||
|
||||
findByID: (id) ->
|
||||
for paymentMethod in @paymentMethods
|
||||
return paymentMethod if paymentMethod.id is id
|
||||
@@ -0,0 +1,5 @@
|
||||
angular.module("ofn.admin").controller "DropdownPanelsCtrl", ($scope) ->
|
||||
$scope.active = false
|
||||
|
||||
$scope.togglePanel = ->
|
||||
$scope.active = !$scope.active
|
||||
@@ -0,0 +1,15 @@
|
||||
angular.module("ofn.admin").controller "ImportOptionsFormCtrl", ($scope, $rootScope, ProductImportService) ->
|
||||
|
||||
$scope.toggleResetAbsent = () ->
|
||||
confirmed = confirm 'This will set stock level to zero on all products for this \n' +
|
||||
'enterprise that are not present in the uploaded file.' if $scope.resetAbsent
|
||||
|
||||
if confirmed or !$scope.resetAbsent
|
||||
ProductImportService.updateResetAbsent($scope.supplierId, $scope.resetCount, $scope.resetAbsent)
|
||||
else
|
||||
$scope.resetAbsent = false
|
||||
|
||||
$scope.resetTotal = ProductImportService.resetTotal
|
||||
|
||||
$rootScope.$watch 'resetTotal', (newValue) ->
|
||||
$scope.resetTotal = newValue if newValue || newValue == 0
|
||||
@@ -0,0 +1,15 @@
|
||||
angular.module("ofn.admin").factory "ProductImportService", ($rootScope) ->
|
||||
new class ProductImportService
|
||||
suppliers: {}
|
||||
resetTotal: 0
|
||||
|
||||
updateResetAbsent: (supplierId, resetCount, resetAbsent) ->
|
||||
if resetAbsent
|
||||
@suppliers[supplierId] = resetCount
|
||||
@resetTotal += resetCount
|
||||
else
|
||||
@suppliers[supplierId] = null
|
||||
@resetTotal -= resetCount
|
||||
|
||||
$rootScope.resetTotal = @resetTotal
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
angular.module("admin.products").controller "editUnitsCtrl", ($scope, VariantUnitManager) ->
|
||||
|
||||
$scope.product =
|
||||
variant_unit: angular.element('#variant_unit').val()
|
||||
variant_unit_scale: angular.element('#variant_unit_scale').val()
|
||||
|
||||
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
|
||||
|
||||
if $scope.product.variant_unit == 'items'
|
||||
$scope.variant_unit_with_scale = 'items'
|
||||
else
|
||||
$scope.variant_unit_with_scale = $scope.product.variant_unit + '_' + $scope.product.variant_unit_scale
|
||||
|
||||
$scope.setFields = ->
|
||||
if $scope.variant_unit_with_scale == 'items'
|
||||
variant_unit = 'items'
|
||||
variant_unit_scale = null
|
||||
else
|
||||
options = $scope.variant_unit_with_scale.split('_')
|
||||
variant_unit = options[0]
|
||||
variant_unit_scale = options[1]
|
||||
|
||||
$scope.product.variant_unit = variant_unit
|
||||
$scope.product.variant_unit_scale = variant_unit_scale
|
||||
@@ -0,0 +1,14 @@
|
||||
angular.module("admin.products").controller "variantUnitsCtrl", ($scope, VariantUnitManager, $timeout) ->
|
||||
|
||||
$scope.unitName = (scale, type) ->
|
||||
VariantUnitManager.getUnitName(scale, type)
|
||||
|
||||
$scope.scale = angular.element('#product_variant_unit_scale').val()
|
||||
|
||||
$scope.updateValue = ->
|
||||
unit_value_human = angular.element('#unit_value_human').val()
|
||||
$scope.unit_value = unit_value_human * $scope.scale
|
||||
|
||||
variant_unit_value = angular.element('#variant_unit_value').val()
|
||||
$scope.unit_value_human = variant_unit_value / $scope.scale
|
||||
$timeout -> $scope.updateValue()
|
||||
@@ -1 +1 @@
|
||||
angular.module("admin.products", [])
|
||||
angular.module("admin.products", ["textAngular", "admin.utils"])
|
||||
@@ -0,0 +1 @@
|
||||
angular.module("admin.resources", ['ngResource'])
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.customers").factory 'CustomerResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'CustomerResource', ($resource) ->
|
||||
$resource('/admin/customers/:id.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -14,4 +14,8 @@ angular.module("admin.customers").factory 'CustomerResource', ($resource) ->
|
||||
method: 'DELETE'
|
||||
params:
|
||||
id: '@id'
|
||||
'update':
|
||||
method: 'PUT'
|
||||
params:
|
||||
id: '@id'
|
||||
})
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.enterprises").factory 'EnterpriseResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'EnterpriseResource', ($resource) ->
|
||||
ignoredAttrs = ->
|
||||
["$$hashKey", "producer", "package", "producerError", "packageError", "status"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.lineItems").factory 'LineItemResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'LineItemResource', ($resource) ->
|
||||
$resource('/admin/:orders/:order_number/line_items/:id.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.orderCycles").factory 'OrderCycleResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'OrderCycleResource', ($resource) ->
|
||||
$resource('/admin/order_cycles/:id/:action.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.orders").factory 'OrderResource', ($resource) ->
|
||||
angular.module("admin.resources").factory 'OrderResource', ($resource) ->
|
||||
$resource('/admin/orders/:id/:action.json', {}, {
|
||||
'index':
|
||||
method: 'GET'
|
||||
@@ -0,0 +1,49 @@
|
||||
angular.module("admin.resources").factory "Customers", ($q, InfoDialog, RequestMonitor, CustomerResource, CurrentShop) ->
|
||||
new class Customers
|
||||
all: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
add: (email) ->
|
||||
params =
|
||||
enterprise_id: CurrentShop.shop.id
|
||||
email: email
|
||||
CustomerResource.create params, (customer) =>
|
||||
if customer.id
|
||||
@all.unshift customer
|
||||
@byID[customer.id] = customer
|
||||
@pristineByID[customer.id] = angular.copy(customer)
|
||||
|
||||
remove: (customer) ->
|
||||
params = id: customer.id
|
||||
CustomerResource.destroy params, =>
|
||||
i = @all.indexOf customer
|
||||
@all.splice i, 1 unless i < 0
|
||||
, (response) =>
|
||||
errors = response.data.errors
|
||||
if errors?
|
||||
InfoDialog.open 'error', errors[0]
|
||||
else
|
||||
InfoDialog.open 'error', "Could not delete customer: #{customer.email}"
|
||||
|
||||
index: (params) ->
|
||||
@clear()
|
||||
request = CustomerResource.index(params, (data) => @load(data))
|
||||
RequestMonitor.load(request.$promise)
|
||||
request.$promise
|
||||
|
||||
load: (customers) ->
|
||||
for customer in customers
|
||||
@all.push customer
|
||||
@byID[customer.id] = customer
|
||||
@pristineByID[customer.id] = angular.copy(customer)
|
||||
|
||||
update: (address, customer, addressType) ->
|
||||
params =
|
||||
id: customer.id
|
||||
customer:
|
||||
"#{addressType}_attributes": address
|
||||
CustomerResource.update params
|
||||
|
||||
clear: ->
|
||||
@all.length = 0
|
||||
@@ -1,21 +1,18 @@
|
||||
angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResource, blankOption) ->
|
||||
angular.module("admin.resources").factory 'Enterprises', ($q, EnterpriseResource) ->
|
||||
new class Enterprises
|
||||
enterprisesByID: {}
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
includeBlank = !!params['includeBlank']
|
||||
delete params['includeBlank']
|
||||
EnterpriseResource.index(params, (data) =>
|
||||
for enterprise in data
|
||||
@enterprisesByID[enterprise.id] = enterprise
|
||||
@pristineByID[enterprise.id] = angular.copy(enterprise)
|
||||
|
||||
EnterpriseResource.index params, (data) =>
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
data.unshift(blankOption()) if includeBlank
|
||||
data
|
||||
)
|
||||
|
||||
load: (enterprises) ->
|
||||
for enterprise in enterprises
|
||||
@byID[enterprise.id] = enterprise
|
||||
@pristineByID[enterprise.id] = angular.copy(enterprise)
|
||||
|
||||
save: (enterprise) ->
|
||||
deferred = $q.defer()
|
||||
@@ -1,23 +1,25 @@
|
||||
angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
|
||||
angular.module("admin.resources").factory 'LineItems', ($q, LineItemResource) ->
|
||||
new class LineItems
|
||||
lineItemsByID: {}
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
LineItemResource.index params, (data) =>
|
||||
@resetData()
|
||||
for lineItem in data
|
||||
@lineItemsByID[lineItem.id] = lineItem
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
resetData: ->
|
||||
@lineItemsByID = {}
|
||||
@byID = {}
|
||||
@pristineByID = {}
|
||||
|
||||
load: (lineItems) ->
|
||||
@resetData()
|
||||
for lineItem in lineItems
|
||||
@byID[lineItem.id] = lineItem
|
||||
@pristineByID[lineItem.id] = angular.copy(lineItem)
|
||||
|
||||
saveAll: ->
|
||||
for id, lineItem of @lineItemsByID
|
||||
for id, lineItem of @byID
|
||||
lineItem.errors = {} # removes errors when line_item has been returned to original state
|
||||
@save(lineItem) if !@isSaved(lineItem)
|
||||
|
||||
@@ -34,7 +36,7 @@ angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
|
||||
deferred.promise
|
||||
|
||||
allSaved: ->
|
||||
for id, lineItem of @lineItemsByID
|
||||
for id, lineItem of @byID
|
||||
return false unless @isSaved(lineItem)
|
||||
true
|
||||
|
||||
@@ -54,7 +56,7 @@ angular.module("admin.lineItems").factory 'LineItems', ($q, LineItemResource) ->
|
||||
deferred = $q.defer()
|
||||
lineItem.$delete({id: lineItem.id, orders: "orders", order_number: lineItem.order.number})
|
||||
.then( (data) =>
|
||||
delete @lineItemsByID[lineItem.id]
|
||||
delete @byID[lineItem.id]
|
||||
delete @pristineByID[lineItem.id]
|
||||
(callback || angular.noop)(data)
|
||||
deferred.resolve(data)
|
||||
@@ -1,21 +1,24 @@
|
||||
angular.module("admin.orderCycles").factory 'OrderCycles', ($q, OrderCycleResource, blankOption) ->
|
||||
angular.module("admin.resources").factory 'OrderCycles', ($q, $injector, OrderCycleResource) ->
|
||||
new class OrderCycles
|
||||
orderCyclesByID: {}
|
||||
all: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
constructor: ->
|
||||
if $injector.has('orderCycles')
|
||||
@load($injector.get('orderCycles'))
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
includeBlank = !!params['includeBlank']
|
||||
delete params['includeBlank']
|
||||
OrderCycleResource.index(params, (data) =>
|
||||
for orderCycle in data
|
||||
@orderCyclesByID[orderCycle.id] = orderCycle
|
||||
@pristineByID[orderCycle.id] = angular.copy(orderCycle)
|
||||
|
||||
OrderCycleResource.index params, (data) =>
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
data.unshift(blankOption()) if includeBlank
|
||||
data
|
||||
)
|
||||
|
||||
load: (orderCycles) ->
|
||||
for orderCycle in orderCycles
|
||||
@all.push orderCycle
|
||||
@byID[orderCycle.id] = orderCycle
|
||||
@pristineByID[orderCycle.id] = angular.copy(orderCycle)
|
||||
|
||||
save: (order_cycle) ->
|
||||
deferred = $q.defer()
|
||||
@@ -1,16 +1,18 @@
|
||||
angular.module("admin.orders").factory 'Orders', ($q, OrderResource) ->
|
||||
angular.module("admin.resources").factory 'Orders', ($q, OrderResource) ->
|
||||
new class Orders
|
||||
ordersByID: {}
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
OrderResource.index params, (data) =>
|
||||
for order in data
|
||||
@ordersByID[order.id] = order
|
||||
@pristineByID[order.id] = angular.copy(order)
|
||||
|
||||
@load(data)
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
load: (orders) ->
|
||||
for order in orders
|
||||
@byID[order.id] = order
|
||||
@pristineByID[order.id] = angular.copy(order)
|
||||
|
||||
save: (order) ->
|
||||
deferred = $q.defer()
|
||||
order.$update({id: order.number})
|
||||
@@ -0,0 +1,16 @@
|
||||
angular.module("admin.resources")
|
||||
.factory "PaymentMethods", ($injector) ->
|
||||
new class PaymentMethods
|
||||
paymentMethods: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
constructor: ->
|
||||
if $injector.has('paymentMethods')
|
||||
@load($injector.get('paymentMethods'))
|
||||
|
||||
load: (paymentMethods) ->
|
||||
for paymentMethod in paymentMethods
|
||||
@paymentMethods.push paymentMethod
|
||||
@byID[paymentMethod.id] = paymentMethod
|
||||
@pristineByID[paymentMethod.id] = angular.copy(paymentMethod)
|
||||
@@ -0,0 +1,16 @@
|
||||
angular.module("admin.resources")
|
||||
.factory "ShippingMethods", ($injector) ->
|
||||
new class ShippingMethods
|
||||
shippingMethods: []
|
||||
byID: {}
|
||||
pristineByID: {}
|
||||
|
||||
constructor: ->
|
||||
if $injector.has('shippingMethods')
|
||||
@load($injector.get('shippingMethods'))
|
||||
|
||||
load: (shippingMethods) ->
|
||||
for shippingMethod in shippingMethods
|
||||
@shippingMethods.push shippingMethod
|
||||
@byID[shippingMethod.id] = shippingMethod
|
||||
@pristineByID[shippingMethod.id] = angular.copy(shippingMethod)
|
||||
@@ -1,3 +1,3 @@
|
||||
angular.module("admin.shippingMethods").controller "shippingMethodsCtrl", ($scope, ShippingMethods) ->
|
||||
$scope.findShippingMethodByID = (id) ->
|
||||
$scope.ShippingMethod = ShippingMethods.findByID(id)
|
||||
$scope.ShippingMethod = ShippingMethods.byID[id]
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
angular.module("admin.shippingMethods")
|
||||
.factory "ShippingMethods", (shippingMethods) ->
|
||||
new class ShippingMethods
|
||||
shippingMethods: shippingMethods
|
||||
|
||||
findByID: (id) ->
|
||||
for shippingMethod in @shippingMethods
|
||||
return shippingMethod if shippingMethod.id is id
|
||||
@@ -38,7 +38,6 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $fil
|
||||
newRule.peferred_exchange_tags = []
|
||||
newRule.preferred_matched_order_cycles_visibility = "visible"
|
||||
tagGroup.rules.push(newRule)
|
||||
$scope.enterprise_form.$setDirty()
|
||||
$scope.updateRuleCounts()
|
||||
|
||||
$scope.addNewTag = ->
|
||||
@@ -58,3 +57,4 @@ angular.module("admin.tagRules").controller "TagRulesCtrl", ($scope, $http, $fil
|
||||
.success ->
|
||||
tagGroup.rules.splice(index, 1)
|
||||
$scope.updateRuleCounts()
|
||||
$scope.enterprise_form.$setDirty()
|
||||
@@ -1,19 +1,20 @@
|
||||
angular.module("admin.taxons").factory "Taxons", (taxons, $filter) ->
|
||||
new class Taxons
|
||||
taxons: taxons
|
||||
taxonsByID: {}
|
||||
all: []
|
||||
byID: {}
|
||||
|
||||
constructor: ->
|
||||
for taxon in @taxons
|
||||
@taxonsByID[taxon.id] = taxon
|
||||
for taxon in taxons
|
||||
@all.push taxon
|
||||
@byID[taxon.id] = taxon
|
||||
|
||||
# For finding a single Taxon
|
||||
findByID: (id) ->
|
||||
@taxonsByID[id]
|
||||
@byID[id]
|
||||
|
||||
# For finding multiple Taxons represented by comma delimited string
|
||||
findByIDs: (ids) ->
|
||||
@taxonsByID[taxon_id] for taxon_id in ids.split(",") when @taxonsByID[taxon_id]
|
||||
@byID[taxon_id] for taxon_id in ids.split(",") when @byID[taxon_id]
|
||||
|
||||
findByTerm: (term) ->
|
||||
$filter('filter')(@taxons, term)
|
||||
$filter('filter')(@all, term)
|
||||
|
||||
@@ -30,8 +30,16 @@ show_flash_error = function(message) {
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
});
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
});
|
||||
|
||||
// Spree locates hidden with prev(), which with our current version of jQuery
|
||||
// does not locate the hidden field, resulting in the delete failing. This
|
||||
// handler updates the hidden field, fixing the problem.
|
||||
$('body').on('click', 'a.remove_fields', function() {
|
||||
$(this).next("input[type=hidden]").val("1");
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
angular.module("admin.utils").directive "textangularStrip", () ->
|
||||
restrict: 'CA'
|
||||
link: (scope, element, attrs) ->
|
||||
scope.stripFormatting = ($html) ->
|
||||
return String($html).replace(/<[^>]+>/gm, '')
|
||||
@@ -1,2 +0,0 @@
|
||||
angular.module("admin.utils").value "blankOption", ->
|
||||
{ id: "0", name: "All" }
|
||||
@@ -10,7 +10,6 @@ angular.module("admin.utils")
|
||||
|
||||
$rootScope.$on "$locationChangeStart", @locationChangeStartHandler
|
||||
|
||||
|
||||
# Action for regular browser navigation.
|
||||
onBeforeUnloadHandler: ($event) =>
|
||||
message = @getMessage()
|
||||
@@ -21,13 +20,17 @@ angular.module("admin.utils")
|
||||
|
||||
# Action for angular navigation.
|
||||
locationChangeStartHandler: ($event) =>
|
||||
message = @getMessage()
|
||||
if message and not $window.confirm(message)
|
||||
if not @confirmLeave()
|
||||
$event.stopPropagation() if $event.stopPropagation
|
||||
$event.preventDefault() if $event.preventDefault
|
||||
$event.cancelBubble = true
|
||||
$event.returnValue = false
|
||||
|
||||
# Check if leaving is okay
|
||||
confirmLeave: =>
|
||||
message = @getMessage()
|
||||
!message or $window.confirm(message)
|
||||
|
||||
# Runs callback functions to retreive most recently added non-empty message.
|
||||
getMessage: ->
|
||||
message = null
|
||||
|
||||
@@ -11,6 +11,14 @@ angular.module("admin.utils").factory "StatusMessage", ($timeout) ->
|
||||
text: ""
|
||||
style: {}
|
||||
|
||||
invalidMessage: ""
|
||||
|
||||
setValidation: (isValid) ->
|
||||
if isValid
|
||||
StatusMessage.invalidMessage = ''
|
||||
else
|
||||
StatusMessage.invalidMessage = t("admin.form_invalid")
|
||||
|
||||
active: ->
|
||||
@statusMessage.text != ''
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
$ ->
|
||||
if ($ 'form#update-cart').is('*')
|
||||
($ 'form#update-cart a.delete').show().one 'click', ->
|
||||
($ this).parents('.line-item').first().find('input.line_item_quantity').val 0
|
||||
($ this).parents('form').first().submit()
|
||||
if $('form#update-cart').is('*') || $('form#update-order').is('*')
|
||||
$('form#update-cart a.delete, form#update-order a.delete').show().one 'click', ->
|
||||
$(this).parents('.line-item').first().find('input.line_item_quantity').val 0
|
||||
$(this).parents('form').first().submit()
|
||||
false
|
||||
|
||||
($ 'form#update-cart').submit ->
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
Darkswarm.controller "AccordionCtrl", ($scope, storage, $timeout, $document, CurrentHub) ->
|
||||
$scope.accordion =
|
||||
details: true
|
||||
billing: false
|
||||
shipping: false
|
||||
payment: false
|
||||
Darkswarm.controller "AccordionCtrl", ($scope, localStorageService, $timeout, $document, CurrentHub) ->
|
||||
key = "accordion_#{$scope.order.id}#{CurrentHub.hub.id}#{$scope.order.user_id}"
|
||||
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"]
|
||||
storage.bind $scope, "accordion", {storeName: "accordion_#{$scope.order.id}#{CurrentHub.hub.id}#{$scope.order.user_id}"}
|
||||
|
||||
$scope.show = (section)->
|
||||
$scope.accordion[section] = true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.controller "CheckoutCtrl", ($scope, storage, Checkout, CurrentUser, CurrentHub) ->
|
||||
Darkswarm.controller "CheckoutCtrl", ($scope, localStorageService, Checkout, CurrentUser, CurrentHub) ->
|
||||
$scope.Checkout = Checkout
|
||||
$scope.submitted = false
|
||||
|
||||
@@ -7,11 +7,11 @@ Darkswarm.controller "CheckoutCtrl", ($scope, storage, Checkout, CurrentUser, Cu
|
||||
prefix = "order_#{Checkout.order.id}#{CurrentUser.id or ""}#{CurrentHub.hub.id}"
|
||||
|
||||
for field in $scope.fieldsToBind
|
||||
storage.bind $scope, "Checkout.order.#{field}",
|
||||
storeName: "#{prefix}_#{field}"
|
||||
storage.bind $scope, "Checkout.ship_address_same_as_billing",
|
||||
storeName: "#{prefix}_sameasbilling"
|
||||
defaultValue: true
|
||||
localStorageService.bind $scope, "Checkout.order.#{field}", Checkout.order[field], "#{prefix}_#{field}"
|
||||
|
||||
localStorageService.bind $scope, "Checkout.ship_address_same_as_billing", true, "#{prefix}_sameasbilling"
|
||||
localStorageService.bind $scope, "Checkout.default_bill_address", false, "#{prefix}_defaultasbilladdress"
|
||||
localStorageService.bind $scope, "Checkout.default_ship_address", false, "#{prefix}_defaultasshipaddress"
|
||||
|
||||
$scope.order = Checkout.order # Ordering is important
|
||||
$scope.secrets = Checkout.secrets
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Darkswarm.controller "EditBoughtOrderController", ($scope, $resource, Cart) ->
|
||||
$scope.showBought = false
|
||||
|
||||
$scope.deleteLineItem = (id) ->
|
||||
params = {id: id}
|
||||
success = (response) ->
|
||||
$(".line-item-" + id).remove()
|
||||
Cart.removeFinalisedLineItem(id)
|
||||
fail = (error) ->
|
||||
console.log error
|
||||
|
||||
$resource("/line_items/:id").delete(params, success, fail)
|
||||
@@ -10,7 +10,7 @@ Darkswarm.controller "OrderCycleCtrl", ($scope, $timeout, OrderCycle) ->
|
||||
$("#order_cycle_id").trigger("openTrigger")
|
||||
|
||||
|
||||
Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Products, Variants, Cart) ->
|
||||
Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Products, Variants, Cart, ChangeableOrdersAlert) ->
|
||||
# Track previous order cycle id for use with revertOrderCycle()
|
||||
$scope.previous_order_cycle_id = OrderCycle.order_cycle.order_cycle_id
|
||||
$scope.$watch 'order_cycle.order_cycle_id', (newValue, oldValue)->
|
||||
@@ -30,3 +30,5 @@ Darkswarm.controller "OrderCycleChangeCtrl", ($scope, $timeout, OrderCycle, Prod
|
||||
Variants.clear()
|
||||
Cart.clear()
|
||||
Products.update()
|
||||
Cart.reloadFinalisedLineItems()
|
||||
ChangeableOrdersAlert.reload()
|
||||
|
||||
@@ -5,7 +5,20 @@ Darkswarm.controller "RegistrationCtrl", ($scope, RegistrationService, Enterpris
|
||||
|
||||
$scope.steps = ['details', 'contact', 'type', 'about', 'images', 'social']
|
||||
|
||||
$scope.countries = availableCountries
|
||||
# Filter countries without states since the form requires a state to be selected.
|
||||
# Consider changing the form to require a state only if a country requires them (Spree option).
|
||||
# Invalid countries still need to be filtered (better server-side).
|
||||
$scope.countries = availableCountries.filter (country) ->
|
||||
country.states.length > 0
|
||||
|
||||
$scope.countriesById = $scope.countries.reduce (obj, country) ->
|
||||
obj[country.id] = country
|
||||
obj
|
||||
, {}
|
||||
|
||||
$scope.setDefaultCountry = (id) ->
|
||||
country = $scope.countriesById[id]
|
||||
$scope.enterprise.country = country if country
|
||||
|
||||
$scope.countryHasStates = ->
|
||||
$scope.enterprise.country.states.length > 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation) ->
|
||||
Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation, $location) ->
|
||||
angular.extend this, $controller('TabsCtrl', {$scope: $scope})
|
||||
|
||||
$scope.tabs =
|
||||
@@ -6,3 +6,7 @@ Darkswarm.controller "ShoppingTabsCtrl", ($scope, $controller, Navigation) ->
|
||||
producers: { active: Navigation.isActive('/producers') }
|
||||
contact: { active: Navigation.isActive('/contact') }
|
||||
groups: { active: Navigation.isActive('/groups') }
|
||||
|
||||
$scope.$on '$locationChangeStart', (event, url) ->
|
||||
tab = $location.path().replace(/^\//, '')
|
||||
$scope.tabs[tab]?.active = true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
window.Darkswarm = angular.module("Darkswarm", ["ngResource",
|
||||
'mm.foundation',
|
||||
'angularLocalStorage',
|
||||
'LocalStorageModule',
|
||||
'infinite-scroll',
|
||||
'angular-flash.service',
|
||||
'templates',
|
||||
@@ -11,8 +11,7 @@ window.Darkswarm = angular.module("Darkswarm", ["ngResource",
|
||||
'angularFileUpload',
|
||||
'angularSlideables'
|
||||
]).config ($httpProvider, $tooltipProvider, $locationProvider, $anchorScrollProvider) ->
|
||||
$httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers.put['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers['common']['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
|
||||
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.directive "ofnChangeOrderCycle", (OrderCycle, Cart, storage) ->
|
||||
Darkswarm.directive "ofnChangeOrderCycle", (OrderCycle, Cart) ->
|
||||
# Compares chosen order cycle with pre-set OrderCycle. Will trigger
|
||||
# a confirmation if they are different, and Cart isn't empty
|
||||
restrict: "A"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Darkswarm.directive "changeableOrdersAlert", (ChangeableOrdersAlert) ->
|
||||
restrict: "C"
|
||||
scope: true
|
||||
link: (scope, element, attrs) ->
|
||||
scope.alert = ChangeableOrdersAlert
|
||||
@@ -0,0 +1,9 @@
|
||||
Darkswarm.directive "confirmLinkClick", ($window) ->
|
||||
restrict: 'A'
|
||||
scope:
|
||||
confirmMsg: '@confirmLinkClick'
|
||||
link: (scope, elem, attr) ->
|
||||
elem.bind 'click', (event) ->
|
||||
unless confirm(scope.confirmMsg)
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
@@ -15,7 +15,7 @@ Darkswarm.directive 'mapOsmTiles', ($timeout) ->
|
||||
if x < 0
|
||||
x = tilesPerGlobe + x
|
||||
# Wrap y (latitude) in a like manner if you want to enable vertical infinite scroll
|
||||
'http://tile.openstreetmap.org/' + zoom + '/' + x + '/' + coord.y + '.png'
|
||||
'https://a.tile.openstreetmap.org/' + zoom + '/' + x + '/' + coord.y + '.png'
|
||||
tileSize: new google.maps.Size(256, 256)
|
||||
name: 'OpenStreetMap'
|
||||
maxZoom: 18
|
||||
|
||||
@@ -6,7 +6,11 @@ Darkswarm.directive "ofnOnHand", ->
|
||||
# In cases where this field gets its value from the HTML element rather than the model,
|
||||
# initialise the model with the HTML value.
|
||||
if scope.$eval(attr.ngModel) == undefined
|
||||
ngModel.$setViewValue elem.val()
|
||||
# Don't dirty the model when we do this
|
||||
setDirty = ngModel.$setDirty
|
||||
ngModel.$setDirty = angular.noop
|
||||
ngModel.$setViewValue(elem.val())
|
||||
ngModel.$setDirty = setDirty
|
||||
|
||||
ngModel.$parsers.push (viewValue) ->
|
||||
on_hand = parseInt(attr.ofnOnHand)
|
||||
|
||||
@@ -4,5 +4,5 @@ Darkswarm.filter 'products', (Matcher) ->
|
||||
text ?= ""
|
||||
return products if text == ""
|
||||
products.filter (product) =>
|
||||
propertiesToMatch = [product.name, product.supplier.name, product.primary_taxon.name]
|
||||
Matcher.match propertiesToMatch, text
|
||||
propertiesToMatch = [product.name, product.variant_names, product.supplier.name, product.primary_taxon.name]
|
||||
Matcher.matchBeginning propertiesToMatch, text
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
Darkswarm.filter 'properties', ()->
|
||||
# Filter anything that responds to object.properties
|
||||
(objects, ids) ->
|
||||
Darkswarm.filter 'properties', ->
|
||||
# Filter anything that responds to object.supplied_properties
|
||||
(objects, ids, source) ->
|
||||
objects ||= []
|
||||
ids ?= []
|
||||
|
||||
source ||= 'properties'
|
||||
return [] unless source in ['properties', 'supplied_properties', 'distributed_properties']
|
||||
|
||||
if ids.length == 0
|
||||
# No properties selected, pass all objects through.
|
||||
objects
|
||||
else
|
||||
objects.filter (obj)->
|
||||
properties = obj.properties
|
||||
# Combine object properties with supplied properties, if they exist.
|
||||
# properties = properties.concat obj.supplied_properties if obj.supplied_properties
|
||||
# Match property array.
|
||||
properties.some (property)->
|
||||
objects.filter (obj) ->
|
||||
properties = obj[source]
|
||||
properties.some (property) ->
|
||||
property.id in ids
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
Darkswarm.filter 'propertiesOf', ->
|
||||
(objects)->
|
||||
(objects, source) ->
|
||||
source ||= 'properties'
|
||||
return {} unless source in ['properties', 'supplied_properties', 'distributed_properties']
|
||||
|
||||
properties = {}
|
||||
for object in objects
|
||||
for property in object.properties
|
||||
properties[property.id] = property
|
||||
if object[source]?
|
||||
for property in object[source]
|
||||
properties[property.id] = property
|
||||
|
||||
properties
|
||||
|
||||
@@ -25,9 +25,7 @@ Darkswarm.factory "AuthenticationService", (Navigation, $modal, $location, Redir
|
||||
isActive: Navigation.isActive
|
||||
|
||||
close: ->
|
||||
if location.pathname in ["/", "/checkout"]
|
||||
Navigation.navigate "/"
|
||||
else
|
||||
if location.pathname in ["/register", "/register/auth"]
|
||||
Loading.message = t 'going_back_to_home_page'
|
||||
location.hash = ""
|
||||
location.pathname = "/"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, storage)->
|
||||
Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $rootScope, $resource, localStorageService) ->
|
||||
# Handles syncing of current cart/order state to server
|
||||
new class Cart
|
||||
dirty: false
|
||||
@@ -6,11 +6,15 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo
|
||||
update_enqueued: false
|
||||
order: CurrentOrder.order
|
||||
line_items: CurrentOrder.order?.line_items || []
|
||||
line_items_finalised: CurrentOrder.order?.finalised_line_items || []
|
||||
|
||||
constructor: ->
|
||||
for line_item in @line_items
|
||||
line_item.variant.line_item = line_item
|
||||
Variants.register line_item.variant
|
||||
for line_item in @line_items_finalised
|
||||
line_item.variant.line_item = line_item
|
||||
Variants.extend line_item.variant
|
||||
|
||||
adjust: (line_item) =>
|
||||
line_item.total_price = line_item.variant.price_with_fees * line_item.quantity
|
||||
@@ -114,4 +118,16 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http, $modal, $roo
|
||||
|
||||
clear: ->
|
||||
@line_items = []
|
||||
storage.clearAll() # One day this will have to be moar GRANULAR
|
||||
localStorageService.clearAll() # One day this will have to be moar GRANULAR
|
||||
|
||||
removeFinalisedLineItem: (id) =>
|
||||
@line_items_finalised = @line_items_finalised.filter (item) ->
|
||||
item.id != id
|
||||
|
||||
reloadFinalisedLineItems: =>
|
||||
@line_items_finalised = []
|
||||
$resource("/line_items/bought").query (items) =>
|
||||
for line_item in items
|
||||
line_item.variant.line_item = line_item
|
||||
Variants.extend line_item.variant
|
||||
@line_items_finalised = items
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
Darkswarm.factory 'ChangeableOrdersAlert', ($http) ->
|
||||
new class ChangeableOrdersAlert
|
||||
html: ''
|
||||
visible: true
|
||||
|
||||
constructor: ->
|
||||
@reload()
|
||||
|
||||
reload: ->
|
||||
$http.get('/shop/changeable_orders_alert').then (response) =>
|
||||
@html = response.data.trim()
|
||||
|
||||
close: =>
|
||||
@visible = false
|
||||
@@ -3,7 +3,6 @@ Darkswarm.factory 'Checkout', (CurrentOrder, ShippingMethods, PaymentMethods, $h
|
||||
errors: {}
|
||||
secrets: {}
|
||||
order: CurrentOrder.order
|
||||
ship_address_same_as_billing: true
|
||||
|
||||
submit: ->
|
||||
Loading.message = t 'submitting_order'
|
||||
@@ -19,7 +18,10 @@ Darkswarm.factory 'Checkout', (CurrentOrder, ShippingMethods, PaymentMethods, $h
|
||||
|
||||
# Rails wants our Spree::Address data to be provided with _attributes
|
||||
preprocess: ->
|
||||
munged_order = {}
|
||||
munged_order =
|
||||
default_bill_address: !!@default_bill_address
|
||||
default_ship_address: !!@default_ship_address
|
||||
|
||||
for name, value of @order # Clone all data from the order JSON object
|
||||
switch name
|
||||
when "bill_address"
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
Darkswarm.factory "Matcher", ->
|
||||
# Match text fragment in an array of strings.
|
||||
new class Matcher
|
||||
|
||||
# Match text fragment in an array of strings.
|
||||
match: (properties, text)->
|
||||
properties.some (prop)->
|
||||
prop ||= ""
|
||||
prop.toLowerCase().indexOf(text.toLowerCase()) != -1
|
||||
|
||||
# Return true if text occurs at the beginning of any word present in an array of strings
|
||||
matchBeginning: (properties, text) ->
|
||||
text = text.trim()
|
||||
regexp = new RegExp("(?:^|[\\s-])#{text}", "i")
|
||||
properties.some (prop) -> (prop || "").search(regexp) >= 0
|
||||
|
||||
@@ -3,10 +3,12 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub,
|
||||
constructor: ->
|
||||
# Populate Orders.orders from json in page.
|
||||
@orders_by_distributor = orders_by_distributor
|
||||
@changeable_orders = []
|
||||
@currency_symbol = currencyConfig.symbol
|
||||
|
||||
for distributor in @orders_by_distributor
|
||||
@updateRunningBalance(distributor.distributed_orders)
|
||||
@findChangeableOrders(distributor.distributed_orders)
|
||||
@updateRunningBalance(distributor.distributed_orders)
|
||||
|
||||
|
||||
updateRunningBalance: (orders) ->
|
||||
@@ -14,3 +16,7 @@ Darkswarm.factory 'Orders', (orders_by_distributor, currencyConfig, CurrentHub,
|
||||
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)
|
||||
|
||||
findChangeableOrders: (orders) ->
|
||||
for order in orders when order.changes_allowed
|
||||
@changeable_orders.push(order)
|
||||
|
||||
@@ -25,7 +25,6 @@ Darkswarm.factory 'Products', ($resource, Enterprises, Dereferencer, Taxons, Pro
|
||||
prices = (v.price for v in product.variants)
|
||||
product.price = Math.min.apply(null, prices)
|
||||
product.hasVariants = product.variants?.length > 0
|
||||
|
||||
product.primaryImage = product.images[0]?.small_url if product.images
|
||||
product.primaryImageOrMissing = product.primaryImage || "/assets/noimage/small.png"
|
||||
product.largeImage = product.images[0]?.large_url if product.images
|
||||
@@ -43,7 +42,10 @@ Darkswarm.factory 'Products', ($resource, Enterprises, Dereferencer, Taxons, Pro
|
||||
registerVariants: ->
|
||||
for product in @products
|
||||
if product.variants
|
||||
product.variant_names = ""
|
||||
product.variants = for variant in product.variants
|
||||
variant = Variants.register variant
|
||||
if product.name != variant.name_to_display
|
||||
product.variant_names += variant.name_to_display + " "
|
||||
variant.product = product
|
||||
variant
|
||||
|
||||
@@ -1,171 +1,546 @@
|
||||
/*
|
||||
* Angular.js localStorage module
|
||||
* https://github.com/agrublev/angularLocalStorage
|
||||
/**
|
||||
* An Angular module that gives you access to the browsers local storage
|
||||
* @version v0.5.0 - 2016-08-29
|
||||
* @link https://github.com/grevory/angular-local-storage
|
||||
* @author grevory <greg@gregpike.ca>
|
||||
* @license MIT License, http://www.opensource.org/licenses/MIT
|
||||
*/
|
||||
(function (window, angular) {
|
||||
var isDefined = angular.isDefined,
|
||||
isUndefined = angular.isUndefined,
|
||||
isNumber = angular.isNumber,
|
||||
isObject = angular.isObject,
|
||||
isArray = angular.isArray,
|
||||
extend = angular.extend,
|
||||
toJson = angular.toJson;
|
||||
|
||||
(function (window, angular, undefined) {
|
||||
'use strict';
|
||||
angular
|
||||
.module('LocalStorageModule', [])
|
||||
.provider('localStorageService', function() {
|
||||
// You should set a prefix to avoid overwriting any local storage variables from the rest of your app
|
||||
// e.g. localStorageServiceProvider.setPrefix('yourAppName');
|
||||
// With provider you can use config as this:
|
||||
// myApp.config(function (localStorageServiceProvider) {
|
||||
// localStorageServiceProvider.prefix = 'yourAppName';
|
||||
// });
|
||||
this.prefix = 'ls';
|
||||
|
||||
angular.module('angularLocalStorage', ['ngCookies']).factory('storage', ['$parse', '$cookieStore', '$window', '$log', function ($parse, $cookieStore, $window, $log) {
|
||||
/**
|
||||
* Global Vars
|
||||
*/
|
||||
var storage = (typeof $window.localStorage === 'undefined') ? undefined : $window.localStorage;
|
||||
var supported = typeof storage !== 'undefined';
|
||||
// You could change web storage type localstorage or sessionStorage
|
||||
this.storageType = 'localStorage';
|
||||
|
||||
var privateMethods = {
|
||||
/**
|
||||
* Pass any type of a string from the localStorage to be parsed so it returns a usable version (like an Object)
|
||||
* @param res - a string that will be parsed for type
|
||||
* @returns {*} - whatever the real type of stored value was
|
||||
*/
|
||||
parseValue: function (res) {
|
||||
var val;
|
||||
try {
|
||||
val = angular.fromJson(res);
|
||||
if (typeof val === 'undefined') {
|
||||
val = res;
|
||||
}
|
||||
if (val === 'true') {
|
||||
val = true;
|
||||
}
|
||||
if (val === 'false') {
|
||||
val = false;
|
||||
}
|
||||
if ($window.parseFloat(val) === val && !angular.isObject(val)) {
|
||||
val = $window.parseFloat(val);
|
||||
}
|
||||
} catch (e) {
|
||||
val = res;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
};
|
||||
// Cookie options (usually in case of fallback)
|
||||
// expiry = Number of days before cookies expire // 0 = Does not expire
|
||||
// path = The web path the cookie represents
|
||||
// secure = Wether the cookies should be secure (i.e only sent on HTTPS requests)
|
||||
this.cookie = {
|
||||
expiry: 30,
|
||||
path: '/',
|
||||
secure: false
|
||||
};
|
||||
|
||||
var publicMethods = {
|
||||
/**
|
||||
* Set - let's you set a new localStorage key pair set
|
||||
* @param key - a string that will be used as the accessor for the pair
|
||||
* @param value - the value of the localStorage item
|
||||
* @returns {*} - will return whatever it is you've stored in the local storage
|
||||
*/
|
||||
set: function (key, value) {
|
||||
if (!supported) {
|
||||
try {
|
||||
$cookieStore.put(key, value);
|
||||
return value;
|
||||
} catch(e) {
|
||||
$log.log('Local Storage not supported, make sure you have angular-cookies enabled.');
|
||||
}
|
||||
}
|
||||
var saver = angular.toJson(value);
|
||||
storage.setItem(key, saver);
|
||||
return privateMethods.parseValue(saver);
|
||||
},
|
||||
// Decides wether we should default to cookies if localstorage is not supported.
|
||||
this.defaultToCookie = true;
|
||||
|
||||
/**
|
||||
* Get - let's you get the value of any pair you've stored
|
||||
* @param key - the string that you set as accessor for the pair
|
||||
* @returns {*} - Object,String,Float,Boolean depending on what you stored
|
||||
*/
|
||||
get: function (key) {
|
||||
if (!supported) {
|
||||
try {
|
||||
return privateMethods.parseValue($.cookie(key));
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
var item = storage.getItem(key);
|
||||
return privateMethods.parseValue(item);
|
||||
},
|
||||
// Send signals for each of the following actions?
|
||||
this.notify = {
|
||||
setItem: true,
|
||||
removeItem: false
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove - let's you nuke a value from localStorage
|
||||
* @param key - the accessor value
|
||||
* @returns {boolean} - if everything went as planned
|
||||
*/
|
||||
remove: function (key) {
|
||||
if (!supported) {
|
||||
try {
|
||||
$cookieStore.remove(key);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
storage.removeItem(key);
|
||||
return true;
|
||||
},
|
||||
// Setter for the prefix
|
||||
this.setPrefix = function(prefix) {
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind - let's you directly bind a localStorage value to a $scope variable
|
||||
* @param {Angular $scope} $scope - the current scope you want the variable available in
|
||||
* @param {String} key - the name of the variable you are binding
|
||||
* @param {Object} opts - (optional) custom options like default value or unique store name
|
||||
* Here are the available options you can set:
|
||||
* * defaultValue: the default value
|
||||
* * storeName: add a custom store key value instead of using the scope variable name
|
||||
* @returns {*} - returns whatever the stored value is
|
||||
*/
|
||||
bind: function ($scope, key, opts) {
|
||||
var defaultOpts = {
|
||||
defaultValue: '',
|
||||
storeName: ''
|
||||
};
|
||||
// Backwards compatibility with old defaultValue string
|
||||
if (angular.isString(opts)) {
|
||||
opts = angular.extend({},defaultOpts,{defaultValue:opts});
|
||||
} else {
|
||||
// If no defined options we use defaults otherwise extend defaults
|
||||
opts = (angular.isUndefined(opts)) ? defaultOpts : angular.extend(defaultOpts,opts);
|
||||
}
|
||||
// Setter for the storageType
|
||||
this.setStorageType = function(storageType) {
|
||||
this.storageType = storageType;
|
||||
return this;
|
||||
};
|
||||
// Setter for defaultToCookie value, default is true.
|
||||
this.setDefaultToCookie = function (shouldDefault) {
|
||||
this.defaultToCookie = !!shouldDefault; // Double-not to make sure it's a bool value.
|
||||
return this;
|
||||
};
|
||||
// Setter for cookie config
|
||||
this.setStorageCookie = function(exp, path, secure) {
|
||||
this.cookie.expiry = exp;
|
||||
this.cookie.path = path;
|
||||
this.cookie.secure = secure;
|
||||
return this;
|
||||
};
|
||||
|
||||
// Set the storeName key for the localStorage entry
|
||||
// use user defined in specified
|
||||
var storeName = opts.storeName || key;
|
||||
// Setter for cookie domain
|
||||
this.setStorageCookieDomain = function(domain) {
|
||||
this.cookie.domain = domain;
|
||||
return this;
|
||||
};
|
||||
|
||||
// If a value doesn't already exist store it as is
|
||||
if (!publicMethods.get(storeName)) {
|
||||
publicMethods.set(storeName, $parse(key)($scope) || opts.defaultValue);
|
||||
} else {
|
||||
// If it does exist assign it to the $scope value
|
||||
$parse(key).assign($scope, publicMethods.get(storeName));
|
||||
// Setter for notification config
|
||||
// itemSet & itemRemove should be booleans
|
||||
this.setNotify = function(itemSet, itemRemove) {
|
||||
this.notify = {
|
||||
setItem: itemSet,
|
||||
removeItem: itemRemove
|
||||
};
|
||||
return this;
|
||||
};
|
||||
|
||||
this.$get = ['$rootScope', '$window', '$document', '$parse','$timeout', function($rootScope, $window, $document, $parse, $timeout) {
|
||||
var self = this;
|
||||
var prefix = self.prefix;
|
||||
var cookie = self.cookie;
|
||||
var notify = self.notify;
|
||||
var storageType = self.storageType;
|
||||
var webStorage;
|
||||
|
||||
// When Angular's $document is not available
|
||||
if (!$document) {
|
||||
$document = document;
|
||||
} else if ($document[0]) {
|
||||
$document = $document[0];
|
||||
}
|
||||
|
||||
// If there is a prefix set in the config lets use that with an appended period for readability
|
||||
if (prefix.substr(-1) !== '.') {
|
||||
prefix = !!prefix ? prefix + '.' : '';
|
||||
}
|
||||
var deriveQualifiedKey = function(key) {
|
||||
return prefix + key;
|
||||
};
|
||||
|
||||
// Removes prefix from the key.
|
||||
var underiveQualifiedKey = function (key) {
|
||||
return key.replace(new RegExp('^' + prefix, 'g'), '');
|
||||
};
|
||||
|
||||
// Check if the key is within our prefix namespace.
|
||||
var isKeyPrefixOurs = function (key) {
|
||||
return key.indexOf(prefix) === 0;
|
||||
};
|
||||
|
||||
// Checks the browser to see if local storage is supported
|
||||
var checkSupport = function () {
|
||||
try {
|
||||
var supported = (storageType in $window && $window[storageType] !== null);
|
||||
|
||||
// When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
|
||||
// is available, but trying to call .setItem throws an exception.
|
||||
//
|
||||
// "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage
|
||||
// that exceeded the quota."
|
||||
var key = deriveQualifiedKey('__' + Math.round(Math.random() * 1e7));
|
||||
if (supported) {
|
||||
webStorage = $window[storageType];
|
||||
webStorage.setItem(key, '');
|
||||
webStorage.removeItem(key);
|
||||
}
|
||||
|
||||
return supported;
|
||||
} catch (e) {
|
||||
// Only change storageType to cookies if defaulting is enabled.
|
||||
if (self.defaultToCookie)
|
||||
storageType = 'cookie';
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
var browserSupportsLocalStorage = checkSupport();
|
||||
|
||||
// Directly adds a value to local storage
|
||||
// If local storage is not available in the browser use cookies
|
||||
// Example use: localStorageService.add('library','angular');
|
||||
var addToLocalStorage = function (key, value, type) {
|
||||
setStorageType(type);
|
||||
|
||||
// Let's convert undefined values to null to get the value consistent
|
||||
if (isUndefined(value)) {
|
||||
value = null;
|
||||
} else {
|
||||
value = toJson(value);
|
||||
}
|
||||
|
||||
// If this browser does not support local storage use cookies
|
||||
if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
|
||||
if (!browserSupportsLocalStorage) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
// Register a listener for changes on the $scope value
|
||||
// to update the localStorage value
|
||||
$scope.$watch(key, function (val) {
|
||||
if (angular.isDefined(val)) {
|
||||
publicMethods.set(storeName, val);
|
||||
}
|
||||
}, true);
|
||||
if (notify.setItem) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: 'cookie'});
|
||||
}
|
||||
return addToCookies(key, value);
|
||||
}
|
||||
|
||||
return publicMethods.get(storeName);
|
||||
},
|
||||
/**
|
||||
* Unbind - let's you unbind a variable from localStorage while removing the value from both
|
||||
* the localStorage and the local variable and sets it to null
|
||||
* @param $scope - the scope the variable was initially set in
|
||||
* @param key - the name of the variable you are unbinding
|
||||
* @param storeName - (optional) if you used a custom storeName you will have to specify it here as well
|
||||
*/
|
||||
unbind: function($scope,key,storeName) {
|
||||
storeName = storeName || key;
|
||||
$parse(key).assign($scope, null);
|
||||
$scope.$watch(key, function () { });
|
||||
publicMethods.remove(storeName);
|
||||
},
|
||||
/**
|
||||
* Clear All - let's you clear out ALL localStorage variables, use this carefully!
|
||||
*/
|
||||
clearAll: function() {
|
||||
storage.clear();
|
||||
}
|
||||
};
|
||||
try {
|
||||
if (webStorage) {
|
||||
webStorage.setItem(deriveQualifiedKey(key), value);
|
||||
}
|
||||
if (notify.setItem) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.setitem', {key: key, newvalue: value, storageType: self.storageType});
|
||||
}
|
||||
} catch (e) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
||||
return addToCookies(key, value);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}]);
|
||||
// Directly get a value from local storage
|
||||
// Example use: localStorageService.get('library'); // returns 'angular'
|
||||
var getFromLocalStorage = function (key, type) {
|
||||
setStorageType(type);
|
||||
|
||||
if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
|
||||
if (!browserSupportsLocalStorage) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
return getFromCookies(key);
|
||||
}
|
||||
|
||||
var item = webStorage ? webStorage.getItem(deriveQualifiedKey(key)) : null;
|
||||
// angular.toJson will convert null to 'null', so a proper conversion is needed
|
||||
// FIXME not a perfect solution, since a valid 'null' string can't be stored
|
||||
if (!item || item === 'null') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(item);
|
||||
} catch (e) {
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
// Remove an item from local storage
|
||||
// Example use: localStorageService.remove('library'); // removes the key/value pair of library='angular'
|
||||
//
|
||||
// This is var-arg removal, check the last argument to see if it is a storageType
|
||||
// and set type accordingly before removing.
|
||||
//
|
||||
var removeFromLocalStorage = function () {
|
||||
// can't pop on arguments, so we do this
|
||||
var consumed = 0;
|
||||
if (arguments.length >= 1 &&
|
||||
(arguments[arguments.length - 1] === 'localStorage' ||
|
||||
arguments[arguments.length - 1] === 'sessionStorage')) {
|
||||
consumed = 1;
|
||||
setStorageType(arguments[arguments.length - 1]);
|
||||
}
|
||||
|
||||
var i, key;
|
||||
for (i = 0; i < arguments.length - consumed; i++) {
|
||||
key = arguments[i];
|
||||
if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
|
||||
if (!browserSupportsLocalStorage) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
||||
}
|
||||
|
||||
if (notify.removeItem) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {key: key, storageType: 'cookie'});
|
||||
}
|
||||
removeFromCookies(key);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
webStorage.removeItem(deriveQualifiedKey(key));
|
||||
if (notify.removeItem) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.removeitem', {
|
||||
key: key,
|
||||
storageType: self.storageType
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
||||
removeFromCookies(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Return array of keys for local storage
|
||||
// Example use: var keys = localStorageService.keys()
|
||||
var getKeysForLocalStorage = function (type) {
|
||||
setStorageType(type);
|
||||
|
||||
if (!browserSupportsLocalStorage) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
||||
return [];
|
||||
}
|
||||
|
||||
var prefixLength = prefix.length;
|
||||
var keys = [];
|
||||
for (var key in webStorage) {
|
||||
// Only return keys that are for this app
|
||||
if (key.substr(0, prefixLength) === prefix) {
|
||||
try {
|
||||
keys.push(key.substr(prefixLength));
|
||||
} catch (e) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', e.Description);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
|
||||
// Remove all data for this app from local storage
|
||||
// Also optionally takes a regular expression string and removes the matching key-value pairs
|
||||
// Example use: localStorageService.clearAll();
|
||||
// Should be used mostly for development purposes
|
||||
var clearAllFromLocalStorage = function (regularExpression, type) {
|
||||
setStorageType(type);
|
||||
|
||||
// Setting both regular expressions independently
|
||||
// Empty strings result in catchall RegExp
|
||||
var prefixRegex = !!prefix ? new RegExp('^' + prefix) : new RegExp();
|
||||
var testRegex = !!regularExpression ? new RegExp(regularExpression) : new RegExp();
|
||||
|
||||
if (!browserSupportsLocalStorage && self.defaultToCookie || self.storageType === 'cookie') {
|
||||
if (!browserSupportsLocalStorage) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.warning', 'LOCAL_STORAGE_NOT_SUPPORTED');
|
||||
}
|
||||
return clearAllFromCookies();
|
||||
}
|
||||
if (!browserSupportsLocalStorage && !self.defaultToCookie)
|
||||
return false;
|
||||
var prefixLength = prefix.length;
|
||||
|
||||
for (var key in webStorage) {
|
||||
// Only remove items that are for this app and match the regular expression
|
||||
if (prefixRegex.test(key) && testRegex.test(key.substr(prefixLength))) {
|
||||
try {
|
||||
removeFromLocalStorage(key.substr(prefixLength));
|
||||
} catch (e) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
||||
return clearAllFromCookies();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Checks the browser to see if cookies are supported
|
||||
var browserSupportsCookies = (function() {
|
||||
try {
|
||||
return $window.navigator.cookieEnabled ||
|
||||
("cookie" in $document && ($document.cookie.length > 0 ||
|
||||
($document.cookie = "test").indexOf.call($document.cookie, "test") > -1));
|
||||
} catch (e) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
||||
return false;
|
||||
}
|
||||
}());
|
||||
|
||||
// Directly adds a value to cookies
|
||||
// Typically used as a fallback if local storage is not available in the browser
|
||||
// Example use: localStorageService.cookie.add('library','angular');
|
||||
var addToCookies = function (key, value, daysToExpiry, secure) {
|
||||
|
||||
if (isUndefined(value)) {
|
||||
return false;
|
||||
} else if(isArray(value) || isObject(value)) {
|
||||
value = toJson(value);
|
||||
}
|
||||
|
||||
if (!browserSupportsCookies) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
var expiry = '',
|
||||
expiryDate = new Date(),
|
||||
cookieDomain = '';
|
||||
|
||||
if (value === null) {
|
||||
// Mark that the cookie has expired one day ago
|
||||
expiryDate.setTime(expiryDate.getTime() + (-1 * 24 * 60 * 60 * 1000));
|
||||
expiry = "; expires=" + expiryDate.toGMTString();
|
||||
value = '';
|
||||
} else if (isNumber(daysToExpiry) && daysToExpiry !== 0) {
|
||||
expiryDate.setTime(expiryDate.getTime() + (daysToExpiry * 24 * 60 * 60 * 1000));
|
||||
expiry = "; expires=" + expiryDate.toGMTString();
|
||||
} else if (cookie.expiry !== 0) {
|
||||
expiryDate.setTime(expiryDate.getTime() + (cookie.expiry * 24 * 60 * 60 * 1000));
|
||||
expiry = "; expires=" + expiryDate.toGMTString();
|
||||
}
|
||||
if (!!key) {
|
||||
var cookiePath = "; path=" + cookie.path;
|
||||
if (cookie.domain) {
|
||||
cookieDomain = "; domain=" + cookie.domain;
|
||||
}
|
||||
/* Providing the secure parameter always takes precedence over config
|
||||
* (allows developer to mix and match secure + non-secure) */
|
||||
if (typeof secure === 'boolean') {
|
||||
if (secure === true) {
|
||||
/* We've explicitly specified secure,
|
||||
* add the secure attribute to the cookie (after domain) */
|
||||
cookieDomain += "; secure";
|
||||
}
|
||||
// else - secure has been supplied but isn't true - so don't set secure flag, regardless of what config says
|
||||
}
|
||||
else if (cookie.secure === true) {
|
||||
// secure parameter wasn't specified, get default from config
|
||||
cookieDomain += "; secure";
|
||||
}
|
||||
$document.cookie = deriveQualifiedKey(key) + "=" + encodeURIComponent(value) + expiry + cookiePath + cookieDomain;
|
||||
}
|
||||
} catch (e) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', e.message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Directly get a value from a cookie
|
||||
// Example use: localStorageService.cookie.get('library'); // returns 'angular'
|
||||
var getFromCookies = function (key) {
|
||||
if (!browserSupportsCookies) {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.error', 'COOKIES_NOT_SUPPORTED');
|
||||
return false;
|
||||
}
|
||||
|
||||
var cookies = $document.cookie && $document.cookie.split(';') || [];
|
||||
for(var i=0; i < cookies.length; i++) {
|
||||
var thisCookie = cookies[i];
|
||||
while (thisCookie.charAt(0) === ' ') {
|
||||
thisCookie = thisCookie.substring(1,thisCookie.length);
|
||||
}
|
||||
if (thisCookie.indexOf(deriveQualifiedKey(key) + '=') === 0) {
|
||||
var storedValues = decodeURIComponent(thisCookie.substring(prefix.length + key.length + 1, thisCookie.length));
|
||||
try {
|
||||
return JSON.parse(storedValues);
|
||||
} catch(e) {
|
||||
return storedValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
var removeFromCookies = function (key) {
|
||||
addToCookies(key,null);
|
||||
};
|
||||
|
||||
var clearAllFromCookies = function () {
|
||||
var thisCookie = null;
|
||||
var prefixLength = prefix.length;
|
||||
var cookies = $document.cookie.split(';');
|
||||
for(var i = 0; i < cookies.length; i++) {
|
||||
thisCookie = cookies[i];
|
||||
|
||||
while (thisCookie.charAt(0) === ' ') {
|
||||
thisCookie = thisCookie.substring(1, thisCookie.length);
|
||||
}
|
||||
|
||||
var key = thisCookie.substring(prefixLength, thisCookie.indexOf('='));
|
||||
removeFromCookies(key);
|
||||
}
|
||||
};
|
||||
|
||||
var getStorageType = function() {
|
||||
return storageType;
|
||||
};
|
||||
|
||||
var setStorageType = function(type) {
|
||||
if (type && storageType !== type) {
|
||||
storageType = type;
|
||||
browserSupportsLocalStorage = checkSupport();
|
||||
}
|
||||
return browserSupportsLocalStorage;
|
||||
};
|
||||
|
||||
// Add a listener on scope variable to save its changes to local storage
|
||||
// Return a function which when called cancels binding
|
||||
var bindToScope = function(scope, key, def, lsKey, type) {
|
||||
lsKey = lsKey || key;
|
||||
var value = getFromLocalStorage(lsKey, type);
|
||||
|
||||
if (value === null && isDefined(def)) {
|
||||
value = def;
|
||||
} else if (isObject(value) && isObject(def)) {
|
||||
value = extend(value, def);
|
||||
}
|
||||
|
||||
$parse(key).assign(scope, value);
|
||||
|
||||
return scope.$watch(key, function(newVal) {
|
||||
addToLocalStorage(lsKey, newVal, type);
|
||||
}, isObject(scope[key]));
|
||||
};
|
||||
|
||||
// Add listener to local storage, for update callbacks.
|
||||
if (browserSupportsLocalStorage) {
|
||||
if ($window.addEventListener) {
|
||||
$window.addEventListener("storage", handleStorageChangeCallback, false);
|
||||
$rootScope.$on('$destroy', function() {
|
||||
$window.removeEventListener("storage", handleStorageChangeCallback);
|
||||
});
|
||||
} else if($window.attachEvent){
|
||||
// attachEvent and detachEvent are proprietary to IE v6-10
|
||||
$window.attachEvent("onstorage", handleStorageChangeCallback);
|
||||
$rootScope.$on('$destroy', function() {
|
||||
$window.detachEvent("onstorage", handleStorageChangeCallback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Callback handler for storage changed.
|
||||
function handleStorageChangeCallback(e) {
|
||||
if (!e) { e = $window.event; }
|
||||
if (notify.setItem) {
|
||||
if (isKeyPrefixOurs(e.key)) {
|
||||
var key = underiveQualifiedKey(e.key);
|
||||
// Use timeout, to avoid using $rootScope.$apply.
|
||||
$timeout(function () {
|
||||
$rootScope.$broadcast('LocalStorageModule.notification.changed', { key: key, newvalue: e.newValue, storageType: self.storageType });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return localStorageService.length
|
||||
// ignore keys that not owned
|
||||
var lengthOfLocalStorage = function(type) {
|
||||
setStorageType(type);
|
||||
|
||||
var count = 0;
|
||||
var storage = $window[storageType];
|
||||
for(var i = 0; i < storage.length; i++) {
|
||||
if(storage.key(i).indexOf(prefix) === 0 ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
return {
|
||||
isSupported: browserSupportsLocalStorage,
|
||||
getStorageType: getStorageType,
|
||||
setStorageType: setStorageType,
|
||||
set: addToLocalStorage,
|
||||
add: addToLocalStorage, //DEPRECATED
|
||||
get: getFromLocalStorage,
|
||||
keys: getKeysForLocalStorage,
|
||||
remove: removeFromLocalStorage,
|
||||
clearAll: clearAllFromLocalStorage,
|
||||
bind: bindToScope,
|
||||
deriveKey: deriveQualifiedKey,
|
||||
underiveKey: underiveQualifiedKey,
|
||||
length: lengthOfLocalStorage,
|
||||
defaultToCookie: this.defaultToCookie,
|
||||
cookie: {
|
||||
isSupported: browserSupportsCookies,
|
||||
set: addToCookies,
|
||||
add: addToCookies, //DEPRECATED
|
||||
get: getFromCookies,
|
||||
remove: removeFromCookies,
|
||||
clearAll: clearAllFromCookies
|
||||
}
|
||||
};
|
||||
}];
|
||||
});
|
||||
})(window, window.angular);
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#edit-address-dialog
|
||||
%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')
|
||||
(
|
||||
%span.required *
|
||||
)
|
||||
.error{ ng: { repeat: "error in errors", bind: "error" } }
|
||||
|
||||
%table.no-borders
|
||||
%tr
|
||||
%td{style: 'width: 30%'}
|
||||
= t('spree.firstname')
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'firstname', required: true, ng: { model: 'address.firstname'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.lastname')
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'lastname', required: true, ng: { model: 'address.lastname'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.street_address')
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'address1', required: true, ng: { model: 'address.address1'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.street_address_1')
|
||||
%td
|
||||
%input{ type: 'text', name: 'address2', ng: { model: 'address.address2'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.city')
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'city', required: true, ng: { model: 'address.city'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.zipcode')
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'zipcode', required: true, ng: { model: 'address.zipcode'} }
|
||||
%tr
|
||||
%td
|
||||
= t('spree.country')
|
||||
%span.required *
|
||||
%td
|
||||
%select{ name: 'country', required: true, ng: { model: 'address.country_id' } }
|
||||
%option{value: ''}
|
||||
= t('admin.customers.index.select_country')
|
||||
%option{ ng: { repeat: 'country in availableCountries' }, value: '{{country.id}}' }
|
||||
{{country.name}}
|
||||
%tr
|
||||
%td
|
||||
= t('spree.state')
|
||||
%span.required *
|
||||
%td
|
||||
%select{ name: 'state', required: true, ng: { model: 'address.state_id' } }
|
||||
%option{value: ''}
|
||||
= t('admin.customers.index.select_state')
|
||||
%option{ ng: { repeat: 'state in states' }, value: '{{state.id}}' }
|
||||
{{state.name}}
|
||||
%tr
|
||||
%td
|
||||
= t('spree.phone')
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'phone', required: true, ng: { model: 'address.phone'} }
|
||||
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'submit', value: t('admin.customers.index.update_address')}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.ofn-drop-down
|
||||
%span
|
||||
%i.icon-check
|
||||
Actions
|
||||
= t('admin.actions')
|
||||
%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,18 +1,19 @@
|
||||
#tag-rule-help
|
||||
.margin-bottom-30.text-center
|
||||
.text-big Tag Rules
|
||||
.text-big
|
||||
= t('js.admin.modals.tag_rule_help.title')
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal Overview
|
||||
%p Tag rules provide a way to describe which items are visible or otherwise to which customers. Items can be Shipping Methods, Payment Methods, Products and Order Cycles.
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.overview')
|
||||
%p= t('js.admin.modals.tag_rule_help.overview_text')
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal 'By Default...' Rules
|
||||
%p Default rules allow you to hide items so that they are not visible by default. This behaviour can then be overriden by non-default rules for customers with particular tags.
|
||||
.text-normal= t('js.admin.modals.tag_rule_help.by_default_rules')
|
||||
%p= t('js.admin.modals.tag_rule_help.by_default_rules_text')
|
||||
|
||||
.margin-bottom-30
|
||||
.text-normal 'Customers Tagged...' Rules
|
||||
%p By creating rules related to a specific customer tag, you can override the default behaviour (whether it be to show or to hide items) for customers with the specified tag.
|
||||
.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-center
|
||||
%input.button.red.icon-plus{ type: 'button', value: 'Got it', ng: { click: 'close()' } }
|
||||
%input.button.red.icon-plus{ type: 'button', value: t('js.admin.modals.got_it'), ng: { click: 'close()' } }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#new-tag-rule-dialog
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
Select a rule type:
|
||||
= t('js.admin.new_tag_rule_dialog.select_rule_type')
|
||||
|
||||
.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,130 +2,128 @@
|
||||
.alpha.eight.columns
|
||||
%div{ ng: { if: "!enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%h3 Hub Profile
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_profile')
|
||||
|
||||
%p
|
||||
%strong COST: ALWAYS FREE
|
||||
%strong= t('js.admin.panels.enterprise_package.hub_profile_cost')
|
||||
|
||||
%p People can find and contact you on the Open Food Network. Your enterprise will be visible on the map, and will be searchable in listings.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_profile_text1')
|
||||
|
||||
%p Having a profile, and making connections within your local food system through the Open Food Network will always be free.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_profile_text2')
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
%h3 Hub Shop
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_shop')
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p Your enterprise is the backbone of your local food system. You aggregate produce from other enterprises and can sell it through your shop on the Open Food Network.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text1')
|
||||
|
||||
%p Hubs can take many forms, whether they be a food co-op, a buying group, a veggie-box program, or a local grocery store.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text2')
|
||||
|
||||
%p If you also want to sell your own products, you will need to switch this enterprise to be a producer.
|
||||
%p= t('js.admin.panels.enterprise_package.hub_shop_text3')
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
%h3
|
||||
Please Choose a Package
|
||||
= t('js.admin.panels.enterprise_package.choose_package')
|
||||
%i.icon-arrow-right
|
||||
|
||||
%p
|
||||
%strong Your enterprise will not be fully activated until a package is selected from the options on the left.
|
||||
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
|
||||
|
||||
%p
|
||||
Click on an option to see more detailed information about each package, and hit the red SAVE button when you are done!
|
||||
|
||||
|
||||
= t('js.admin.panels.enterprise_package.choose_package_text2')
|
||||
|
||||
%div{ ng: { if: "enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%h3 Profile Only
|
||||
%h3= t('js.admin.panels.enterprise_package.profile_only')
|
||||
|
||||
%p
|
||||
%strong COST: ALWAYS FREE
|
||||
%strong= t('js.admin.panels.enterprise_package.profile_only_cost')
|
||||
|
||||
%p A profile makes you visible and contactable to others and is a way to share your story.
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text1')
|
||||
|
||||
%p If you prefer to focus on producing food, and want to leave the work of selling it to someone else, you won't require a shop on the Open Food Network.
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text2')
|
||||
|
||||
%p Add your products to Open Food Network, allowing hubs to stock your products in their stores.
|
||||
%p= t('js.admin.panels.enterprise_package.profile_only_text3')
|
||||
|
||||
.info{ ng: { switch: { when: "own" } } }
|
||||
%h3 Producer Shop
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_shop')
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p Sell your products directly to customers through your very own Open Food Network shopfront.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_shop_text1')
|
||||
|
||||
%p A Producer Shop is for your produce only, if you want to sell produce grown/produced off site, please select 'Producer Hub'.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_shop_text2')
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
%h3 Producer Hub
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_hub')
|
||||
|
||||
%p
|
||||
%strong
|
||||
%monthly-pricing-description{ joiner: "comma" }
|
||||
|
||||
%p Your enterprise is the backbone of your local food system. You can sell your own produce as well as produce aggregated from other enterprises through your shopfront on the Open Food Network.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text1')
|
||||
|
||||
%p Producer Hubs can take many forms, whether they be a CSA, a veggie-box program, or a food co-op with a rooftop garden.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text2')
|
||||
|
||||
%p The Open Food Network aims to support as many hub models as possible, so no matter your situation, we want to provide the tools you need to run your organisation or local food business.
|
||||
%p= t('js.admin.panels.enterprise_package.producer_hub_text3')
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
%h3
|
||||
Please Choose a Package
|
||||
= t('js.admin.panels.enterprise_package.choose_package')
|
||||
%i.icon-arrow-right
|
||||
|
||||
%p
|
||||
%strong Your producer enterprise will not be fully activated until a package is selected from the options on the left.
|
||||
%strong= t('js.admin.panels.enterprise_package.choose_package_text1')
|
||||
|
||||
%p
|
||||
Click on an option to see more detailed information about each package, and hit the red SAVE button when you are done!
|
||||
= t('js.admin.panels.enterprise_package.choose_package_text2')
|
||||
|
||||
.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 Profile Only
|
||||
%p Get a listing
|
||||
.bottom ALWAYS FREE
|
||||
%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')
|
||||
%a.button.selector.hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Hub Shop
|
||||
%p Sell produce from others
|
||||
%h3= t('js.admin.panels.enterprise_package.hub_shop')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_produce_others')
|
||||
.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 Profile Only
|
||||
%p Get a listing
|
||||
.bottom ALWAYS FREE
|
||||
%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')
|
||||
%a.button.selector.producer-shop{ ng: { click: "enterprise.owned && (enterprise.sells='own')", class: "{selected: enterprise.sells=='own', disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Producer Shop
|
||||
%p Sell your own produce
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_shop')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_own_produce')
|
||||
.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 Producer Hub
|
||||
%p Sell produce from self and others
|
||||
%h3= t('js.admin.panels.enterprise_package.producer_hub')
|
||||
%p= t('js.admin.panels.enterprise_package.sell_both')
|
||||
.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" } }
|
||||
SAVE
|
||||
= t('js.admin.panels.save')
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
SAVED
|
||||
= t('js.admin.panels.saved')
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
SAVING
|
||||
= t('js.admin.panels.saving')
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -1,39 +1,37 @@
|
||||
.row.enterprise_producer_panel{ ng: { controller: 'indexProducerPanelCtrl' } }
|
||||
|
||||
.alpha.eight.columns
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==true" } }
|
||||
%h3 Producer
|
||||
%p Producers make yummy things to eat &/or drink. You're a producer if you grow it, raise it, brew it, bake it, ferment it, milk it or mould it.
|
||||
|
||||
%p Producers can also perform other functions, such as aggregating food from other enterprises and selling it through a shop on the Open Food Network.
|
||||
%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')
|
||||
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==false" } }
|
||||
%h3 Non-Producer
|
||||
%p Non-producers do not produce any food themselves, meaning that they cannot create their own products for sale through the Open Food Network.
|
||||
%h3= t('js.admin.panels.enterprise_producer.non_producer')
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_text1')
|
||||
|
||||
%p Instead, non-producers specialise in linking producers to the end eater, whether it be by aggregating, grading, packing, selling or delivering food.
|
||||
%p= t('js.admin.panels.enterprise_producer.non_producer_text2')
|
||||
|
||||
.omega.eight.columns
|
||||
%a.button.selector.producer{ ng: { click: 'enterprise.owned && changeToProducer()', class: "{selected: enterprise.is_primary_producer==true, disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 PRODUCER
|
||||
%p Producers of food
|
||||
.bottom eg. GROWERS, BAKERS, BREWERS, MAKERS
|
||||
%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')
|
||||
|
||||
%a.button.selector.non-producer{ ng: { click: 'enterprise.owned && changeToNonProducer()', class: "{selected: enterprise.is_primary_producer==false, disabled: !enterprise.owned}" } }
|
||||
.top
|
||||
%h3 Non-Producer
|
||||
%p All other food enterprises
|
||||
.bottom eg. Grocery stores, Food co-ops, Buying groups
|
||||
%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')
|
||||
|
||||
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
|
||||
%span{ ng: {hide: "saved() || saving" } }
|
||||
SAVE
|
||||
= t('js.admin.panels.save')
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
SAVED
|
||||
= t('js.admin.panels.saved')
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
SAVING
|
||||
= t('js.admin.panels.saving')
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
.row.enterprise_status_panel{ ng: { controller: 'indexStatusPanelCtrl' } }
|
||||
.alpha.omega.sixteen.columns
|
||||
|
||||
%h4.status-ok.text-center{ ng: { show: "issues.length == 0 && warnings.length == 0" } }
|
||||
%i.icon-ok-sign
|
||||
{{ object.name }} is set up and ready to go!
|
||||
= t('js.admin.panels.enterprise_status.status_title', name: '{{ object.name }}')
|
||||
|
||||
%table{ ng: { show: "issues.length > 0 || warnings.length > 0" } }
|
||||
%thead
|
||||
%th.severity
|
||||
Severity
|
||||
= t('js.admin.panels.enterprise_status.severity')
|
||||
%th.description
|
||||
Description
|
||||
= t('js.admin.panels.enterprise_status.description')
|
||||
%th.resolve
|
||||
Resolve
|
||||
= t('js.admin.panels.enterprise_status.resolve')
|
||||
%tr{ ng: { repeat: "issue in issues"} }
|
||||
%td.severity
|
||||
%i.icon-warning-sign.issue
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
.exchange-product{'ng-repeat' => 'product in supplied_products | filter:productSuppliedToOrderCycle | visibleProducts:exchange:order_cycle.visible_variants_for_outgoing_exchanges | orderBy:"name"' }
|
||||
.exchange-product-details
|
||||
%label
|
||||
-# MASTER_VARIANTS: No longer required
|
||||
-# = check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}',
|
||||
-# 'ng-disabled' => 'product.variants.length > 0 || !order_cycle.editable_variants_for_outgoing_exchanges.hasOwnProperty(exchange.enterprise_id) || order_cycle.editable_variants_for_outgoing_exchanges[exchange.enterprise_id].indexOf(product.master_id) < 0'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
.name {{ product.name }}
|
||||
.supplier {{ product.supplier_name }}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#save-bar.animate-show{ ng: { show: 'dirty || persist || StatusMessage.active()' } }
|
||||
.container
|
||||
.eight.columns.alpha
|
||||
%h5#status-message{ ng: { style: 'StatusMessage.statusMessage.style' } }
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage == ''", style: 'StatusMessage.statusMessage.style' } }
|
||||
{{ StatusMessage.statusMessage.text || " " }}
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage !== ''" }, style: 'color: #da5354' }
|
||||
{{ StatusMessage.invalidMessage || " " }}
|
||||
.eight.columns.omega.text-right{ ng: { transclude: true } }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%div{ ng: { show: "data.length > limit" } }
|
||||
%input{ type: 'button', value: 'Show More', ng: { click: 'limit = limit + increment' } }
|
||||
%input{ type: 'button', value: t(:show_more), ng: { click: 'limit = limit + increment' } }
|
||||
or
|
||||
%input{ type: 'button', value: "Show All ({{ data.length - limit }} More)", ng: { click: 'limit = data.length' } }
|
||||
%input{ type: 'button', value: t(:show_all_with_more, num: '{{ data.length - limit }}'), ng: { click: 'limit = data.length' } }
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
{{$getDisplayText()}}
|
||||
%span.tag-with-rules{ ng: { if: "data.rules == 1" } }
|
||||
—
|
||||
= t 'admin.has_one_rule'
|
||||
= t('admin.has_one_rule')
|
||||
%span.tag-with-rules{ ng: { if: "data.rules > 1" } }
|
||||
—
|
||||
= t 'admin.has_n_rules', { num: '{{data.rules}}' }
|
||||
= t('admin.has_n_rules', { num: '{{data.rules}}' })
|
||||
%span{ ng: { if: "!data.rules" } }
|
||||
{{$getDisplayText()}}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
%a.close-reveal-modal{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
|
||||
%h3 Reduced stock available
|
||||
%h3= t('js.out_of_stock.reduced_stock_available')
|
||||
|
||||
%p While you've been shopping, the stock levels for one or more of the products in your cart have reduced. Here's what's changed:
|
||||
%p= t('js.out_of_stock.out_of_stock_text')
|
||||
|
||||
%p{'ng-repeat' => "v in variants"}
|
||||
%em {{ v.name_to_display }} - {{ v.unit_to_display }}
|
||||
%span{'ng-if' => "v.count_on_hand == 0"}
|
||||
is now out of stock.
|
||||
= t('js.out_of_stock.now_out_of_stock')
|
||||
%span{'ng-if' => "v.count_on_hand > 0"}
|
||||
now only has {{ v.count_on_hand }} remaining.
|
||||
= t('js.out_of_stock.only_n_remainging', num: '{{ v.count_on_hand }}')
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
%p.modal-header {{'contact' | t}}
|
||||
%p{"ng-if" => "::enterprise.phone", "ng-bind" => "::enterprise.phone"}
|
||||
|
||||
%p.word-wrap{"ng-if" => "::enterprise.email_address"}
|
||||
%p{"ng-if" => "::enterprise.email_address"}
|
||||
%a{"ng-href" => "{{::enterprise.email_address | stripUrl}}", target: "_blank", mailto: true}
|
||||
%span.email{"ng-bind" => "::enterprise.email_address | stripUrl"}
|
||||
|
||||
%p.word-wrap{"ng-if" => "enterprise.website"}
|
||||
%p{"ng-if" => "enterprise.website"}
|
||||
%a{"ng-href" => "http://{{::enterprise.website | stripUrl}}", target: "_blank", "ng-bind" => "::enterprise.website | stripUrl"}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
%span.filter-shopfront.property-selectors.pad-top
|
||||
%ul.inline-block
|
||||
%li{"ng-repeat" => "property in enterprise.properties"}
|
||||
%li{"ng-repeat" => "property in enterprise.supplied_properties"}
|
||||
%a.button.tiny{"ng-bind" => "property.presentation"}
|
||||
|
||||
.about-container.pad-top
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
.filter-shopfront.property-selectors.inline-block
|
||||
%filter-selector{ 'selector-set' => "productPropertySelectors", objects: "[product] | propertiesWithValuesOf" }
|
||||
|
||||
%div{"ng-if" => "product.description"}
|
||||
%div{"ng-if" => "product.description_html"}
|
||||
%hr
|
||||
%p.text-small{"ng-bind" => "::product.description"}
|
||||
%p.text-small{"ng-bind-html" => "::product.description_html"}
|
||||
%hr
|
||||
|
||||
.columns.small-12.large-6
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
%div#registration-modal{"ng-controller" => "RegistrationCtrl"}
|
||||
%div{ ng: { show: "currentStep() == 'introduction'" } }
|
||||
%ng-include{ src: "'registration/introduction.html'" }
|
||||
%div{ ng: { repeat: 'step in steps', show: "currentStep() == step" } }
|
||||
%ng-include{ src: "'registration/'+ step + '.html'" }
|
||||
%div{ ng: { show: "currentStep() == 'finished'" } }
|
||||
%ng-include{ src: "'registration/finished.html'" }
|
||||
|
||||
%a.close-reveal-modal{"ng-click" => "$close()"}
|
||||
%i.ofn-i_009-close
|
||||
@@ -1,57 +0,0 @@
|
||||
.container#registration-about
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
.row
|
||||
.small-12.columns
|
||||
%header
|
||||
%h2 {{'enterprise_about_headline' | t}}
|
||||
%h5
|
||||
{{'enterprise_about_message' | t}}
|
||||
%span{ ng: { class: "{brick: !enterprise.is_primary_producer, turquoise: enterprise.is_primary_producer}" } }
|
||||
{{ enterprise.name }}
|
||||
|
||||
%form{ name: 'about', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "update('images',about)" } }
|
||||
.row
|
||||
.small-12.columns
|
||||
.alert-box.info{ "ofn-inline-alert" => true, ng: { show: "visible" } }
|
||||
%h6{ "ng-bind" => "'enterprise_success' | t:{enterprise: enterprise.name}" }
|
||||
%span {{'enterprise_registration_exit_message' | t}}
|
||||
%a.close{ ng: { click: "close()" } } ×
|
||||
|
||||
.small-12.large-8.columns
|
||||
.row
|
||||
.small-12.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_description' } {{'enterprise_description' | t}}:
|
||||
%input.chunky{ id: 'enterprise_description', placeholder: "{{'enterprise_description_placeholder' | t}}", ng: { model: 'enterprise.description' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_long_desc' } {{'enterprise_long_desc' | t}}:
|
||||
%textarea.chunky{ id: 'enterprise_long_desc', rows: 6, placeholder: "{{'enterprise_long_desc_placeholder' | t}}", ng: { model: 'enterprise.long_description' } }
|
||||
%small{ "ng-bind" => "'enterprise_long_desc_length' | t:{num: enterprise.long_description.length}" }
|
||||
.small-12.large-4.columns
|
||||
.row
|
||||
.small-12.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_abn' } {{'enterprise_abn' | t}}:
|
||||
%input.chunky{ id: 'enterprise_abn', placeholder: "{{'enterprise_abn_placeholder' | t}}", ng: { model: 'enterprise.abn' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_acn' } {{'enterprise_acn' | t}}:
|
||||
%input.chunky{ id: 'enterprise_acn', placeholder: "{{'enterprise_acn_placeholder' | t}}", ng: { model: 'enterprise.acn' } }
|
||||
.row
|
||||
.small-12.columns
|
||||
.field
|
||||
%label{ for: 'enterprise_charges_sales_tax' }= t(:charges_sales_tax)
|
||||
%input{ id: 'enterprise_charges_sales_tax_true', type: 'radio', name: 'charges_sales_tax', value: 'true', required: true, ng: { model: 'enterprise.charges_sales_tax' } }
|
||||
%label{ for: 'enterprise_charges_sales_tax_true' } {{'say_yes' | t}}
|
||||
%input{ id: 'enterprise_charges_sales_tax_false', type: 'radio', name: 'charges_sales_tax', value: 'false', required: true, ng: { model: 'enterprise.charges_sales_tax' } }
|
||||
%label{ for: 'enterprise_charges_sales_tax_false' } {{'say_no' | t}}
|
||||
%span.error.small-12.columns{ ng: { show: "about.charges_sales_tax.$error.required && submitted" } }
|
||||
{{'enterprise_tax_required' | t}}
|
||||
|
||||
.row.buttons.pad-top
|
||||
.small-12.columns
|
||||
%input.button.primary.right{ type: "submit", value: "{{'continue' | t}}" }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user