Compare commits
1125 Commits
Author | SHA1 | Date | |
---|---|---|---|
12a3931b7b | |||
25a55dbb67 | |||
6758f60a81 | |||
5e9e53ec41 | |||
1285252a8c | |||
98f95f72ad | |||
09ca788371 | |||
b48cc5a959 | |||
812d138c4e | |||
07bc35d4cd | |||
90b95a2c25 | |||
78c50c41e3 | |||
7eee7def63 | |||
9ba6e9806f | |||
8c28dc3d8a | |||
9197e39fb4 | |||
37f59814e5 | |||
bf894fc26f | |||
0b2b42cf4d | |||
542015a4f6 | |||
f5a8323f5d | |||
55942cd88b | |||
f26a2cbd26 | |||
4402f826c3 | |||
b9745b555a | |||
f923a8063b | |||
f4367b9146 | |||
a3395e41c9 | |||
be61135daf | |||
21b4187a11 | |||
1c3c1e35e7 | |||
ded373557e | |||
280c4762bb | |||
bbd02260be | |||
1b1e9abd68 | |||
b0ab9e0408 | |||
d32abff78d | |||
7fbf84db1f | |||
8c5aebc7d6 | |||
42202f676a | |||
ba6198f956 | |||
120af4170b | |||
1faa53b978 | |||
e565a7a234 | |||
90b6b57a8d | |||
548253d68e | |||
e1c5f609ff | |||
226befdef6 | |||
a9d57654b4 | |||
ed00ae0516 | |||
48d738e8c4 | |||
132b4ed2e8 | |||
9a513cb27b | |||
5d692c0395 | |||
991ab67fff | |||
dd00640119 | |||
fa04173cfb | |||
a328d3b48a | |||
d5cff4f0d3 | |||
52bf24b6db | |||
50e134d696 | |||
ea5c73721b | |||
4799882b80 | |||
2e4c5ca39a | |||
13ed3aa3b9 | |||
6091751a4b | |||
c4d9e85dff | |||
1a85914c1b | |||
0ba48234de | |||
1c2a532949 | |||
9087be6ee8 | |||
5b2ede8b83 | |||
2fa5e5ead2 | |||
d5107be65e | |||
379dfb5f6e | |||
8360377992 | |||
4538cab6c8 | |||
1bf0988297 | |||
e1caf49ea5 | |||
0dfae97b32 | |||
ef2187c175 | |||
6157d17c5b | |||
8e879047c2 | |||
bff6aecd0d | |||
a121583c2d | |||
e11fd66fec | |||
b37e85eeb5 | |||
f88dabffe8 | |||
8c436180d9 | |||
b834a6af4d | |||
1bd8aed192 | |||
cfdf72867e | |||
5888620fc1 | |||
55ba605eb0 | |||
7a73ca7d1a | |||
1918894c5c | |||
0c5589a3e3 | |||
d6eaa4ac8a | |||
b0571b97f5 | |||
6d51ca8011 | |||
d3289dfb84 | |||
bfffdd7274 | |||
c5b8b2aef0 | |||
d7bcf1b817 | |||
f30ed153ce | |||
f436088a16 | |||
db8cb7499d | |||
49c4adc754 | |||
405e743171 | |||
3508ac36b4 | |||
f17c8228cd | |||
3dd5ac0536 | |||
4ebdff49e0 | |||
4a72995bf4 | |||
ef27ac0b84 | |||
2b4adef6c2 | |||
f650455a90 | |||
afbe25e215 | |||
d93249f077 | |||
6223ef77d9 | |||
a423123b66 | |||
1b3d3082b0 | |||
fa117cc7dd | |||
acd407c1f1 | |||
9baf4b068f | |||
18d852e147 | |||
b8dc306741 | |||
6ea056c042 | |||
bcf1b37c6a | |||
2986cdba85 | |||
53a8ae74e2 | |||
8bab01506c | |||
c664045444 | |||
6b8149210d | |||
f31d30b318 | |||
d9fbbdc02d | |||
8136ee2d9b | |||
f7cf6e2131 | |||
f2d1787bd5 | |||
fb51765d3f | |||
088ad5fb42 | |||
2f5b3c0c0a | |||
04ac4d896c | |||
f3b96af863 | |||
eb42b0b98d | |||
304667eb49 | |||
dad1082cd7 | |||
37cf0f3d29 | |||
d61c6dff58 | |||
3734ac578d | |||
b3f56c9d8e | |||
3603eeee77 | |||
59d30cc139 | |||
6ff3bbbb72 | |||
a561e10156 | |||
99f2cf6702 | |||
c6b72e729b | |||
c5bc0f36a4 | |||
efc5c34bf9 | |||
3929efbdd9 | |||
0e0c41882e | |||
79cc708fc6 | |||
8fa98879b8 | |||
331ba385e9 | |||
71ce46d78d | |||
c493de6569 | |||
ff2c2ace86 | |||
7fa789cfd1 | |||
ae6269eb63 | |||
a8f4779bfe | |||
6868142e35 | |||
133d123919 | |||
05c128d12d | |||
bdab0c12fa | |||
75b94690e2 | |||
80fddd6c58 | |||
c807ead5fd | |||
f004bb5368 | |||
1d756e95a7 | |||
1fb0da9fda | |||
a0017b91ee | |||
444ab17342 | |||
44f3058326 | |||
ec09fbcb78 | |||
ed352bb1d3 | |||
375bbd2759 | |||
9fb9d25132 | |||
30f79aa589 | |||
69f8daac95 | |||
03f3a6080c | |||
44f84c6cdb | |||
31008a6895 | |||
2490d8c919 | |||
5886dbfd25 | |||
e48d55f0b1 | |||
42339927cf | |||
b492bcecc0 | |||
6ab7debb7b | |||
b76ce6c26f | |||
6fbc7b1593 | |||
69c8670b01 | |||
da44a87415 | |||
9fb17d4a6b | |||
16dd286f9d | |||
5025f10f9f | |||
1278d9648c | |||
289811a595 | |||
916ae97f73 | |||
876e386966 | |||
9582e58dda | |||
213bca8050 | |||
dc97d3115e | |||
90eb443965 | |||
1b40f02715 | |||
c5a02c6136 | |||
492cd8c96b | |||
7f091d7188 | |||
1c081623b9 | |||
87332037c2 | |||
62023397f4 | |||
37ec6dc1a6 | |||
81c277ca93 | |||
f8fea75130 | |||
a4457649f7 | |||
1d6a09f010 | |||
faec553521 | |||
37fcf3a234 | |||
68a56aada8 | |||
f744305834 | |||
7a9402f5b5 | |||
de6d7e0cae | |||
a3c56b84ce | |||
3d4defd563 | |||
52da08abb2 | |||
b9637b52e9 | |||
0369a23fe8 | |||
f690e1a095 | |||
22e8e34213 | |||
12b46736c5 | |||
4950e47297 | |||
d7c5c8c3e7 | |||
46b0fcf37b | |||
b07c4d0e6e | |||
eb107799a7 | |||
4eec0a42f9 | |||
9a5a3a08c6 | |||
151683c632 | |||
fd2103d1aa | |||
7696b6ec5d | |||
d972b96255 | |||
35ccfb8bcf | |||
7ff036b1e9 | |||
983d56c29b | |||
a2528939ba | |||
c136d91dd2 | |||
bf00e82596 | |||
0e10f6c820 | |||
c056e95249 | |||
1be7fda1cf | |||
0b0c0f5759 | |||
59a4428965 | |||
3f5c36d2d4 | |||
3cc5812c1d | |||
3e616201ad | |||
5558ebad45 | |||
63bd093f35 | |||
ec6559b8be | |||
3421406dc7 | |||
a2917c08f6 | |||
5fa9b5a8dd | |||
41ad86ba1f | |||
067b3ff3e6 | |||
9b9cb1455a | |||
a5569a6a55 | |||
71c1026729 | |||
f102e847bf | |||
3158e2c460 | |||
a438f13bb0 | |||
5ed0a5819c | |||
6dd3c6acda | |||
ca2c1c2e6f | |||
1305a10ee0 | |||
5e36eb818b | |||
cfde82ff5f | |||
af98ade650 | |||
598432466e | |||
9469ce83f1 | |||
5624f4c7a0 | |||
82a001dc05 | |||
a9b424fb79 | |||
d31af9d71c | |||
ff7a24590f | |||
ea87a7acf8 | |||
9d36a17261 | |||
9c3cb5a509 | |||
4dd7f32f3a | |||
1c6fca7f83 | |||
c5b376bd21 | |||
5d2800bc25 | |||
6675d5a20d | |||
28c39d301c | |||
afa0d3af63 | |||
b05344b1d3 | |||
2e88d7cce0 | |||
cb558ce2ab | |||
ed30d8f639 | |||
9410d4f10a | |||
354d249e1d | |||
008fdb94c5 | |||
d0fb94b3f8 | |||
a451f00ed3 | |||
0e0c371b28 | |||
2e52f3bb92 | |||
a3a5016278 | |||
cb5d7cb9a0 | |||
a44d4ed0b5 | |||
7bd23288f6 | |||
08c663759c | |||
c46ee07674 | |||
18398a3bfb | |||
88d9315f8b | |||
8bc95db0c9 | |||
c05a20cff9 | |||
08cb994252 | |||
543ad81e28 | |||
641ba04685 | |||
8e4d07c658 | |||
420650f37f | |||
775f7faee4 | |||
13b91ad051 | |||
2d3ec13473 | |||
3094cfc076 | |||
6aadd1fdc4 | |||
13589a4660 | |||
5f124659d0 | |||
d3ebc9706c | |||
e83d01ff28 | |||
9600e4f220 | |||
3e746d1545 | |||
3cc43aa302 | |||
c610d87e85 | |||
362ee49ce4 | |||
515515ba9f | |||
ed7da1a8fe | |||
12c036dbef | |||
1dd4ade04d | |||
0706450f9a | |||
b837a153d1 | |||
6d22a85fd7 | |||
3d706414b7 | |||
ef0cbb3e9f | |||
f5552847a3 | |||
101ef0cff4 | |||
9e70ba5e6e | |||
8f1a7ed3de | |||
6aa976ba1f | |||
db85604f18 | |||
7605fc71ac | |||
2c98270084 | |||
a5300624c2 | |||
2714c7fa9a | |||
49b65729db | |||
e053b62a70 | |||
88113cf22e | |||
5bf352e9fc | |||
5a7d5ac3f0 | |||
05848ce7aa | |||
b58d996ac7 | |||
16fa4491a5 | |||
456deede14 | |||
4ef50ca551 | |||
5ff7d98b00 | |||
3018dff1ff | |||
9386fe8328 | |||
e4213437e9 | |||
386bdceed3 | |||
87eda71931 | |||
cef9f1dcf8 | |||
c78b2088eb | |||
150364de3a | |||
1cd9f3eb67 | |||
89253125af | |||
e7ee356f90 | |||
a88017400b | |||
f557881462 | |||
8dba4727c4 | |||
8ec094089f | |||
3c353e715b | |||
ab33a9c352 | |||
406b509ac4 | |||
bd814baf28 | |||
2db681d908 | |||
37e3af584e | |||
5fc863bd82 | |||
76649f9590 | |||
cb2faec8b2 | |||
e8604284fe | |||
d2ccdef6c7 | |||
38199dc96f | |||
630b219e96 | |||
64155bc121 | |||
7fb45a15ee | |||
ed5294477f | |||
d152b073a6 | |||
f8efb3934b | |||
5a21d3fdc8 | |||
710ede15ce | |||
150286ab6b | |||
9e758e8a33 | |||
059165e5d2 | |||
fe154d9251 | |||
a8ffbc2d0e | |||
9de3a245b0 | |||
5eef709af5 | |||
7b0c130d0a | |||
7f265675b0 | |||
ba15db9829 | |||
d15473a8e4 | |||
d9f93dc6e7 | |||
634c5b699d | |||
23e8ce38dd | |||
c62ae2ce80 | |||
d0813bb4e2 | |||
0ac701eb20 | |||
607395be6f | |||
55d48df8a4 | |||
e0282ae45b | |||
235fdea00f | |||
b8c6d54f48 | |||
67661e3aad | |||
c03facdc45 | |||
9ddc1ef555 | |||
9cfc2fd940 | |||
24e108bce7 | |||
48f0c03425 | |||
0bfbe6dc79 | |||
ad0a9838bc | |||
81ec293e54 | |||
b8b3d76a1d | |||
805e641d40 | |||
18326f9df1 | |||
46dda84012 | |||
9979261cb6 | |||
e8887e2aa5 | |||
4a91fae984 | |||
0fe975f614 | |||
c7fd7b8a32 | |||
b7e3c3ae81 | |||
b2c3206185 | |||
b7d8d482fe | |||
8a9d14319b | |||
c396254e64 | |||
e4dbeca664 | |||
168540d6d2 | |||
c62cd6c023 | |||
033e0581f1 | |||
9f978d3362 | |||
841340a42d | |||
9595e9629f | |||
56ba543f8d | |||
1cead6c6cd | |||
f5f7ce4c42 | |||
b13075b8f2 | |||
c4db9e3227 | |||
f47bfb5439 | |||
cc4639cb23 | |||
69094f57fd | |||
ffe7b80888 | |||
fc846b808e | |||
1cbf6b67b2 | |||
286c02bdd9 | |||
5f1d76225b | |||
c05ea1b968 | |||
2d45ab2e88 | |||
ca9b1e25a7 | |||
2927875e16 | |||
486a97fa30 | |||
c22d434dff | |||
306cdeb68f | |||
7ee83dad06 | |||
d414313749 | |||
66d329f630 | |||
f524ffcb28 | |||
264b7e180b | |||
88dc7f4199 | |||
9652f75028 | |||
36c32db2d1 | |||
fd12bd557e | |||
7bd8ed4639 | |||
ca0e511efd | |||
e5f3fabcda | |||
efc9bac760 | |||
ce6327c3d5 | |||
f32d6bb331 | |||
e807aad814 | |||
b87754ca30 | |||
22dfb372ec | |||
674bbd728e | |||
68c09b8678 | |||
c83ab0886f | |||
999a0b3ede | |||
6daecd6466 | |||
7af2775972 | |||
4bb1acf493 | |||
c8cd3d3eb5 | |||
2360c4d6e4 | |||
36e9168eef | |||
fb79d189d7 | |||
12330d6d34 | |||
5efbcfd9c1 | |||
75240fc2e1 | |||
b6fabcc739 | |||
269ddae93a | |||
90c3f0e4e4 | |||
dd8c54aae3 | |||
aa3a46b941 | |||
744455f0df | |||
9aa25446d1 | |||
6199caea29 | |||
d6a68dd4d0 | |||
ee6e261c42 | |||
cabfd8a946 | |||
cf712636ed | |||
873c3d15a0 | |||
bc1bd3bad1 | |||
9f971632c9 | |||
91bc0505ac | |||
90c94624cc | |||
cd412894c6 | |||
ecf15d53d9 | |||
a593347336 | |||
22566869cb | |||
c959e7ec96 | |||
86a2846215 | |||
3b97a26a8a | |||
dc6c973574 | |||
2a3a561464 | |||
e5f45fb7ad | |||
f22cadd319 | |||
5ea25ec697 | |||
c0a250fc0f | |||
e69aa792c4 | |||
3b4ac4d2d2 | |||
781973777e | |||
8698d2c6ba | |||
47c15eca83 | |||
64f4bed080 | |||
fe47ba8a38 | |||
eb02adc7ba | |||
f257b503e9 | |||
bfdabe3554 | |||
77dd71935a | |||
4b418f041b | |||
c8a0e006a0 | |||
359119d896 | |||
1a3c767601 | |||
6a97e82d42 | |||
3edfd32879 | |||
33bdde1156 | |||
710cab64c3 | |||
ed707b1738 | |||
398903e8b8 | |||
d590f5ea98 | |||
d6cbe5aac8 | |||
08e6430c7d | |||
945fe66bbb | |||
8e3eb2b795 | |||
52fbc0ee8a | |||
a355228b93 | |||
2cb0b3b071 | |||
bc1fb235d3 | |||
713dda913e | |||
d182638971 | |||
a5c620acf3 | |||
c176ad1d16 | |||
14c2b4d90f | |||
03eb4ad0fc | |||
ba9cd15651 | |||
329ec63dfd | |||
4925c7868e | |||
13d28d0aa7 | |||
c7d3c79fe3 | |||
1e9da724ea | |||
645d4e15ab | |||
cad5b242b2 | |||
99a81042c1 | |||
61987a204e | |||
a208104fc8 | |||
00ccc8adf4 | |||
df0ed9ce53 | |||
26d9b915a2 | |||
16cb91990b | |||
9642d3e672 | |||
aed60e6905 | |||
da7615ba4c | |||
3eb6a21980 | |||
b4e371302c | |||
e6724b1d4a | |||
2b6e87c3a7 | |||
b01ee80ec2 | |||
5d48ecac80 | |||
ebdb826011 | |||
9dc725e34d | |||
f47c331a5b | |||
b45c70f32b | |||
cf33d6f066 | |||
8292e9a744 | |||
3c46a5b434 | |||
4a4c4e093a | |||
4fa8a650b8 | |||
da755b7902 | |||
ceebb18bdf | |||
d10a29598d | |||
8c56c8da5e | |||
c4ddb38d18 | |||
15a21e5745 | |||
7df1a856ea | |||
69381205a2 | |||
9e0d8056b3 | |||
4b85c57436 | |||
377498be1d | |||
142421ad48 | |||
768115b794 | |||
8b9d76db8a | |||
f17c78fda2 | |||
3d45a8b7d4 | |||
3888241cbd | |||
603b6749de | |||
22918ecfd1 | |||
70ded73b51 | |||
da147047ec | |||
0e24174373 | |||
bc9b4eeb19 | |||
c6b13c5175 | |||
f754b1d1b2 | |||
bd5300d69a | |||
9996f3ef41 | |||
0f95d7bc8a | |||
14098643ae | |||
7c2d5a45c5 | |||
d25070829d | |||
9d5902e179 | |||
d194502b27 | |||
2cef99de2b | |||
05d3756a1c | |||
b3d9fc54fe | |||
20841eb5e8 | |||
9e23326d45 | |||
f81d639b19 | |||
ab3e272020 | |||
4c265d1339 | |||
da08de0e74 | |||
6074aa927b | |||
046127eeba | |||
0c8a8c6854 | |||
acfcfdd730 | |||
8f935df12a | |||
2784bb7282 | |||
08a8ca4969 | |||
5a03eb9a17 | |||
91bb215e4d | |||
0b3a388a78 | |||
66a93768e1 | |||
61df4899cd | |||
f8b1e153be | |||
f322433875 | |||
be155c38bc | |||
13ee338fb0 | |||
f8628c1f4e | |||
f7c70be5eb | |||
65df28d52e | |||
3e658033da | |||
31e082eb2b | |||
bf1ab3a593 | |||
8540c51679 | |||
d2a6b6bd4e | |||
06417c1e88 | |||
be238f4c67 | |||
343da0fdcc | |||
dbb3c96300 | |||
c8f7bea419 | |||
396ab50fa0 | |||
84e9ecef29 | |||
57472d1a2e | |||
cb4f055263 | |||
3f1bdd2c59 | |||
a6802a1925 | |||
a02b2d3aa0 | |||
607a151c23 | |||
c8748e5e6e | |||
6e45a8e788 | |||
395e95bc54 | |||
a8309b436d | |||
77fe385645 | |||
290f749220 | |||
8cb5b3729d | |||
ce4a3196ee | |||
40ea5a0b84 | |||
af95380a62 | |||
483eaffc0e | |||
7e86ee3266 | |||
65630e6726 | |||
23682011af | |||
00eaa768a6 | |||
bc92d9a61e | |||
a1d8dec047 | |||
ff030068b0 | |||
79e37018c9 | |||
7ae8248339 | |||
30720975ab | |||
b2359258d4 | |||
1bd7639cc2 | |||
2dab89135f | |||
c3368d69fd | |||
751d8e7852 | |||
8a4dec08e1 | |||
8b9f5ad5b1 | |||
fc597a53bb | |||
2f25dc6a20 | |||
fc38ee2f08 | |||
33bebc6629 | |||
14a8e02f99 | |||
0bf6c87ec7 | |||
422fba2835 | |||
f36dbb78e6 | |||
3213dd0d08 | |||
3f2199fd63 | |||
a4477a9bd6 | |||
52790d7bd6 | |||
0b9812210f | |||
756dbb4641 | |||
b38742ddc0 | |||
49e38549ec | |||
afcb0a0d7f | |||
d18f0e50b5 | |||
6868a07ead | |||
cca76d0d97 | |||
70fa77d333 | |||
412201d965 | |||
045a92c7d6 | |||
2ba2e3eca5 | |||
90c294f60e | |||
57b953dd14 | |||
0f81a8db60 | |||
2d6971f8df | |||
0abe8b5371 | |||
5bad682879 | |||
fa9d32c230 | |||
1b3ceca7b2 | |||
9be326b45d | |||
2d2e1298c4 | |||
5dc3a4386e | |||
b617dde266 | |||
962e91f9dc | |||
4047b41a7f | |||
59199140bf | |||
1079c0beae | |||
1694baab7d | |||
335ac9c778 | |||
65efd234f9 | |||
f726d943db | |||
2d1e950097 | |||
ca2f16970b | |||
4a123f8fe9 | |||
7b224328e1 | |||
699dfa19f0 | |||
06d56fe19d | |||
1b7ac62b5c | |||
ae358ce13e | |||
18f35b5e91 | |||
67ca305b7f | |||
cb0908fc70 | |||
42df59076d | |||
ff8be3bdc6 | |||
f7b6dcf409 | |||
940f3848dd | |||
e847ad2df2 | |||
2459a103fd | |||
0dd3f2178e | |||
de873eca71 | |||
ef461da77f | |||
caf6dcddfa | |||
9684c88651 | |||
256bca8ed9 | |||
8d56e8582f | |||
56959f2f49 | |||
bbc7de6898 | |||
0df246da15 | |||
757e18355d | |||
4b29b04bd1 | |||
6cb94bc413 | |||
f624c891ab | |||
b83abf0ac5 | |||
ef1b0036e5 | |||
5efa9f65c6 | |||
a8e3dd424e | |||
26628ba156 | |||
78cabde9e1 | |||
1ec0372c2d | |||
31e2d5e771 | |||
d2dbf86a9c | |||
1c39d39078 | |||
6d0795abba | |||
5f45c6cc74 | |||
d4d806e247 | |||
758a545eb6 | |||
578088d2e5 | |||
e17dba2b07 | |||
7e5cf533f0 | |||
f7c656aed5 | |||
2e42305710 | |||
b3e310652e | |||
6737158130 | |||
906558a772 | |||
d559483c7b | |||
bec3e02285 | |||
9d6d72dd8c | |||
3b76f838d1 | |||
909ad86e33 | |||
dd8f58e35e | |||
4b2061fcfa | |||
8e6ca502b3 | |||
ef85834db5 | |||
2bdcd0eb42 | |||
3b90be4122 | |||
375e70d84b | |||
42d586610e | |||
e4a5438512 | |||
11b22fa63a | |||
45b933d635 | |||
15cf087d40 | |||
ed09c3e5d4 | |||
285a556f21 | |||
dc1ef2af47 | |||
6f17f0d2d1 | |||
91076580ef | |||
d4abaa7150 | |||
d2bc0fd24a | |||
1f26079b5f | |||
87a1211a55 | |||
0ca0a7d029 | |||
cb3d49f200 | |||
c0da428c27 | |||
435cd9b777 | |||
bfde34eb8d | |||
a4c1b24c35 | |||
2cbd2d54f3 | |||
378f6d803a | |||
af4d29ebe6 | |||
599661e028 | |||
84294b7ee6 | |||
a3e6eb5bba | |||
67359980e9 | |||
f1b955d74a | |||
809be415c5 | |||
457a4d1bba | |||
1e16912763 | |||
e2c9971c99 | |||
c1d31ca400 | |||
a011c3aade | |||
e35e97cdbf | |||
49a59d35a1 | |||
9a46640c15 | |||
678a0b3835 | |||
0c008325c4 | |||
ad5441487b | |||
104620a40a | |||
c1a3ba67f5 | |||
c42bbf3dc4 | |||
7d34274fbf | |||
f930b3303b | |||
a25ea3ddf6 | |||
021349caee | |||
89f2958d23 | |||
8c8435766e | |||
40dd1bbb3b | |||
ba40437eb9 | |||
813db1ae33 | |||
9588397e4e | |||
ecf83ca419 | |||
9cc494f0fa | |||
dd4b7e4d1c | |||
738b2f6c17 | |||
33289342d3 | |||
a00f1efcfe | |||
b89897e6d4 | |||
c539837896 | |||
27edf5f71d | |||
32cc5644f9 | |||
8a664aa7f1 | |||
7e5e8a4282 | |||
70d5d609e2 | |||
19160c99e1 | |||
99b2a7457e | |||
945d7edc70 | |||
6a97badfed | |||
5ec8e4ed52 | |||
1569b5f80a | |||
e62ecc5036 | |||
b0150e184b | |||
8b96854f39 | |||
28d8600078 | |||
4f30158722 | |||
4486f9c5b0 | |||
8515dcf29b | |||
d16eb87782 | |||
3c77e5d25e | |||
aa1a2a0da9 | |||
7c9029b227 | |||
1823bf606a | |||
525b7fdd65 | |||
11031d2b56 | |||
4d45635d03 | |||
b81764402b | |||
947e1150d8 | |||
97f0e512af | |||
f15374de43 | |||
f082c065d1 | |||
72a9951125 | |||
a82d9a63d4 | |||
a7e9979781 | |||
cebd1ee7ae | |||
5faa467306 | |||
53eb9cd2ae | |||
7f6eed6d66 | |||
74f3fa65cd | |||
8723aa4e4e | |||
ccab8b4cf3 | |||
4c4a4ab31d | |||
45df02b0ec | |||
dd7067e590 | |||
1219b5ba49 | |||
01496ac813 | |||
3b3ccc18ce | |||
3dce951e66 | |||
db1dc172aa | |||
26c5cc1e43 | |||
f91bfbf473 | |||
3dae0ef13f | |||
3281ac390e | |||
d731a6b432 | |||
bb869e8ae8 | |||
7331e5cabd | |||
ba05ca35af | |||
91e7bf6336 | |||
ff58067d55 | |||
2ba6bb339e | |||
a47afdd313 | |||
608b559ee1 | |||
181ed45d0b | |||
29fac8d052 | |||
a3d7d53eea | |||
3f6caf5fa4 | |||
42c4139ba5 | |||
ad31b143d2 | |||
6ec15bec22 | |||
71d8fb0d93 | |||
2f293da7a3 | |||
17b56f0160 | |||
bb9fce7f82 | |||
ad4f1f8326 | |||
8ece62c9a6 | |||
a9b9e9c631 | |||
6e289b6a8f | |||
20ced8b099 | |||
f38b632707 | |||
8ce0595342 | |||
f11de2f1ad | |||
e28451d410 | |||
72882aaf2b | |||
fdf9dd0fa3 | |||
97dd0abea2 | |||
a099174226 | |||
a054acc6e6 | |||
74254d7e2a | |||
1795964c69 | |||
0118b2472a | |||
5fe03f0dee | |||
9aef6850c2 | |||
f688a69f8b | |||
b2682fa0b7 | |||
18b15c5440 | |||
c3416977bb | |||
88a00bc38c | |||
a1441dfde6 | |||
8e7336d352 | |||
e0e2933cdf | |||
c93ec629ea | |||
d613df6558 | |||
01c9096543 | |||
f120e839dd | |||
f0ab592c04 | |||
1a269d28b3 | |||
8d4a666bf0 | |||
4a96e483a6 | |||
263a66407f | |||
c4b728f4e1 | |||
9970ad7fb6 | |||
eb380499d9 | |||
4b528549f5 | |||
a903017bc2 | |||
afd25e9174 | |||
b1bbf1b3bc | |||
9e84e8df93 | |||
df775b5a07 | |||
c9c22b9b52 | |||
93d20688ea | |||
9ebcddfa2a | |||
85995bc8a6 | |||
a8f2959bc6 | |||
36242bd580 | |||
1e7dbc8449 | |||
12c159c627 | |||
82ed7e51c5 | |||
0b3aa0d12a | |||
4d788f69aa | |||
c721843c12 | |||
d2be407ccb | |||
e6337216cf | |||
f1c396f0b0 | |||
3622bc9fcb | |||
14fe333678 | |||
cf6466197a | |||
f56bee76f2 | |||
2ec6bc8c99 | |||
4aeccb1961 | |||
bd593b1ad4 | |||
bb7812bd5d | |||
73ed070a34 | |||
9e81c48bf8 | |||
f9028d28c0 | |||
da32b243ea | |||
5092c3d328 | |||
06ad4488bf | |||
a856800e6d | |||
dfc680f3a1 | |||
a9baecc504 | |||
11e15659ac | |||
ebe440a272 | |||
853794d459 | |||
cfea13bf81 | |||
7f291d80b9 | |||
9840b55de6 | |||
ca7322933f | |||
81569e5b81 | |||
1942972282 | |||
a23aac370c | |||
99d6f74d1b | |||
a883e1176c | |||
24b98a1154 | |||
8dbb6ab79f | |||
3e7d1690bd | |||
07d533a810 | |||
499936e3ab | |||
580ac989aa | |||
acf300160d | |||
983df4ee13 | |||
03c782d4ab | |||
0daf7e12c1 | |||
6a2e18a0e1 | |||
316d5ab183 | |||
eb6bba5961 | |||
b5864adf06 | |||
9bce50a633 | |||
365a53cf27 | |||
31a4575d43 | |||
1ae584c4e7 | |||
aac2cd6eb8 | |||
9874e1c371 | |||
16b1c0dc41 | |||
9223fbf478 | |||
eb27de36f4 | |||
636fa38ab6 | |||
9b1503dc7a | |||
2ac3b00af6 | |||
5fcdbfe826 | |||
67036ddb61 | |||
6c0f6a07cd | |||
8139a7dd0a | |||
97adfc14c0 | |||
4ed703a351 | |||
2aee853406 | |||
854736fac7 | |||
841c69af59 | |||
56b4688f93 | |||
e60bc7c387 | |||
6094a83f4b | |||
91ddb98f56 | |||
27d5972306 | |||
6088497433 | |||
0d894a6fef | |||
57f0b88299 | |||
5121dbe0c8 | |||
f874ffc19c | |||
e928a5c2bc | |||
d11badf3ce | |||
3006c982cb | |||
b29e31fdd6 | |||
bc42c8e280 | |||
409697ee64 | |||
cfb4265971 | |||
13d78aac05 | |||
6f176f4e6c | |||
9b584296a5 | |||
5ea87c5eed | |||
7522084ccb | |||
214aa60d0e | |||
7a049ce1b7 | |||
94d293deb7 | |||
bd2d38d757 | |||
abec524daa | |||
cac6beb4ac | |||
cac995e15b | |||
b26380fd10 | |||
6c6a4070be | |||
8b001d820b | |||
2ae3d8ebdf | |||
459ec21f9d | |||
9c7790d07e | |||
f9c5b99e46 | |||
95b0b39366 | |||
4b6fa0e760 | |||
67a3440ced | |||
0de372344a | |||
7a04eeb650 |
15
.circle_ci/apache/mailpoet.loc.conf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Listen 8080
|
||||||
|
|
||||||
|
<VirtualHost *:8080>
|
||||||
|
UseCanonicalName Off
|
||||||
|
ServerName mailpoet.loc
|
||||||
|
DocumentRoot /home/ubuntu/mailpoet/wordpress
|
||||||
|
DirectoryIndex index.php
|
||||||
|
LogLevel notice
|
||||||
|
|
||||||
|
<Directory /home/ubuntu/mailpoet/wordpress>
|
||||||
|
AllowOverride All
|
||||||
|
Allow from All
|
||||||
|
</Directory>
|
||||||
|
</VirtualHost>
|
||||||
|
|
3
.gitignore
vendored
@ -12,8 +12,9 @@ npm-debug.log
|
|||||||
/views/cache/**
|
/views/cache/**
|
||||||
temp
|
temp
|
||||||
.idea
|
.idea
|
||||||
wysija-newsletters.zip
|
mailpoet.zip
|
||||||
tests/javascript/testBundles
|
tests/javascript/testBundles
|
||||||
assets/css/*.css
|
assets/css/*.css
|
||||||
assets/js/*.js
|
assets/js/*.js
|
||||||
.vagrant
|
.vagrant
|
||||||
|
lang
|
70
RoboFile.php
@ -89,43 +89,64 @@ class RoboFile extends \Robo\Tasks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makepot() {
|
function makepot() {
|
||||||
$this->_exec('grunt makepot'.
|
$this->_exec('./node_modules/.bin/grunt makepot'.
|
||||||
' --gruntfile '.__DIR__.'/tasks/makepot/makepot.js'.
|
' --gruntfile '.__DIR__.'/tasks/makepot/makepot.js'.
|
||||||
' --base_path '.__DIR__
|
' --base_path '.__DIR__
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushpot() {
|
function pushpot() {
|
||||||
$this->_exec('grunt pushpot'.
|
$this->_exec('./node_modules/.bin/grunt pushpot'.
|
||||||
' --gruntfile '.__DIR__.'/tasks/makepot/makepot.js'.
|
' --gruntfile '.__DIR__.'/tasks/makepot/makepot.js'.
|
||||||
' --base_path '.__DIR__
|
' --base_path '.__DIR__
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testUnit($file = null) {
|
function testUnit($opts=['file' => null, 'xml' => false]) {
|
||||||
$this->loadEnv();
|
$this->loadEnv();
|
||||||
$this->_exec('vendor/bin/codecept build');
|
$this->_exec('vendor/bin/codecept build');
|
||||||
$this->_exec('vendor/bin/codecept run unit -f '.(($file) ? $file : ''));
|
|
||||||
|
$command = 'vendor/bin/codecept run unit -f '.(($opts['file']) ? $opts['file'] : '');
|
||||||
|
|
||||||
|
if($opts['xml']) {
|
||||||
|
$command .= ' --xml';
|
||||||
|
}
|
||||||
|
return $this->_exec($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCoverage() {
|
function testCoverage($opts=['file' => null, 'xml' => false]) {
|
||||||
$this->loadEnv();
|
$this->loadEnv();
|
||||||
$this->_exec('vendor/bin/codecept build');
|
$this->_exec('vendor/bin/codecept build');
|
||||||
$this->_exec(join(' ', array(
|
$command = join(' ', array(
|
||||||
'vendor/bin/codecept run',
|
'vendor/bin/codecept run',
|
||||||
|
(($opts['file']) ? $opts['file'] : ''),
|
||||||
'--coverage',
|
'--coverage',
|
||||||
'--coverage-html'
|
($opts['xml']) ? '--coverage-xml' : '--coverage-html'
|
||||||
)));
|
));
|
||||||
|
|
||||||
|
if($opts['xml']) {
|
||||||
|
$command .= ' --xml';
|
||||||
|
}
|
||||||
|
return $this->_exec($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testJavascript() {
|
function testJavascript($xml_output_file = null) {
|
||||||
$this->compileJs();
|
$this->compileJs();
|
||||||
|
|
||||||
$this->_exec(join(' ', array(
|
$command = join(' ', array(
|
||||||
'./node_modules/mocha/bin/mocha',
|
'./node_modules/.bin/mocha',
|
||||||
'-r tests/javascript/mochaTestHelper.js',
|
'-r tests/javascript/mochaTestHelper.js',
|
||||||
'tests/javascript/testBundles/**/*.js'
|
'tests/javascript/testBundles/**/*.js'
|
||||||
)));
|
));
|
||||||
|
|
||||||
|
if(!empty($xml_output_file)) {
|
||||||
|
$command .= sprintf(
|
||||||
|
' --reporter xunit --reporter-options output="%s"',
|
||||||
|
$xml_output_file
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_exec($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testDebug() {
|
function testDebug() {
|
||||||
@ -140,6 +161,31 @@ class RoboFile extends \Robo\Tasks {
|
|||||||
$this->_exec('vendor/bin/codecept run -g failed');
|
$this->_exec('vendor/bin/codecept run -g failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function qa() {
|
||||||
|
$this->qaLint();
|
||||||
|
$this->qaCodeSniffer('all');
|
||||||
|
}
|
||||||
|
|
||||||
|
function qaLint() {
|
||||||
|
$this->_exec('./tasks/php_lint.sh lib/ tests/ mailpoet.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
function qaCodeSniffer($severity='errors') {
|
||||||
|
if ($severity === 'all') {
|
||||||
|
$severityFlag = '-w';
|
||||||
|
} else {
|
||||||
|
$severityFlag = '-n';
|
||||||
|
}
|
||||||
|
$this->_exec(
|
||||||
|
'./vendor/bin/phpcs '.
|
||||||
|
'--standard=./tasks/code_sniffer/MailPoet '.
|
||||||
|
'--ignore=./lib/Util/Sudzy/*,./lib/Util/CSS.php,./lib/Util/XLSXWriter.php,'.
|
||||||
|
'./lib/Config/PopulatorData/Templates/* '.
|
||||||
|
'lib/ '.
|
||||||
|
$severityFlag
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadEnv() {
|
protected function loadEnv() {
|
||||||
$dotenv = new Dotenv\Dotenv(__DIR__);
|
$dotenv = new Dotenv\Dotenv(__DIR__);
|
||||||
$dotenv->load();
|
$dotenv->load();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
@import 'nib'
|
@import 'nib'
|
||||||
|
|
||||||
@require 'select2/dist/css/select2.css'
|
@require 'select2/dist/css/select2.css'
|
||||||
|
@require 'datepicker/datepicker'
|
||||||
|
|
||||||
@require 'common'
|
@require 'common'
|
||||||
@require 'modal'
|
@require 'modal'
|
||||||
@ -8,6 +9,8 @@
|
|||||||
|
|
||||||
@require 'form_editor'
|
@require 'form_editor'
|
||||||
@require 'listing'
|
@require 'listing'
|
||||||
|
@require 'listing/newsletters'
|
||||||
|
|
||||||
@require 'box'
|
@require 'box'
|
||||||
@require 'breadcrumb'
|
@require 'breadcrumb'
|
||||||
|
|
||||||
@ -17,3 +20,5 @@
|
|||||||
|
|
||||||
@require 'settings'
|
@require 'settings'
|
||||||
@require 'progress_bar'
|
@require 'progress_bar'
|
||||||
|
|
||||||
|
@require 'subscribers'
|
||||||
|
@ -27,13 +27,12 @@
|
|||||||
|
|
||||||
img
|
img
|
||||||
min-width: 150px
|
min-width: 150px
|
||||||
min-height: 150px
|
|
||||||
height: auto
|
height: auto
|
||||||
width: 110%
|
width: 110%
|
||||||
position: relative
|
position: relative
|
||||||
top: 0
|
top: 50%
|
||||||
left: 50%
|
left: 50%
|
||||||
transform: translate(-50%, 0%)
|
transform: translate(-50%, -50%)
|
||||||
|
|
||||||
.mailpoet_overlay
|
.mailpoet_overlay
|
||||||
position: absolute
|
position: absolute
|
||||||
@ -61,16 +60,20 @@
|
|||||||
.mailpoet_boxes .mailpoet_description
|
.mailpoet_boxes .mailpoet_description
|
||||||
float:left
|
float:left
|
||||||
width: 245px
|
width: 245px
|
||||||
max-height: calc(110px - 2em)
|
max-height: calc(115px - 2em)
|
||||||
padding-bottom: 2em
|
padding-bottom: 2em
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|
||||||
.mailpoet_boxes .mailpoet_description h3
|
h3
|
||||||
margin: 0 0 1em 0
|
margin: 0 0 0.7em 0
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
white-space: nowrap
|
max-width: 210px
|
||||||
text-overflow: ellipsis
|
line-height: 1.4em
|
||||||
max-width: 220px
|
|
||||||
|
p
|
||||||
|
font-size: 13px
|
||||||
|
line-height: 1.5
|
||||||
|
margin: 1em 0
|
||||||
|
|
||||||
.mailpoet_boxes .mailpoet_actions
|
.mailpoet_boxes .mailpoet_actions
|
||||||
position: absolute
|
position: absolute
|
||||||
|
2
assets/css/src/datepicker/datepicker.styl
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@require 'jquery-ui-1.10.1.css'
|
||||||
|
@require 'melon.datepicker.css'
|
649
assets/css/src/datepicker/jquery-ui-1.10.1.css
vendored
Normal file
@ -0,0 +1,649 @@
|
|||||||
|
/*! jQuery UI - v1.10.1 - 2013-03-10
|
||||||
|
* http://jqueryui.com
|
||||||
|
* Includes: jquery.ui.core.css, jquery.ui.datepicker.css
|
||||||
|
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
|
||||||
|
* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
|
||||||
|
|
||||||
|
/* Layout helpers
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-helper-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.ui-helper-hidden-accessible {
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
.ui-helper-reset {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
outline: 0;
|
||||||
|
line-height: 1.3;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 100%;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.ui-helper-clearfix:before,
|
||||||
|
.ui-helper-clearfix:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
.ui-helper-clearfix:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.ui-helper-clearfix {
|
||||||
|
min-height: 0; /* support: IE7 */
|
||||||
|
}
|
||||||
|
.ui-helper-zfix {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
filter:Alpha(Opacity=0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-front {
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Interaction Cues
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-state-disabled {
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Icons
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* states and images */
|
||||||
|
.ui-icon {
|
||||||
|
display: block;
|
||||||
|
text-indent: -99999px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Misc visuals
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* Overlays */
|
||||||
|
.ui-widget-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.ui-datepicker {
|
||||||
|
width: 17em;
|
||||||
|
padding: .2em .2em 0;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-header {
|
||||||
|
position: relative;
|
||||||
|
padding: .2em 0;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-prev,
|
||||||
|
.ui-datepicker .ui-datepicker-next {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
width: 1.8em;
|
||||||
|
height: 1.8em;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-prev-hover,
|
||||||
|
.ui-datepicker .ui-datepicker-next-hover {
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-prev {
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-next {
|
||||||
|
right: 2px;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-prev-hover {
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-next-hover {
|
||||||
|
right: 1px;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-prev span,
|
||||||
|
.ui-datepicker .ui-datepicker-next span {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -8px;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -8px;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-title {
|
||||||
|
margin: 0 2.3em;
|
||||||
|
line-height: 1.8em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-title select {
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 1px 0;
|
||||||
|
}
|
||||||
|
.ui-datepicker select.ui-datepicker-month-year {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.ui-datepicker select.ui-datepicker-month,
|
||||||
|
.ui-datepicker select.ui-datepicker-year {
|
||||||
|
width: 49%;
|
||||||
|
}
|
||||||
|
.ui-datepicker table {
|
||||||
|
width: 100%;
|
||||||
|
font-size: .9em;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 0 0 .4em;
|
||||||
|
}
|
||||||
|
.ui-datepicker th {
|
||||||
|
padding: .7em .3em;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.ui-datepicker td {
|
||||||
|
border: 0;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
.ui-datepicker td span,
|
||||||
|
.ui-datepicker td a {
|
||||||
|
display: block;
|
||||||
|
padding: .2em;
|
||||||
|
text-align: right;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-buttonpane {
|
||||||
|
background-image: none;
|
||||||
|
margin: .7em 0 0 0;
|
||||||
|
padding: 0 .2em;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-buttonpane button {
|
||||||
|
float: right;
|
||||||
|
margin: .5em .2em .4em;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: .2em .6em .3em .6em;
|
||||||
|
width: auto;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* with multiple calendars */
|
||||||
|
.ui-datepicker.ui-datepicker-multi {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group table {
|
||||||
|
width: 95%;
|
||||||
|
margin: 0 auto .4em;
|
||||||
|
}
|
||||||
|
.ui-datepicker-multi-2 .ui-datepicker-group {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.ui-datepicker-multi-3 .ui-datepicker-group {
|
||||||
|
width: 33.3%;
|
||||||
|
}
|
||||||
|
.ui-datepicker-multi-4 .ui-datepicker-group {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
|
||||||
|
border-left-width: 0;
|
||||||
|
}
|
||||||
|
.ui-datepicker-multi .ui-datepicker-buttonpane {
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
.ui-datepicker-row-break {
|
||||||
|
clear: both;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RTL support */
|
||||||
|
.ui-datepicker-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-prev {
|
||||||
|
right: 2px;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-next {
|
||||||
|
left: 2px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-prev:hover {
|
||||||
|
right: 1px;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-next:hover {
|
||||||
|
left: 1px;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-buttonpane {
|
||||||
|
clear: right;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-group {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
|
||||||
|
border-right-width: 0;
|
||||||
|
border-left-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Component containers
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-widget {
|
||||||
|
font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
.ui-widget .ui-widget {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
.ui-widget input,
|
||||||
|
.ui-widget select,
|
||||||
|
.ui-widget textarea,
|
||||||
|
.ui-widget button {
|
||||||
|
font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
.ui-widget-content {
|
||||||
|
border: 1px solid #dddddd;
|
||||||
|
background: #eeeeee url(../img/datepicker/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.ui-widget-content a {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.ui-widget-header {
|
||||||
|
border: 1px solid #e78f08;
|
||||||
|
background: #f6a828 url(../img/datepicker/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;
|
||||||
|
color: #ffffff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.ui-widget-header a {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interaction states
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-state-default,
|
||||||
|
.ui-widget-content .ui-state-default,
|
||||||
|
.ui-widget-header .ui-state-default {
|
||||||
|
border: 1px solid #cccccc;
|
||||||
|
background: #f6f6f6 url(../img/datepicker/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1c94c4;
|
||||||
|
}
|
||||||
|
.ui-state-default a,
|
||||||
|
.ui-state-default a:link,
|
||||||
|
.ui-state-default a:visited {
|
||||||
|
color: #1c94c4;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.ui-state-hover,
|
||||||
|
.ui-widget-content .ui-state-hover,
|
||||||
|
.ui-widget-header .ui-state-hover,
|
||||||
|
.ui-state-focus,
|
||||||
|
.ui-widget-content .ui-state-focus,
|
||||||
|
.ui-widget-header .ui-state-focus {
|
||||||
|
border: 1px solid #fbcb09;
|
||||||
|
background: #fdf5ce url(../img/datepicker/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #c77405;
|
||||||
|
}
|
||||||
|
.ui-state-hover a,
|
||||||
|
.ui-state-hover a:hover,
|
||||||
|
.ui-state-hover a:link,
|
||||||
|
.ui-state-hover a:visited {
|
||||||
|
color: #c77405;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.ui-state-active,
|
||||||
|
.ui-widget-content .ui-state-active,
|
||||||
|
.ui-widget-header .ui-state-active {
|
||||||
|
border: 1px solid #fbd850;
|
||||||
|
background: #ffffff url(../img/datepicker/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #eb8f00;
|
||||||
|
}
|
||||||
|
.ui-state-active a,
|
||||||
|
.ui-state-active a:link,
|
||||||
|
.ui-state-active a:visited {
|
||||||
|
color: #eb8f00;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interaction Cues
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-state-highlight,
|
||||||
|
.ui-widget-content .ui-state-highlight,
|
||||||
|
.ui-widget-header .ui-state-highlight {
|
||||||
|
border: 1px solid #fed22f;
|
||||||
|
background: #ffe45c url(../img/datepicker/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;
|
||||||
|
color: #363636;
|
||||||
|
}
|
||||||
|
.ui-state-highlight a,
|
||||||
|
.ui-widget-content .ui-state-highlight a,
|
||||||
|
.ui-widget-header .ui-state-highlight a {
|
||||||
|
color: #363636;
|
||||||
|
}
|
||||||
|
.ui-state-error,
|
||||||
|
.ui-widget-content .ui-state-error,
|
||||||
|
.ui-widget-header .ui-state-error {
|
||||||
|
border: 1px solid #cd0a0a;
|
||||||
|
background: #b81900 url(../img/datepicker/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.ui-state-error a,
|
||||||
|
.ui-widget-content .ui-state-error a,
|
||||||
|
.ui-widget-header .ui-state-error a {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.ui-state-error-text,
|
||||||
|
.ui-widget-content .ui-state-error-text,
|
||||||
|
.ui-widget-header .ui-state-error-text {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.ui-priority-primary,
|
||||||
|
.ui-widget-content .ui-priority-primary,
|
||||||
|
.ui-widget-header .ui-priority-primary {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.ui-priority-secondary,
|
||||||
|
.ui-widget-content .ui-priority-secondary,
|
||||||
|
.ui-widget-header .ui-priority-secondary {
|
||||||
|
opacity: .7;
|
||||||
|
filter:Alpha(Opacity=70);
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.ui-state-disabled,
|
||||||
|
.ui-widget-content .ui-state-disabled,
|
||||||
|
.ui-widget-header .ui-state-disabled {
|
||||||
|
opacity: .35;
|
||||||
|
filter:Alpha(Opacity=35);
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
.ui-state-disabled .ui-icon {
|
||||||
|
filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icons
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* states and images */
|
||||||
|
.ui-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-position: 16px 16px;
|
||||||
|
}
|
||||||
|
.ui-icon,
|
||||||
|
.ui-widget-content .ui-icon {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_222222_256x240.png);
|
||||||
|
}
|
||||||
|
.ui-widget-header .ui-icon {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_ffffff_256x240.png);
|
||||||
|
}
|
||||||
|
.ui-state-default .ui-icon {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_ef8c08_256x240.png);
|
||||||
|
}
|
||||||
|
.ui-state-hover .ui-icon,
|
||||||
|
.ui-state-focus .ui-icon {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_ef8c08_256x240.png);
|
||||||
|
}
|
||||||
|
.ui-state-active .ui-icon {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_ef8c08_256x240.png);
|
||||||
|
}
|
||||||
|
.ui-state-highlight .ui-icon {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_228ef1_256x240.png);
|
||||||
|
}
|
||||||
|
.ui-state-error .ui-icon,
|
||||||
|
.ui-state-error-text .ui-icon {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_ffd27a_256x240.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* positioning */
|
||||||
|
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||||
|
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||||
|
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||||
|
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||||
|
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||||
|
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||||
|
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||||
|
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||||
|
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||||
|
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||||
|
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||||
|
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||||
|
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||||
|
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||||
|
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||||
|
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||||
|
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||||
|
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||||
|
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||||
|
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||||
|
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||||
|
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||||
|
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||||
|
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||||
|
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||||
|
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||||
|
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||||
|
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||||
|
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||||
|
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||||
|
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||||
|
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||||
|
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||||
|
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||||
|
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||||
|
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||||
|
.ui-icon-extlink { background-position: -32px -80px; }
|
||||||
|
.ui-icon-newwin { background-position: -48px -80px; }
|
||||||
|
.ui-icon-refresh { background-position: -64px -80px; }
|
||||||
|
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||||
|
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||||
|
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||||
|
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||||
|
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||||
|
.ui-icon-document { background-position: -32px -96px; }
|
||||||
|
.ui-icon-document-b { background-position: -48px -96px; }
|
||||||
|
.ui-icon-note { background-position: -64px -96px; }
|
||||||
|
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||||
|
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||||
|
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||||
|
.ui-icon-comment { background-position: -128px -96px; }
|
||||||
|
.ui-icon-person { background-position: -144px -96px; }
|
||||||
|
.ui-icon-print { background-position: -160px -96px; }
|
||||||
|
.ui-icon-trash { background-position: -176px -96px; }
|
||||||
|
.ui-icon-locked { background-position: -192px -96px; }
|
||||||
|
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||||
|
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||||
|
.ui-icon-tag { background-position: -240px -96px; }
|
||||||
|
.ui-icon-home { background-position: 0 -112px; }
|
||||||
|
.ui-icon-flag { background-position: -16px -112px; }
|
||||||
|
.ui-icon-calendar { background-position: -32px -112px; }
|
||||||
|
.ui-icon-cart { background-position: -48px -112px; }
|
||||||
|
.ui-icon-pencil { background-position: -64px -112px; }
|
||||||
|
.ui-icon-clock { background-position: -80px -112px; }
|
||||||
|
.ui-icon-disk { background-position: -96px -112px; }
|
||||||
|
.ui-icon-calculator { background-position: -112px -112px; }
|
||||||
|
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||||
|
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||||
|
.ui-icon-search { background-position: -160px -112px; }
|
||||||
|
.ui-icon-wrench { background-position: -176px -112px; }
|
||||||
|
.ui-icon-gear { background-position: -192px -112px; }
|
||||||
|
.ui-icon-heart { background-position: -208px -112px; }
|
||||||
|
.ui-icon-star { background-position: -224px -112px; }
|
||||||
|
.ui-icon-link { background-position: -240px -112px; }
|
||||||
|
.ui-icon-cancel { background-position: 0 -128px; }
|
||||||
|
.ui-icon-plus { background-position: -16px -128px; }
|
||||||
|
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||||
|
.ui-icon-minus { background-position: -48px -128px; }
|
||||||
|
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||||
|
.ui-icon-close { background-position: -80px -128px; }
|
||||||
|
.ui-icon-closethick { background-position: -96px -128px; }
|
||||||
|
.ui-icon-key { background-position: -112px -128px; }
|
||||||
|
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||||
|
.ui-icon-scissors { background-position: -144px -128px; }
|
||||||
|
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||||
|
.ui-icon-copy { background-position: -176px -128px; }
|
||||||
|
.ui-icon-contact { background-position: -192px -128px; }
|
||||||
|
.ui-icon-image { background-position: -208px -128px; }
|
||||||
|
.ui-icon-video { background-position: -224px -128px; }
|
||||||
|
.ui-icon-script { background-position: -240px -128px; }
|
||||||
|
.ui-icon-alert { background-position: 0 -144px; }
|
||||||
|
.ui-icon-info { background-position: -16px -144px; }
|
||||||
|
.ui-icon-notice { background-position: -32px -144px; }
|
||||||
|
.ui-icon-help { background-position: -48px -144px; }
|
||||||
|
.ui-icon-check { background-position: -64px -144px; }
|
||||||
|
.ui-icon-bullet { background-position: -80px -144px; }
|
||||||
|
.ui-icon-radio-on { background-position: -96px -144px; }
|
||||||
|
.ui-icon-radio-off { background-position: -112px -144px; }
|
||||||
|
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||||
|
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||||
|
.ui-icon-play { background-position: 0 -160px; }
|
||||||
|
.ui-icon-pause { background-position: -16px -160px; }
|
||||||
|
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||||
|
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||||
|
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||||
|
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||||
|
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||||
|
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||||
|
.ui-icon-stop { background-position: -96px -160px; }
|
||||||
|
.ui-icon-eject { background-position: -112px -160px; }
|
||||||
|
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||||
|
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||||
|
.ui-icon-power { background-position: 0 -176px; }
|
||||||
|
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||||
|
.ui-icon-signal { background-position: -32px -176px; }
|
||||||
|
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||||
|
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||||
|
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||||
|
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||||
|
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||||
|
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||||
|
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||||
|
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||||
|
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||||
|
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||||
|
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||||
|
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||||
|
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||||
|
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||||
|
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||||
|
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||||
|
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||||
|
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||||
|
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||||
|
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||||
|
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||||
|
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||||
|
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||||
|
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||||
|
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||||
|
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||||
|
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||||
|
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||||
|
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||||
|
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Misc visuals
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* Corner radius */
|
||||||
|
.ui-corner-all,
|
||||||
|
.ui-corner-top,
|
||||||
|
.ui-corner-left,
|
||||||
|
.ui-corner-tl {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
}
|
||||||
|
.ui-corner-all,
|
||||||
|
.ui-corner-top,
|
||||||
|
.ui-corner-right,
|
||||||
|
.ui-corner-tr {
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
}
|
||||||
|
.ui-corner-all,
|
||||||
|
.ui-corner-bottom,
|
||||||
|
.ui-corner-left,
|
||||||
|
.ui-corner-bl {
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
.ui-corner-all,
|
||||||
|
.ui-corner-bottom,
|
||||||
|
.ui-corner-right,
|
||||||
|
.ui-corner-br {
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overlays */
|
||||||
|
.ui-widget-overlay {
|
||||||
|
background: #666666 url(../img/datepicker/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;
|
||||||
|
opacity: .5;
|
||||||
|
filter: Alpha(Opacity=50);
|
||||||
|
}
|
||||||
|
.ui-widget-shadow {
|
||||||
|
margin: -5px 0 0 -5px;
|
||||||
|
padding: 5px;
|
||||||
|
background: #000000 url(../img/datepicker/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;
|
||||||
|
opacity: .2;
|
||||||
|
filter: Alpha(Opacity=20);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
115
assets/css/src/datepicker/melon.datepicker.css
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/**
|
||||||
|
* Melon skin from: https://github.com/rtsinani/jquery-datepicker-skins
|
||||||
|
*/
|
||||||
|
|
||||||
|
.wp-admin {
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-widget {
|
||||||
|
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
|
||||||
|
background: #2e3641;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
-moz-border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker-header {
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker-header .ui-state-hover {
|
||||||
|
background: transparent;
|
||||||
|
border-color: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
-moz-border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-title {
|
||||||
|
margin-top: .4em;
|
||||||
|
margin-bottom: .3em;
|
||||||
|
color: #e9f0f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-prev-hover,
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-next-hover,
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-next,
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-prev {
|
||||||
|
top: .9em;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-prev-hover {
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-next-hover {
|
||||||
|
right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-next span,
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-prev span {
|
||||||
|
background-image: url(../img/datepicker/ui-icons_ffffff_256x240.png);
|
||||||
|
background-position: -32px 0;
|
||||||
|
margin-top: 0;
|
||||||
|
top: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker .ui-datepicker-prev span {
|
||||||
|
background-position: -96px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker th {
|
||||||
|
padding: 1em 0;
|
||||||
|
color: #ccc;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: normal;
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid #3a414d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-datepicker td {
|
||||||
|
background: #f97e76;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin td .ui-state-default {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
padding: .5em;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #efefef;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-state-disabled {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin .ui-state-disabled .ui-state-default {
|
||||||
|
color: #fba49e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-admin td .ui-state-active,
|
||||||
|
.wp-admin td .ui-state-hover {
|
||||||
|
background: #2e3641;
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,5 @@
|
|||||||
|
.mailpoet_form
|
||||||
|
margin: 0 0 20px 0
|
||||||
|
|
||||||
.mailpoet_form td
|
.mailpoet_form td
|
||||||
vertical-align: top !important
|
vertical-align: top !important
|
@ -563,3 +563,6 @@ handle_icon = '../img/handle.png'
|
|||||||
.CodeMirror
|
.CodeMirror
|
||||||
border: 1px solid #eee
|
border: 1px solid #eee
|
||||||
|
|
||||||
|
/* Settings */
|
||||||
|
#mailpoet_form_segments.parsley-error + span .select2-selection
|
||||||
|
border: 1px solid #b94a48
|
3
assets/css/src/listing/newsletters.styl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#newsletters_container
|
||||||
|
h2.nav-tab-wrapper
|
||||||
|
margin-bottom: 1rem
|
@ -1,6 +1,6 @@
|
|||||||
$tool-inactive-color = #bbbbbb
|
$tool-inactive-color = #333333
|
||||||
$tool-inactive-secondary-color = #ffffff
|
$tool-inactive-secondary-color = #ffffff
|
||||||
$tool-hover-color = #333333
|
$tool-hover-color = #bbbbbb
|
||||||
$tool-hover-secondary-color = #ffffff
|
$tool-hover-secondary-color = #ffffff
|
||||||
$tool-active-color = #d2d2d4
|
$tool-active-color = #d2d2d4
|
||||||
$tool-active-secondary-color = #ffffff
|
$tool-active-secondary-color = #ffffff
|
||||||
@ -12,21 +12,42 @@ $master-column-tool-width = 24px
|
|||||||
position: absolute
|
position: absolute
|
||||||
top: 0
|
top: 0
|
||||||
right: 0
|
right: 0
|
||||||
display: none
|
|
||||||
z-index: 20
|
z-index: 20
|
||||||
padding: 2px
|
padding: 2px
|
||||||
text-align: right
|
text-align: right
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
position: relative
|
||||||
|
right: -100%
|
||||||
|
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000)
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
&.mailpoet_display_tools
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
right: 0
|
||||||
|
opacity: 1
|
||||||
|
|
||||||
a
|
a
|
||||||
vertical-align: top
|
vertical-align: top
|
||||||
|
|
||||||
.mailpoet_container_horizontal + &
|
.mailpoet_container_horizontal + &
|
||||||
left: 100%
|
left: 100%
|
||||||
|
right: initial
|
||||||
padding-left: 5px
|
padding-left: 5px
|
||||||
|
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
left: -100%
|
||||||
|
right: initial
|
||||||
|
|
||||||
|
&.mailpoet_display_tools
|
||||||
|
.mailpoet_tool_slider
|
||||||
|
left: 0
|
||||||
|
|
||||||
.mailpoet_tool
|
.mailpoet_tool
|
||||||
width: $master-column-tool-width
|
width: $master-column-tool-width
|
||||||
height: $master-column-tool-width
|
height: $master-column-tool-width
|
||||||
|
display: block
|
||||||
|
|
||||||
.mailpoet_tool_icon
|
.mailpoet_tool_icon
|
||||||
width: $master-column-tool-width
|
width: $master-column-tool-width
|
||||||
@ -46,6 +67,7 @@ $master-column-tool-width = 24px
|
|||||||
opacity: 0
|
opacity: 0
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
display: block
|
display: block
|
||||||
|
margin: 0
|
||||||
|
|
||||||
.mailpoet_delete_block_activated
|
.mailpoet_delete_block_activated
|
||||||
width: auto
|
width: auto
|
||||||
@ -125,7 +147,6 @@ $master-column-tool-width = 24px
|
|||||||
border-radius(3px)
|
border-radius(3px)
|
||||||
background-color: $warning-background-color
|
background-color: $warning-background-color
|
||||||
padding: 3px 5px
|
padding: 3px 5px
|
||||||
line-height: 1.2em
|
|
||||||
|
|
||||||
.mailpoet_delete_block_activate
|
.mailpoet_delete_block_activate
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
.mailpoet_form_field_title
|
.mailpoet_form_field_title
|
||||||
clear: both
|
clear: both
|
||||||
font-size: 1.1em
|
|
||||||
margin-bottom: 5px
|
margin-bottom: 5px
|
||||||
|
|
||||||
.mailpoet_form_field_title_small
|
.mailpoet_form_field_title_small
|
||||||
@ -37,3 +36,6 @@
|
|||||||
|
|
||||||
input[type=text]
|
input[type=text]
|
||||||
vertical-align: middle
|
vertical-align: middle
|
||||||
|
|
||||||
|
.mailpoet_form_field_block
|
||||||
|
display: block
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
.mailpoet_input_title,
|
.mailpoet_input_title,
|
||||||
.mailpoet_input_preheader
|
.mailpoet_input_preheader
|
||||||
width: 400px
|
width: 500px
|
||||||
padding: 3px
|
padding: 3px
|
||||||
line-height: normal
|
line-height: normal
|
||||||
|
|
||||||
|
@ -38,9 +38,7 @@
|
|||||||
content: '\f142'
|
content: '\f142'
|
||||||
|
|
||||||
.mailpoet_save_show_options_icon
|
.mailpoet_save_show_options_icon
|
||||||
width: auto
|
vertical-align: middle
|
||||||
height: auto
|
|
||||||
line-height: auto
|
|
||||||
|
|
||||||
&::before
|
&::before
|
||||||
content: '\f140'
|
content: '\f140'
|
||||||
|
@ -17,6 +17,7 @@ $widget-icon-width = 30px
|
|||||||
border-left: $content-border-color
|
border-left: $content-border-color
|
||||||
border-bottom: $content-border-color
|
border-bottom: $content-border-color
|
||||||
color: $sidebar-text-color
|
color: $sidebar-text-color
|
||||||
|
font-size: $sidebar-text-size
|
||||||
|
|
||||||
.mailpoet_sidebar_region
|
.mailpoet_sidebar_region
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
|
@ -3,6 +3,7 @@ $sidepanel-active-heading-color = $primary-active-color
|
|||||||
/* Sidepanel */
|
/* Sidepanel */
|
||||||
.mailpoet_editor_settings
|
.mailpoet_editor_settings
|
||||||
color: $sidebar-text-color
|
color: $sidebar-text-color
|
||||||
|
font-size: $sidebar-text-size
|
||||||
|
|
||||||
p
|
p
|
||||||
font-size: 1em
|
font-size: 1em
|
||||||
@ -18,7 +19,6 @@ $sidepanel-active-heading-color = $primary-active-color
|
|||||||
|
|
||||||
.mailpoet_sidepanel_field_title
|
.mailpoet_sidepanel_field_title
|
||||||
clear: both
|
clear: both
|
||||||
font-size: 1.1em
|
|
||||||
margin-bottom: 5px
|
margin-bottom: 5px
|
||||||
|
|
||||||
.mailpoet_sidepanel_field_title_small
|
.mailpoet_sidepanel_field_title_small
|
||||||
|
@ -21,3 +21,9 @@
|
|||||||
|
|
||||||
.mailpoet_automated_latest_content_display_options
|
.mailpoet_automated_latest_content_display_options
|
||||||
animation-slide-open-downwards()
|
animation-slide-open-downwards()
|
||||||
|
|
||||||
|
.mailpoet_automated_latest_content_show_amount
|
||||||
|
width: 25px
|
||||||
|
|
||||||
|
.mailpoet_automated_latest_content_content_type
|
||||||
|
width: 180px
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
$block-hover-highlight-color = $primary-active-color
|
$block-hover-highlight-color = $primary-active-color
|
||||||
|
$block-text-line-height = $text-line-height
|
||||||
|
|
||||||
.mailpoet_block
|
.mailpoet_block
|
||||||
box-sizing: border-box
|
box-sizing: border-box
|
||||||
@ -22,6 +23,7 @@ $block-hover-highlight-color = $primary-active-color
|
|||||||
border: 1px solid $transparent-color
|
border: 1px solid $transparent-color
|
||||||
|
|
||||||
&:hover > .mailpoet_block_highlight
|
&:hover > .mailpoet_block_highlight
|
||||||
|
&.mailpoet_highlight > .mailpoet_block_highlight
|
||||||
border: 1px dashed $block-hover-highlight-color
|
border: 1px dashed $block-hover-highlight-color
|
||||||
|
|
||||||
|
|
||||||
@ -30,3 +32,34 @@ $block-hover-highlight-color = $primary-active-color
|
|||||||
|
|
||||||
.mailpoet_content
|
.mailpoet_content
|
||||||
position: relative
|
position: relative
|
||||||
|
line-height: $block-text-line-height
|
||||||
|
|
||||||
|
p, h1, h2, h3, h4, h5, h6
|
||||||
|
line-height: $block-text-line-height
|
||||||
|
padding: 0
|
||||||
|
margin: 0
|
||||||
|
font-style: normal
|
||||||
|
font-weight: normal
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6
|
||||||
|
margin-bottom: 0.3em
|
||||||
|
|
||||||
|
p
|
||||||
|
margin-top: 0
|
||||||
|
margin-bottom: 0
|
||||||
|
font-weight: normal
|
||||||
|
|
||||||
|
ul
|
||||||
|
padding: 0
|
||||||
|
margin-top: 10px
|
||||||
|
margin-bottom: 10px
|
||||||
|
|
||||||
|
li
|
||||||
|
margin-top: 0
|
||||||
|
font-weight: normal
|
||||||
|
margin-bottom: 10px
|
||||||
|
|
||||||
|
blockquote
|
||||||
|
margin: 0 0 $block-text-line-height
|
||||||
|
padding-left: 10px
|
||||||
|
border-left: 2px #565656 solid
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
$button-vertical-padding = 13px
|
|
||||||
|
|
||||||
.mailpoet_button_block
|
.mailpoet_button_block
|
||||||
padding-top: $button-vertical-padding
|
|
||||||
padding-bottom: $button-vertical-padding
|
|
||||||
|
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|
||||||
.mailpoet_editor_button
|
.mailpoet_editor_button
|
||||||
|
@ -17,7 +17,7 @@ $three-column-width = ($newsletter-width / 3) - (2 * $column-margin)
|
|||||||
padding-left: 0
|
padding-left: 0
|
||||||
padding-right: 0
|
padding-right: 0
|
||||||
|
|
||||||
&:hover
|
&:hover > .mailpoet_block_highlight
|
||||||
border: 0
|
border: 0
|
||||||
|
|
||||||
.mailpoet_container_vertical > *
|
.mailpoet_container_vertical > *
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
.mailpoet_footer_block
|
.mailpoet_footer_block
|
||||||
padding-left: 0
|
padding-left: 0
|
||||||
padding-right: 0
|
padding-right: 0
|
||||||
|
margin-bottom: 0
|
||||||
|
|
||||||
.mailpoet_content
|
.mailpoet_content
|
||||||
padding: 5px 20px
|
padding: 10px 20px
|
||||||
|
|
||||||
|
& > *:last-child
|
||||||
|
margin-bottom: 0
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
.mailpoet_header_block
|
.mailpoet_header_block
|
||||||
padding-left: 0
|
padding-left: 0
|
||||||
padding-right: 0
|
padding-right: 0
|
||||||
|
margin-bottom: 0
|
||||||
|
|
||||||
.mailpoet_content
|
.mailpoet_content
|
||||||
padding: 5px 20px
|
padding: 10px 20px
|
||||||
|
|
||||||
|
& > *:last-child
|
||||||
|
margin-bottom: 0
|
||||||
|
@ -11,9 +11,6 @@
|
|||||||
padding-right: 0
|
padding-right: 0
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
|
|
||||||
img
|
|
||||||
width: 100%
|
|
||||||
|
|
||||||
.mailpoet_content a:hover
|
.mailpoet_content a:hover
|
||||||
cursor: all-scroll
|
cursor: all-scroll
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
$social-block-vertical-padding = 11px
|
$social-block-vertical-padding = 0px
|
||||||
|
|
||||||
$social-icon-width = 32px
|
$social-icon-width = 32px
|
||||||
$active-social-icon-set-border-color = #adadad
|
$active-social-icon-set-border-color = #adadad
|
||||||
$active-social-icon-set-background-color = #daebf2
|
$active-social-icon-set-background-color = #daebf2
|
||||||
$social-icon-set-hover-border-color = $primary-active-color
|
$social-icon-set-hover-border-color = $primary-active-color
|
||||||
|
|
||||||
$tool-inactive-color = #bbbbbb
|
$tool-inactive-color = #333333
|
||||||
$tool-hover-color = #333333
|
$tool-hover-color = #bbbbbb
|
||||||
$tool-active-color = #d2d2d4
|
$tool-active-color = #d2d2d4
|
||||||
|
|
||||||
$tool-width = 16px
|
$tool-width = 16px
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
$text-vertical-padding = 3px
|
|
||||||
|
|
||||||
.mailpoet_text_block
|
.mailpoet_text_block
|
||||||
padding-left: 0
|
padding-left: 0
|
||||||
padding-right: 0
|
padding-right: 0
|
||||||
|
|
||||||
& > .mailpoet_content
|
& > .mailpoet_content
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
padding-top: 13px
|
padding-top: 0
|
||||||
padding-bottom: 13px
|
padding-bottom: 0px
|
||||||
padding-left: 20px
|
padding-left: 20px
|
||||||
padding-right: 20px
|
padding-right: 20px
|
||||||
|
|
||||||
blockquote
|
& > *:last-child
|
||||||
margin: 1em
|
margin-bottom: 0
|
||||||
padding-left: 1em
|
|
||||||
border-left: 2px #565656 solid
|
|
||||||
|
@ -31,7 +31,7 @@ div.mce-toolbar-grp.mce-container
|
|||||||
box-shadow(0px 0px 3px 1px rgba(0, 0, 0, 0.05))
|
box-shadow(0px 0px 3px 1px rgba(0, 0, 0, 0.05))
|
||||||
|
|
||||||
.mce-window
|
.mce-window
|
||||||
/* Fix TinyMCE mailpoet_custom_fields window lack of hiding overflow */
|
/* Fix TinyMCE mailpoet_shortcodes window lack of hiding overflow */
|
||||||
div.mce-container-body.mce-abs-layout
|
div.mce-container-body.mce-abs-layout
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ div.mce-toolbar-grp.mce-container
|
|||||||
width: -webkit-calc( 100% - 36px )
|
width: -webkit-calc( 100% - 36px )
|
||||||
width: calc( 100% - 36px )
|
width: calc( 100% - 36px )
|
||||||
|
|
||||||
/* TinyMCE mailpoet_custom_fields toolbar icon */
|
/* TinyMCE mailpoet_shortcodes toolbar icon */
|
||||||
.mce-i-mailpoet_custom_fields:before
|
.mce-i-mailpoet_shortcodes:before
|
||||||
font: 400 20px/1 dashicons!important
|
font: 400 20px/1 dashicons!important
|
||||||
content: "\f307"
|
content: "\f307"
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ position: relative
|
|||||||
body
|
body
|
||||||
overflow-x: auto
|
overflow-x: auto
|
||||||
|
|
||||||
/* Hide the "Details" section of Wordpress Media manager */
|
/* Hide the "Details" section of WordPress Media manager */
|
||||||
.media-sidebar
|
.media-sidebar
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ body
|
|||||||
.attachments-browser .uploader-inline
|
.attachments-browser .uploader-inline
|
||||||
right: 0
|
right: 0
|
||||||
|
|
||||||
/* Remove max width from date selector in Wordpress Media Manager */
|
/* Remove max width from date selector in WordPress Media Manager */
|
||||||
#media-attachment-date-filters
|
#media-attachment-date-filters
|
||||||
max-width: calc(100% - 12px)
|
max-width: calc(100% - 12px)
|
||||||
|
|
||||||
@ -133,3 +133,17 @@ body
|
|||||||
.wrap > .mailpoet_notice,
|
.wrap > .mailpoet_notice,
|
||||||
.update-nag
|
.update-nag
|
||||||
margin-left: 2px + 15px !important
|
margin-left: 2px + 15px !important
|
||||||
|
|
||||||
|
/* Make a button group */
|
||||||
|
.mailpoet_button_group
|
||||||
|
|
||||||
|
.button:first-child
|
||||||
|
border-right: 0
|
||||||
|
border-top-right-radius: 0
|
||||||
|
border-bottom-right-radius: 0
|
||||||
|
|
||||||
|
.button:last-child
|
||||||
|
border-left: 0
|
||||||
|
border-top-left-radius: 0
|
||||||
|
border-bottom-left-radius: 0
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
animation-slide-open-downwards()
|
animation-slide-open-downwards($max-height = 2000px)
|
||||||
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||||
max-height: 2000px
|
max-height: $max-height
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
overflow-y: hidden
|
||||||
|
|
||||||
&.mailpoet_closed
|
&.mailpoet_closed
|
||||||
max-height: 0
|
max-height: 0px
|
||||||
opacity: 0
|
opacity: 0
|
||||||
overflow-y: hidden
|
|
||||||
|
|
||||||
animation-background-color()
|
animation-background-color()
|
||||||
transition: background 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
transition: background 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||||
|
@ -24,3 +24,6 @@ $error-text-color = #d54e21
|
|||||||
|
|
||||||
// Dimensions
|
// Dimensions
|
||||||
$newsletter-width = 660px
|
$newsletter-width = 660px
|
||||||
|
|
||||||
|
$text-line-height = 1.6em
|
||||||
|
$sidebar-text-size = 13px
|
||||||
|
@ -18,6 +18,7 @@ textarea.parsley-error
|
|||||||
list-style-type none
|
list-style-type none
|
||||||
font-size 0.9em
|
font-size 0.9em
|
||||||
line-height 0.9em
|
line-height 0.9em
|
||||||
|
color #B94A48
|
||||||
opacity 0
|
opacity 0
|
||||||
transition all .3s ease-in
|
transition all .3s ease-in
|
||||||
-o-transition all .3s ease-in
|
-o-transition all .3s ease-in
|
||||||
|
@ -2,3 +2,13 @@
|
|||||||
|
|
||||||
@require 'parsley'
|
@require 'parsley'
|
||||||
@require 'form_validation'
|
@require 'form_validation'
|
||||||
|
|
||||||
|
/* labels */
|
||||||
|
.mailpoet_text_label
|
||||||
|
.mailpoet_textarea_label
|
||||||
|
.mailpoet_select_label
|
||||||
|
.mailpoet_radio_label
|
||||||
|
.mailpoet_checkbox_label
|
||||||
|
.mailpoet_list_label
|
||||||
|
.mailpoet_date_label
|
||||||
|
display:block
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
#mailpoet_settings
|
#mailpoet_settings
|
||||||
// common
|
// common
|
||||||
.mailpoet_panel
|
.mailpoet_panel
|
||||||
display: none
|
display none
|
||||||
|
|
||||||
.form-table th
|
.form-table th
|
||||||
width:20em
|
width 20em
|
||||||
|
|
||||||
// advanced
|
|
||||||
#mailpoet_role_permissions
|
|
||||||
margin-top: 20px;
|
|
||||||
|
|
||||||
// sending methods
|
// sending methods
|
||||||
.mailpoet_sending_methods
|
.mailpoet_sending_methods
|
||||||
@ -28,8 +24,7 @@
|
|||||||
line-height 54px
|
line-height 54px
|
||||||
font-size 1.5em
|
font-size 1.5em
|
||||||
.mailpoet_description
|
.mailpoet_description
|
||||||
line-height 1.5em
|
font-size 14px
|
||||||
font-size 1.1em
|
|
||||||
.mailpoet_status
|
.mailpoet_status
|
||||||
background-color #2f2f2f
|
background-color #2f2f2f
|
||||||
color #fff
|
color #fff
|
||||||
@ -60,11 +55,11 @@
|
|||||||
// responsive
|
// responsive
|
||||||
@media screen and (max-width: 782px)
|
@media screen and (max-width: 782px)
|
||||||
.form-table th
|
.form-table th
|
||||||
width: auto
|
width auto
|
||||||
|
|
||||||
.mailpoet_sending_methods
|
.mailpoet_sending_methods
|
||||||
li
|
li
|
||||||
float none
|
float none
|
||||||
width: auto
|
width auto
|
||||||
margin-right: 0
|
margin-right 0
|
||||||
|
|
||||||
|
3
assets/css/src/subscribers.styl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#subscribers_container
|
||||||
|
.mailpoet_segments_unsubscribed
|
||||||
|
color: lighten(#555, 33)
|
BIN
assets/img/blank_templates/fake-logo.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
assets/img/datepicker/animated-overlay.gif
Executable file
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/img/datepicker/cal_logo.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/img/datepicker/ui-bg_diagonals-thick_18_b81900_40x40.png
Executable file
After Width: | Height: | Size: 418 B |
BIN
assets/img/datepicker/ui-bg_diagonals-thick_20_666666_40x40.png
Executable file
After Width: | Height: | Size: 312 B |
BIN
assets/img/datepicker/ui-bg_flat_10_000000_40x100.png
Executable file
After Width: | Height: | Size: 205 B |
BIN
assets/img/datepicker/ui-bg_glass_100_f6f6f6_1x400.png
Executable file
After Width: | Height: | Size: 262 B |
BIN
assets/img/datepicker/ui-bg_glass_100_fdf5ce_1x400.png
Executable file
After Width: | Height: | Size: 348 B |
BIN
assets/img/datepicker/ui-bg_glass_65_ffffff_1x400.png
Executable file
After Width: | Height: | Size: 207 B |
BIN
assets/img/datepicker/ui-bg_gloss-wave_35_f6a828_500x100.png
Executable file
After Width: | Height: | Size: 5.7 KiB |
BIN
assets/img/datepicker/ui-bg_highlight-soft_100_eeeeee_1x100.png
Executable file
After Width: | Height: | Size: 278 B |
BIN
assets/img/datepicker/ui-bg_highlight-soft_75_ffe45c_1x100.png
Executable file
After Width: | Height: | Size: 328 B |
BIN
assets/img/datepicker/ui-icons_222222_256x240.png
Executable file
After Width: | Height: | Size: 6.8 KiB |
BIN
assets/img/datepicker/ui-icons_228ef1_256x240.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/img/datepicker/ui-icons_454545_256x240.png
Executable file
After Width: | Height: | Size: 4.3 KiB |
BIN
assets/img/datepicker/ui-icons_ef8c08_256x240.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/img/datepicker/ui-icons_ffd27a_256x240.png
Executable file
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/img/datepicker/ui-icons_ffffff_256x240.png
Executable file
After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
BIN
assets/img/sample_templates/discount/bicycle-header2.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
assets/img/sample_templates/discount/bicycle-header3.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/img/sample_templates/discount/orange-bicycle.jpg
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
assets/img/sample_templates/discount/red-icycle.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
assets/img/sample_templates/restaurant/boyga-1329911-639x852.jpg
Normal file
After Width: | Height: | Size: 303 KiB |
BIN
assets/img/sample_templates/restaurant/burger.jpg
Normal file
After Width: | Height: | Size: 289 KiB |
BIN
assets/img/sample_templates/restaurant/header.jpg
Normal file
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 498 KiB |
BIN
assets/img/sample_templates/travel/gallery1.jpg
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
assets/img/sample_templates/travel/gallery2.jpg
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
assets/img/sample_templates/travel/gallery3.jpg
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
assets/img/sample_templates/travel/gallery4.jpg
Normal file
After Width: | Height: | Size: 156 KiB |
BIN
assets/img/sample_templates/travel/glow-worms.jpg
Normal file
After Width: | Height: | Size: 145 KiB |
BIN
assets/img/sample_templates/travel/header.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
assets/img/sample_templates/travel/holiday-park.jpg
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
assets/img/sample_templates/travel/luge.jpg
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
assets/img/welcome_template/beacon.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 4.8 KiB |
BIN
assets/img/welcome_template/mailpoet-logo.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
@ -1 +0,0 @@
|
|||||||
../src/newsletter_editor/tinymce/mailpoet_custom_fields
|
|
1
assets/js/lib/mailpoet_shortcodes
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../src/newsletter_editor/tinymce/mailpoet_shortcodes
|
@ -1,4 +1,4 @@
|
|||||||
define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
define('ajax', ['mailpoet', 'jquery', 'underscore'], function(MailPoet, jQuery, _) {
|
||||||
'use strict';
|
'use strict';
|
||||||
MailPoet.Ajax = {
|
MailPoet.Ajax = {
|
||||||
version: 0.5,
|
version: 0.5,
|
||||||
@ -8,19 +8,11 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
endpoint: null,
|
endpoint: null,
|
||||||
action: null,
|
action: null,
|
||||||
token: null,
|
token: null,
|
||||||
data: {},
|
data: {}
|
||||||
onSuccess: function(data, textStatus, xhr) {},
|
|
||||||
onError: function(xhr, textStatus, errorThrown) {}
|
|
||||||
},
|
|
||||||
get: function(options) {
|
|
||||||
return this.request('get', options);
|
|
||||||
},
|
},
|
||||||
post: function(options) {
|
post: function(options) {
|
||||||
return this.request('post', options);
|
return this.request('post', options);
|
||||||
},
|
},
|
||||||
delete: function(options) {
|
|
||||||
return this.request('delete', options);
|
|
||||||
},
|
|
||||||
init: function(options) {
|
init: function(options) {
|
||||||
// merge options
|
// merge options
|
||||||
this.options = jQuery.extend({}, this.defaults, options);
|
this.options = jQuery.extend({}, this.defaults, options);
|
||||||
@ -50,31 +42,31 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
|
|
||||||
// set request params
|
// set request params
|
||||||
var params = this.getParams();
|
var params = this.getParams();
|
||||||
var jqXHR;
|
var deferred = jQuery.Deferred();
|
||||||
|
|
||||||
// make ajax request depending on method
|
// remove null values from the data object
|
||||||
if(method === 'get') {
|
if (_.isObject(params.data)) {
|
||||||
jqXHR = jQuery.get(
|
params.data = _.pick(params.data, function(value) {
|
||||||
|
return (value !== null)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ajax request
|
||||||
|
deferred = jQuery.post(
|
||||||
this.options.url,
|
this.options.url,
|
||||||
params,
|
params,
|
||||||
this.options.onSuccess,
|
null,
|
||||||
'json'
|
'json'
|
||||||
);
|
).then(function(data) {
|
||||||
} else {
|
return data;
|
||||||
jqXHR = jQuery.ajax({
|
}, function(xhr) {
|
||||||
url: this.options.url,
|
return xhr.responseJSON;
|
||||||
type : 'post',
|
|
||||||
data: params,
|
|
||||||
dataType: 'json',
|
|
||||||
success : this.options.onSuccess,
|
|
||||||
error : this.options.onError
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// clear options
|
// clear options
|
||||||
this.options = {};
|
this.options = {};
|
||||||
|
|
||||||
return jqXHR;
|
return deferred;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
define(
|
|
||||||
[
|
|
||||||
'react',
|
|
||||||
'react-dom',
|
|
||||||
'mailpoet'
|
|
||||||
],
|
|
||||||
function(
|
|
||||||
React,
|
|
||||||
ReactDOM,
|
|
||||||
MailPoet
|
|
||||||
) {
|
|
||||||
var CronControl = React.createClass({
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
status: 'loading'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getCronData: function() {
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
endpoint: 'cron',
|
|
||||||
action: 'getStatus'
|
|
||||||
})
|
|
||||||
.done(function(response) {
|
|
||||||
jQuery('.button-primary')
|
|
||||||
.removeClass('disabled');
|
|
||||||
if(response.status !== undefined) {
|
|
||||||
this.setState(response);
|
|
||||||
} else {
|
|
||||||
this.replaceState();
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
componentDidMount: function() {
|
|
||||||
if(this.isMounted()) {
|
|
||||||
this.getCronData();
|
|
||||||
setInterval(this.getCronData, 5000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
controlCron: function(action) {
|
|
||||||
if(jQuery('.button-primary').hasClass('disabled')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
jQuery('.button-primary')
|
|
||||||
.addClass('disabled');
|
|
||||||
MailPoet.Ajax.post({
|
|
||||||
endpoint: 'cron',
|
|
||||||
action: action,
|
|
||||||
})
|
|
||||||
.done(function(response) {
|
|
||||||
if(!response.result) {
|
|
||||||
MailPoet.Notice.error(MailPoetI18n.daemonControlError);
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
render: function() {
|
|
||||||
if(this.state.status === 'loading') {
|
|
||||||
return(<div>Loading daemon status...</div>);
|
|
||||||
}
|
|
||||||
switch(this.state.status) {
|
|
||||||
case 'started':
|
|
||||||
return(
|
|
||||||
<div>
|
|
||||||
Cron daemon is running.
|
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
It was started
|
|
||||||
<strong> {this.state.timeSinceStart} </strong> and last executed
|
|
||||||
<strong> {this.state.timeSinceUpdate} </strong> for a total of
|
|
||||||
<strong> {this.state.counter} </strong> times (once every 30 seconds, unless it was interrupted and restarted).
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'stop')}>Stop</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'starting':
|
|
||||||
case 'stopping':
|
|
||||||
return(
|
|
||||||
<div>
|
|
||||||
Daemon is {this.state.status}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'stopped':
|
|
||||||
return(
|
|
||||||
<div>
|
|
||||||
Daemon is {this.state.status}
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<a href="#" className="button-primary" onClick={this.controlCron.bind(null, 'start')}>Start</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const container = document.getElementById('cron_container');
|
|
||||||
|
|
||||||
if(container) {
|
|
||||||
ReactDOM.render(
|
|
||||||
<CronControl />,
|
|
||||||
container
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
146
assets/js/src/date.js
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
define('date',
|
||||||
|
[
|
||||||
|
'mailpoet',
|
||||||
|
'jquery',
|
||||||
|
'moment'
|
||||||
|
], function(
|
||||||
|
MailPoet,
|
||||||
|
jQuery,
|
||||||
|
Moment
|
||||||
|
) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
MailPoet.Date = {
|
||||||
|
version: 0.1,
|
||||||
|
options: {},
|
||||||
|
defaults: {
|
||||||
|
offset: 0,
|
||||||
|
format: 'F, d Y H:i:s'
|
||||||
|
},
|
||||||
|
init: function(options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// set UTC offset
|
||||||
|
if (
|
||||||
|
options.offset === undefined
|
||||||
|
&& window.mailpoet_date_offset !== undefined
|
||||||
|
) {
|
||||||
|
options.offset = window.mailpoet_date_offset;
|
||||||
|
}
|
||||||
|
// set date format
|
||||||
|
if (
|
||||||
|
options.format === undefined
|
||||||
|
&& window.mailpoet_date_format !== undefined
|
||||||
|
) {
|
||||||
|
options.format = window.mailpoet_date_format;
|
||||||
|
}
|
||||||
|
// merge options
|
||||||
|
this.options = jQuery.extend({}, this.defaults, options);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
format: function(date, options) {
|
||||||
|
options = options || {};
|
||||||
|
this.init(options);
|
||||||
|
|
||||||
|
var date = Moment(date, this.convertFormat(options.parseFormat));
|
||||||
|
if (options.offset === 0) date = date.utc();
|
||||||
|
return date.format(this.convertFormat(this.options.format));
|
||||||
|
},
|
||||||
|
toDate: function(date, options) {
|
||||||
|
options = options || {};
|
||||||
|
this.init(options);
|
||||||
|
|
||||||
|
return Moment(date, this.convertFormat(options.parseFormat)).toDate();
|
||||||
|
},
|
||||||
|
short: function(date) {
|
||||||
|
return this.format(date, {
|
||||||
|
format: 'F, j Y'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
full: function(date) {
|
||||||
|
return this.format(date, {
|
||||||
|
format: 'F, j Y H:i:s'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
time: function(date) {
|
||||||
|
return this.format(date, {
|
||||||
|
format: 'H:i:s'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
convertFormat: function(format) {
|
||||||
|
var format_mappings = {
|
||||||
|
date: {
|
||||||
|
D: 'ddd',
|
||||||
|
l: 'dddd',
|
||||||
|
d: 'DD',
|
||||||
|
j: 'D',
|
||||||
|
z: 'DDDD',
|
||||||
|
N: 'E',
|
||||||
|
S: '',
|
||||||
|
M: 'MMM',
|
||||||
|
F: 'MMMM',
|
||||||
|
m: 'MM',
|
||||||
|
n: '',
|
||||||
|
t: '',
|
||||||
|
y: 'YY',
|
||||||
|
Y: 'YYYY',
|
||||||
|
H: 'HH',
|
||||||
|
h: 'hh',
|
||||||
|
g: 'h',
|
||||||
|
A: 'A',
|
||||||
|
i: 'mm',
|
||||||
|
s: 'ss',
|
||||||
|
T: 'z',
|
||||||
|
O: 'ZZ',
|
||||||
|
w: 'd',
|
||||||
|
W: 'WW'
|
||||||
|
},
|
||||||
|
strftime: {
|
||||||
|
a: 'ddd',
|
||||||
|
A: 'dddd',
|
||||||
|
b: 'MMM',
|
||||||
|
B: 'MMMM',
|
||||||
|
d: 'DD',
|
||||||
|
e: 'D',
|
||||||
|
F: 'YYYY-MM-DD',
|
||||||
|
H: 'HH',
|
||||||
|
I: 'hh',
|
||||||
|
j: 'DDDD',
|
||||||
|
k: 'H',
|
||||||
|
l: 'h',
|
||||||
|
m: 'MM',
|
||||||
|
M: 'mm',
|
||||||
|
p: 'A',
|
||||||
|
S: 'ss',
|
||||||
|
u: 'E',
|
||||||
|
w: 'd',
|
||||||
|
W: 'WW',
|
||||||
|
y: 'YY',
|
||||||
|
Y: 'YYYY',
|
||||||
|
z: 'ZZ',
|
||||||
|
Z: 'z'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!format || format.length <= 0) return format;
|
||||||
|
|
||||||
|
var replacements = format_mappings['date'];
|
||||||
|
|
||||||
|
var outputFormat = '';
|
||||||
|
|
||||||
|
Object.keys(replacements).forEach(function(key) {
|
||||||
|
if (format.indexOf(key) !== -1) {
|
||||||
|
format = format.replace(key, '%'+key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
outputFormat = format;
|
||||||
|
Object.keys(replacements).forEach(function(key) {
|
||||||
|
if (outputFormat.indexOf('%'+key) !== -1) {
|
||||||
|
outputFormat = outputFormat.replace('%'+key, replacements[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return outputFormat;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
@ -6,14 +6,19 @@ function(
|
|||||||
) {
|
) {
|
||||||
const FormFieldCheckbox = React.createClass({
|
const FormFieldCheckbox = React.createClass({
|
||||||
onValueChange: function(e) {
|
onValueChange: function(e) {
|
||||||
e.target.value = this.refs.checkbox.checked ? '1' : '';
|
e.target.value = this.refs.checkbox.checked ? '1' : '0';
|
||||||
return this.props.onValueChange(e);
|
return this.props.onValueChange(e);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
const isChecked = !!(this.props.item[this.props.field.name]);
|
if (this.props.field.values === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// isChecked will be true only if the value is "1"
|
||||||
|
// it will be false in case value is "0" or empty
|
||||||
|
const isChecked = !!(~~(this.props.item[this.props.field.name]));
|
||||||
const options = Object.keys(this.props.field.values).map(
|
const options = Object.keys(this.props.field.values).map(
|
||||||
function(value, index) {
|
(value, index) => {
|
||||||
return (
|
return (
|
||||||
<p key={ 'checkbox-' + index }>
|
<p key={ 'checkbox-' + index }>
|
||||||
<label>
|
<label>
|
||||||
@ -29,7 +34,7 @@ function(
|
|||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}.bind(this)
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -9,6 +9,13 @@ define([
|
|||||||
render() {
|
render() {
|
||||||
const yearsRange = 100;
|
const yearsRange = 100;
|
||||||
const years = [];
|
const years = [];
|
||||||
|
|
||||||
|
if (this.props.placeholder !== undefined) {
|
||||||
|
years.push((
|
||||||
|
<option value="" key={ 0 }>{ this.props.placeholder }</option>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
const currentYear = Moment().year();
|
const currentYear = Moment().year();
|
||||||
for (let i = currentYear; i >= currentYear - yearsRange; i--) {
|
for (let i = currentYear; i >= currentYear - yearsRange; i--) {
|
||||||
years.push((
|
years.push((
|
||||||
@ -20,7 +27,7 @@ define([
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
name={ this.props.name + '[year]' }
|
name={ `${this.props.name}[year]` }
|
||||||
value={ this.props.year }
|
value={ this.props.year }
|
||||||
onChange={ this.props.onValueChange }
|
onChange={ this.props.onValueChange }
|
||||||
>
|
>
|
||||||
@ -33,6 +40,13 @@ define([
|
|||||||
class FormFieldDateMonth extends React.Component {
|
class FormFieldDateMonth extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const months = [];
|
const months = [];
|
||||||
|
|
||||||
|
if (this.props.placeholder !== undefined) {
|
||||||
|
months.push((
|
||||||
|
<option value="" key={ 0 }>{ this.props.placeholder }</option>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 1; i <= 12; i++) {
|
for (let i = 1; i <= 12; i++) {
|
||||||
months.push((
|
months.push((
|
||||||
<option
|
<option
|
||||||
@ -43,7 +57,7 @@ define([
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
name={ this.props.name + '[month]' }
|
name={ `${this.props.name}[month]` }
|
||||||
value={ this.props.month }
|
value={ this.props.month }
|
||||||
onChange={ this.props.onValueChange }
|
onChange={ this.props.onValueChange }
|
||||||
>
|
>
|
||||||
@ -56,6 +70,13 @@ define([
|
|||||||
class FormFieldDateDay extends React.Component {
|
class FormFieldDateDay extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const days = [];
|
const days = [];
|
||||||
|
|
||||||
|
if (this.props.placeholder !== undefined) {
|
||||||
|
days.push((
|
||||||
|
<option value="" key={ 0 }>{ this.props.placeholder }</option>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 1; i <= 31; i++) {
|
for (let i = 1; i <= 31; i++) {
|
||||||
days.push((
|
days.push((
|
||||||
<option
|
<option
|
||||||
@ -67,7 +88,7 @@ define([
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
name={ this.props.name + '[day]' }
|
name={ `${this.props.name}[day]` }
|
||||||
value={ this.props.day }
|
value={ this.props.day }
|
||||||
onChange={ this.props.onValueChange }
|
onChange={ this.props.onValueChange }
|
||||||
>
|
>
|
||||||
@ -81,47 +102,74 @@ define([
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
year: Moment().year(),
|
year: '',
|
||||||
month: 1,
|
month: '',
|
||||||
day: 1
|
day: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.extractDateParts();
|
||||||
}
|
}
|
||||||
componentDidUpdate(prevProps, prevState) {
|
componentDidUpdate(prevProps, prevState) {
|
||||||
if (
|
if (
|
||||||
(this.props.item !== undefined && prevProps.item !== undefined)
|
(this.props.item !== undefined && prevProps.item !== undefined)
|
||||||
&& (this.props.item.id !== prevProps.item.id)
|
&& (this.props.item.id !== prevProps.item.id)
|
||||||
) {
|
) {
|
||||||
this.extractTimeStamp();
|
this.extractDateParts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extractTimeStamp() {
|
extractDateParts() {
|
||||||
const timeStamp = parseInt(this.props.item[this.props.field.name], 10);
|
const value = (this.props.item[this.props.field.name] !== undefined)
|
||||||
|
? this.props.item[this.props.field.name].trim()
|
||||||
|
: '';
|
||||||
|
|
||||||
|
if(value === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateTime = Moment(value);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
year: Moment.unix(timeStamp).year(),
|
year: dateTime.format('YYYY'),
|
||||||
// Moment returns the month as [0..11]
|
month: dateTime.format('M'),
|
||||||
// We increment it to match PHP's mktime() which expects [1..12]
|
day: dateTime.format('D')
|
||||||
month: Moment.unix(timeStamp).month() + 1,
|
|
||||||
day: Moment.unix(timeStamp).date()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
updateTimeStamp(field) {
|
formatValue() {
|
||||||
let newTimeStamp = Moment(
|
const dateType = this.props.field.params.date_type;
|
||||||
`${this.state.month}/${this.state.day}/${this.state.year}`,
|
|
||||||
'M/D/YYYY'
|
let value;
|
||||||
).valueOf();
|
|
||||||
if (!isNaN(newTimeStamp) && parseInt(newTimeStamp, 10) > 0) {
|
switch(dateType) {
|
||||||
// convert milliseconds to seconds
|
case 'year_month_day':
|
||||||
newTimeStamp /= 1000;
|
value = {
|
||||||
return this.props.onValueChange({
|
'year': this.state.year,
|
||||||
target: {
|
'month': this.state.month,
|
||||||
name: field,
|
'day': this.state.day
|
||||||
value: newTimeStamp
|
};
|
||||||
}
|
break;
|
||||||
});
|
|
||||||
|
case 'year_month':
|
||||||
|
value = {
|
||||||
|
'year': this.state.year,
|
||||||
|
'month': this.state.month
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'month':
|
||||||
|
value = {
|
||||||
|
'month': this.state.month
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'year':
|
||||||
|
value = {
|
||||||
|
'year': this.state.year
|
||||||
|
};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
onValueChange(e) {
|
onValueChange(e) {
|
||||||
// extract property from name
|
// extract property from name
|
||||||
@ -133,35 +181,40 @@ define([
|
|||||||
field = matches[1];
|
field = matches[1];
|
||||||
property = matches[2];
|
property = matches[2];
|
||||||
|
|
||||||
let value = parseInt(e.target.value, 10);
|
let value = ~~(e.target.value);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
[`${property}`]: value
|
[`${property}`]: value
|
||||||
}, () => {
|
}, () => {
|
||||||
this.updateTimeStamp(field);
|
this.props.onValueChange({
|
||||||
|
target: {
|
||||||
|
name: field,
|
||||||
|
value: this.formatValue()
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const monthNames = window.mailpoet_month_names || [];
|
const monthNames = window.mailpoet_month_names || [];
|
||||||
|
const dateFormats = window.mailpoet_date_formats || {};
|
||||||
const dateType = this.props.field.params.date_type;
|
const dateType = this.props.field.params.date_type;
|
||||||
|
const dateSelects = dateFormats[dateType][0].split('/');
|
||||||
const dateSelects = dateType.split('_');
|
|
||||||
|
|
||||||
const fields = dateSelects.map(type => {
|
const fields = dateSelects.map(type => {
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case 'year':
|
case 'YYYY':
|
||||||
return (<FormFieldDateYear
|
return (<FormFieldDateYear
|
||||||
onValueChange={ this.onValueChange.bind(this) }
|
onValueChange={ this.onValueChange.bind(this) }
|
||||||
ref={ 'year' }
|
ref={ 'year' }
|
||||||
key={ 'year' }
|
key={ 'year' }
|
||||||
name={ this.props.field.name }
|
name={ this.props.field.name }
|
||||||
year={ this.state.year }
|
year={ this.state.year }
|
||||||
|
placeholder={ this.props.field.year_placeholder }
|
||||||
/>);
|
/>);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'month':
|
case 'MM':
|
||||||
return (<FormFieldDateMonth
|
return (<FormFieldDateMonth
|
||||||
onValueChange={ this.onValueChange.bind(this) }
|
onValueChange={ this.onValueChange.bind(this) }
|
||||||
ref={ 'month' }
|
ref={ 'month' }
|
||||||
@ -169,16 +222,18 @@ define([
|
|||||||
name={ this.props.field.name }
|
name={ this.props.field.name }
|
||||||
month={ this.state.month }
|
month={ this.state.month }
|
||||||
monthNames={ monthNames }
|
monthNames={ monthNames }
|
||||||
|
placeholder={ this.props.field.month_placeholder }
|
||||||
/>);
|
/>);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'day':
|
case 'DD':
|
||||||
return (<FormFieldDateDay
|
return (<FormFieldDateDay
|
||||||
onValueChange={ this.onValueChange.bind(this) }
|
onValueChange={ this.onValueChange.bind(this) }
|
||||||
ref={ 'day' }
|
ref={ 'day' }
|
||||||
key={ 'day' }
|
key={ 'day' }
|
||||||
name={ this.props.field.name }
|
name={ this.props.field.name }
|
||||||
day={ this.state.day }
|
day={ this.state.day }
|
||||||
|
placeholder={ this.props.field.day_placeholder }
|
||||||
/>);
|
/>);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,10 @@ function(
|
|||||||
case 'date':
|
case 'date':
|
||||||
field = (<FormFieldDate {...data} />);
|
field = (<FormFieldDate {...data} />);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'reactComponent':
|
||||||
|
field = (<data.field.component {...data} />);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inline === true) {
|
if(inline === true) {
|
||||||
|
@ -4,12 +4,15 @@ define([
|
|||||||
function(
|
function(
|
||||||
React
|
React
|
||||||
) {
|
) {
|
||||||
var FormFieldRadio = React.createClass({
|
const FormFieldRadio = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
var selected_value = this.props.item[this.props.field.name];
|
if (this.props.field.values === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var options = Object.keys(this.props.field.values).map(
|
const selected_value = this.props.item[this.props.field.name];
|
||||||
function(value, index) {
|
const options = Object.keys(this.props.field.values).map(
|
||||||
|
(value, index) => {
|
||||||
return (
|
return (
|
||||||
<p key={ 'radio-' + index }>
|
<p key={ 'radio-' + index }>
|
||||||
<label>
|
<label>
|
||||||
@ -23,7 +26,7 @@ function(
|
|||||||
</label>
|
</label>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}.bind(this)
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,13 +1,53 @@
|
|||||||
define([
|
import React from 'react'
|
||||||
'react'
|
import _ from 'underscore'
|
||||||
],
|
|
||||||
function(
|
const FormFieldSelect = React.createClass({
|
||||||
React
|
render() {
|
||||||
) {
|
if (this.props.field.values === undefined) {
|
||||||
var FormFieldSelect = React.createClass({
|
return false;
|
||||||
render: function() {
|
}
|
||||||
var options =
|
|
||||||
Object.keys(this.props.field.values).map(function(value, index) {
|
let filter = false;
|
||||||
|
let placeholder = false;
|
||||||
|
let sortBy = false;
|
||||||
|
|
||||||
|
if (this.props.field.placeholder !== undefined) {
|
||||||
|
placeholder = (
|
||||||
|
<option value="">{ this.props.field.placeholder }</option>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.field['filter'] !== undefined) {
|
||||||
|
filter = this.props.field.filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.isFunction(this.props.field.sortBy)) {
|
||||||
|
sortBy = this.props.field.sortBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
let keys;
|
||||||
|
if (sortBy) {
|
||||||
|
// Extract keys from sorted [key, value] select value pairs, sorted by
|
||||||
|
// provided sorting order.
|
||||||
|
keys =
|
||||||
|
_.map(
|
||||||
|
_.sortBy(
|
||||||
|
_.pairs(this.props.field.values),
|
||||||
|
(item) => sortBy(item[0], item[1])
|
||||||
|
),
|
||||||
|
(item) => item[0]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
keys = Object.keys(this.props.field.values)
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = keys.map(
|
||||||
|
(value, index) => {
|
||||||
|
|
||||||
|
if (filter !== false && filter(this.props.item, value) === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<option
|
<option
|
||||||
key={ 'option-' + index }
|
key={ 'option-' + index }
|
||||||
@ -15,7 +55,7 @@ function(
|
|||||||
{ this.props.field.values[value] }
|
{ this.props.field.values[value] }
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
}.bind(this)
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -26,11 +66,11 @@ function(
|
|||||||
onChange={ this.props.onValueChange }
|
onChange={ this.props.onValueChange }
|
||||||
{...this.props.field.validation}
|
{...this.props.field.validation}
|
||||||
>
|
>
|
||||||
|
{placeholder}
|
||||||
{options}
|
{options}
|
||||||
</select>
|
</select>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return FormFieldSelect;
|
module.exports = FormFieldSelect;
|
||||||
});
|
|
||||||
|
@ -13,12 +13,22 @@ function(
|
|||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
items: [],
|
items: [],
|
||||||
initialized: false
|
select2: false
|
||||||
}
|
};
|
||||||
|
},
|
||||||
|
componentWillMount: function() {
|
||||||
|
this.loadCachedItems();
|
||||||
|
},
|
||||||
|
allowMultipleValues: function() {
|
||||||
|
return (this.props.field.multiple === true);
|
||||||
|
},
|
||||||
|
isSelect2Initialized: function() {
|
||||||
|
return (this.state.select2 === true);
|
||||||
},
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this.loadCachedItems();
|
if(this.allowMultipleValues()) {
|
||||||
this.setupSelect2();
|
this.setupSelect2();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
componentDidUpdate: function(prevProps, prevState) {
|
componentDidUpdate: function(prevProps, prevState) {
|
||||||
if(
|
if(
|
||||||
@ -26,16 +36,22 @@ function(
|
|||||||
&& (this.props.item.id !== prevProps.item.id)
|
&& (this.props.item.id !== prevProps.item.id)
|
||||||
) {
|
) {
|
||||||
jQuery('#'+this.refs.select.id)
|
jQuery('#'+this.refs.select.id)
|
||||||
.val(this.props.item[this.props.field.name])
|
.val(this.getSelectedValues())
|
||||||
.trigger('change');
|
.trigger('change');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
if(this.allowMultipleValues()) {
|
||||||
|
this.destroySelect2();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroySelect2: function() {
|
||||||
|
if(this.isSelect2Initialized()) {
|
||||||
|
jQuery('#'+this.refs.select.id).select2('destroy');
|
||||||
|
}
|
||||||
|
},
|
||||||
setupSelect2: function() {
|
setupSelect2: function() {
|
||||||
if(
|
if(this.isSelect2Initialized()) {
|
||||||
!this.props.field.multiple
|
|
||||||
|| this.state.initialized === true
|
|
||||||
|| this.refs.select === undefined
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,10 +60,14 @@ function(
|
|||||||
templateResult: function(item) {
|
templateResult: function(item) {
|
||||||
if(item.element && item.element.selected) {
|
if(item.element && item.element.selected) {
|
||||||
return null;
|
return null;
|
||||||
|
} else {
|
||||||
|
if(item.title) {
|
||||||
|
return item.title;
|
||||||
} else {
|
} else {
|
||||||
return item.text;
|
return item.text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var hasRemoved = false;
|
var hasRemoved = false;
|
||||||
@ -63,17 +83,29 @@ function(
|
|||||||
|
|
||||||
select2.on('change', this.handleChange);
|
select2.on('change', this.handleChange);
|
||||||
|
|
||||||
select2.select2(
|
this.setState({ select2: true });
|
||||||
'val',
|
},
|
||||||
this.props.item[this.props.field.name]
|
getSelectedValues: function() {
|
||||||
);
|
if(this.props.field['selected'] !== undefined) {
|
||||||
|
return this.props.field['selected'](this.props.item);
|
||||||
this.setState({ initialized: true });
|
} else if(this.props.item !== undefined && this.props.field.name !== undefined) {
|
||||||
|
if (this.allowMultipleValues()) {
|
||||||
|
if (Array.isArray(this.props.item[this.props.field.name])) {
|
||||||
|
return this.props.item[this.props.field.name].map(function(item) {
|
||||||
|
return item.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this.props.item[this.props.field.name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
loadCachedItems: function() {
|
loadCachedItems: function() {
|
||||||
if(typeof(window['mailpoet_'+this.props.field.endpoint]) !== 'undefined') {
|
if(typeof(window['mailpoet_'+this.props.field.endpoint]) !== 'undefined') {
|
||||||
var items = window['mailpoet_'+this.props.field.endpoint];
|
var items = window['mailpoet_'+this.props.field.endpoint];
|
||||||
|
|
||||||
|
|
||||||
if(this.props.field['filter'] !== undefined) {
|
if(this.props.field['filter'] !== undefined) {
|
||||||
items = items.filter(this.props.field.filter);
|
items = items.filter(this.props.field.filter);
|
||||||
}
|
}
|
||||||
@ -98,31 +130,48 @@ function(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getLabel: function(item) {
|
||||||
|
if(this.props.field['getLabel'] !== undefined) {
|
||||||
|
return this.props.field.getLabel(item, this.props.item);
|
||||||
|
}
|
||||||
|
return item.name;
|
||||||
|
},
|
||||||
|
getSearchLabel: function(item) {
|
||||||
|
if(this.props.field['getSearchLabel'] !== undefined) {
|
||||||
|
return this.props.field.getSearchLabel(item, this.props.item);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
getValue: function(item) {
|
||||||
|
if(this.props.field['getValue'] !== undefined) {
|
||||||
|
return this.props.field.getValue(item, this.props.item);
|
||||||
|
}
|
||||||
|
return item.id;
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var options = this.state.items.map(function(item, index) {
|
const options = this.state.items.map((item, index) => {
|
||||||
|
let label = this.getLabel(item);
|
||||||
|
let searchLabel = this.getSearchLabel(item);
|
||||||
|
let value = this.getValue(item);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<option
|
<option
|
||||||
key={ item.id }
|
key={ 'option-'+index }
|
||||||
value={ item.id }
|
value={ value }
|
||||||
|
title={ searchLabel }
|
||||||
>
|
>
|
||||||
{ item.name }
|
{ label }
|
||||||
</option>
|
</option>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
var default_value = (
|
|
||||||
(this.props.item !== undefined && this.props.field.name !== undefined)
|
|
||||||
? this.props.item[this.props.field.name]
|
|
||||||
: null
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
id={ this.props.field.id || this.props.field.name }
|
id={ this.props.field.id || this.props.field.name }
|
||||||
ref="select"
|
ref="select"
|
||||||
data-placeholder={ this.props.field.placeholder }
|
data-placeholder={ this.props.field.placeholder }
|
||||||
multiple={ this.props.field.multiple }
|
multiple={ this.props.field.multiple }
|
||||||
defaultValue={ default_value }
|
defaultValue={ this.getSelectedValues() }
|
||||||
{...this.props.field.validation}
|
{...this.props.field.validation}
|
||||||
>{ options }</select>
|
>{ options }</select>
|
||||||
);
|
);
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
define([
|
import React from 'react'
|
||||||
'react'
|
|
||||||
],
|
const FormFieldText = React.createClass({
|
||||||
function(
|
render() {
|
||||||
React
|
let value = this.props.item[this.props.field.name];
|
||||||
) {
|
if (value === undefined) {
|
||||||
var FormFieldText = React.createClass({
|
value = this.props.field.defaultValue || '';
|
||||||
render: function() {
|
}
|
||||||
var value = this.props.item[this.props.field.name];
|
|
||||||
if(!value) { value = null; }
|
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
disabled={
|
||||||
|
(this.props.field['disabled'] !== undefined)
|
||||||
|
? this.props.field.disabled(this.props.item)
|
||||||
|
: false
|
||||||
|
}
|
||||||
className={ (this.props.field.size) ? '' : 'regular-text' }
|
className={ (this.props.field.size) ? '' : 'regular-text' }
|
||||||
size={
|
size={
|
||||||
(this.props.field.size !== 'auto' && this.props.field.size > 0)
|
(this.props.field.size !== 'auto' && this.props.field.size > 0)
|
||||||
@ -21,7 +25,6 @@ function(
|
|||||||
id={ 'field_'+this.props.field.name }
|
id={ 'field_'+this.props.field.name }
|
||||||
value={ value }
|
value={ value }
|
||||||
placeholder={ this.props.field.placeholder }
|
placeholder={ this.props.field.placeholder }
|
||||||
defaultValue={ this.props.field.defaultValue }
|
|
||||||
onChange={ this.props.onValueChange }
|
onChange={ this.props.onValueChange }
|
||||||
{...this.props.field.validation}
|
{...this.props.field.validation}
|
||||||
/>
|
/>
|
||||||
@ -29,5 +32,4 @@ function(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return FormFieldText;
|
module.exports = FormFieldText;
|
||||||
});
|
|
@ -13,10 +13,16 @@ define(
|
|||||||
Router,
|
Router,
|
||||||
FormField
|
FormField
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var Form = React.createClass({
|
var Form = React.createClass({
|
||||||
mixins: [
|
contextTypes: {
|
||||||
Router.History
|
router: React.PropTypes.object.isRequired
|
||||||
],
|
},
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
params: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -24,10 +30,20 @@ define(
|
|||||||
item: {}
|
item: {}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
getValues: function() {
|
||||||
|
return this.props.item ? this.props.item : this.state.item;
|
||||||
|
},
|
||||||
|
getErrors: function() {
|
||||||
|
return this.props.errors ? this.props.errors : this.state.errors;
|
||||||
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
if(this.props.params.id !== undefined) {
|
|
||||||
if(this.isMounted()) {
|
if(this.isMounted()) {
|
||||||
|
if(this.props.params.id !== undefined) {
|
||||||
this.loadItem(this.props.params.id);
|
this.loadItem(this.props.params.id);
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
item: jQuery('.mailpoet_form').serializeObject()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -37,7 +53,9 @@ define(
|
|||||||
loading: false,
|
loading: false,
|
||||||
item: {}
|
item: {}
|
||||||
});
|
});
|
||||||
|
if (props.item === undefined) {
|
||||||
this.refs.form.reset();
|
this.refs.form.reset();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.loadItem(props.params.id);
|
this.loadItem(props.params.id);
|
||||||
}
|
}
|
||||||
@ -48,22 +66,22 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'get',
|
action: 'get',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
if(response === false) {
|
}
|
||||||
|
}).done((response) => {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
item: response.data
|
||||||
|
});
|
||||||
|
}).fail((response) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
item: {}
|
item: {}
|
||||||
}, function() {
|
}, function() {
|
||||||
this.history.pushState(null, '/new');
|
this.context.router.push('/new');
|
||||||
}.bind(this));
|
});
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
item: response
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
},
|
||||||
handleSubmit: function(e) {
|
handleSubmit: function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -88,7 +106,6 @@ define(
|
|||||||
item[field.name] = this.state.item[field.name];
|
item[field.name] = this.state.item[field.name];
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
// set id if specified
|
// set id if specified
|
||||||
if(this.props.params.id !== undefined) {
|
if(this.props.params.id !== undefined) {
|
||||||
item.id = this.props.params.id;
|
item.id = this.props.params.id;
|
||||||
@ -98,14 +115,13 @@ define(
|
|||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'save',
|
action: 'save',
|
||||||
data: item
|
data: item
|
||||||
}).done(function(response) {
|
}).always(() => {
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
|
}).done((response) => {
|
||||||
if(response.result === true) {
|
|
||||||
if(this.props.onSuccess !== undefined) {
|
if(this.props.onSuccess !== undefined) {
|
||||||
this.props.onSuccess();
|
this.props.onSuccess();
|
||||||
} else {
|
} else {
|
||||||
this.history.pushState(null, '/')
|
this.context.router.push('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.props.params.id !== undefined) {
|
if(this.props.params.id !== undefined) {
|
||||||
@ -113,16 +129,16 @@ define(
|
|||||||
} else {
|
} else {
|
||||||
this.props.messages.onCreate();
|
this.props.messages.onCreate();
|
||||||
}
|
}
|
||||||
} else {
|
}).fail((response) => {
|
||||||
if(response.result === false) {
|
|
||||||
if(response.errors.length > 0) {
|
if(response.errors.length > 0) {
|
||||||
this.setState({ errors: response.errors });
|
this.setState({ errors: response.errors });
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
},
|
||||||
handleValueChange: function(e) {
|
handleValueChange: function(e) {
|
||||||
|
if (this.props.onChange) {
|
||||||
|
return this.props.onChange(e);
|
||||||
|
} else {
|
||||||
var item = this.state.item,
|
var item = this.state.item,
|
||||||
field = e.target.name;
|
field = e.target.name;
|
||||||
|
|
||||||
@ -132,13 +148,14 @@ define(
|
|||||||
item: item
|
item: item
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
if(this.state.errors !== undefined) {
|
if(this.getErrors() !== undefined) {
|
||||||
var errors = this.state.errors.map(function(error, index) {
|
var errors = this.getErrors().map(function(error, index) {
|
||||||
return (
|
return (
|
||||||
<p key={ 'error-'+index } className="mailpoet_error">
|
<p key={ 'error-'+index } className="mailpoet_error">
|
||||||
{ error }
|
{ error.message }
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -146,14 +163,25 @@ define(
|
|||||||
|
|
||||||
var formClasses = classNames(
|
var formClasses = classNames(
|
||||||
'mailpoet_form',
|
'mailpoet_form',
|
||||||
{ 'mailpoet_form_loading': this.state.loading }
|
{ 'mailpoet_form_loading': this.state.loading || this.props.loading }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var beforeFormContent = false;
|
||||||
|
var afterFormContent = false;
|
||||||
|
|
||||||
|
if (this.props.beforeFormContent !== undefined) {
|
||||||
|
beforeFormContent = this.props.beforeFormContent(this.getValues());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.afterFormContent !== undefined) {
|
||||||
|
afterFormContent = this.props.afterFormContent(this.getValues());
|
||||||
|
}
|
||||||
|
|
||||||
var fields = this.props.fields.map(function(field, i) {
|
var fields = this.props.fields.map(function(field, i) {
|
||||||
return (
|
return (
|
||||||
<FormField
|
<FormField
|
||||||
field={ field }
|
field={ field }
|
||||||
item={ this.state.item }
|
item={ this.getValues() }
|
||||||
onValueChange={ this.handleValueChange }
|
onValueChange={ this.handleValueChange }
|
||||||
key={ 'field-'+i } />
|
key={ 'field-'+i } />
|
||||||
);
|
);
|
||||||
@ -167,12 +195,14 @@ define(
|
|||||||
<input
|
<input
|
||||||
className="button button-primary"
|
className="button button-primary"
|
||||||
type="submit"
|
type="submit"
|
||||||
value="Save"
|
value={MailPoet.I18n.t('save')}
|
||||||
disabled={this.state.loading} />
|
disabled={this.state.loading} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
|
{ beforeFormContent }
|
||||||
<form
|
<form
|
||||||
id={ this.props.id }
|
id={ this.props.id }
|
||||||
ref="form"
|
ref="form"
|
||||||
@ -193,6 +223,8 @@ define(
|
|||||||
|
|
||||||
{ actions }
|
{ actions }
|
||||||
</form>
|
</form>
|
||||||
|
{ afterFormContent }
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -402,11 +402,30 @@ var WysijaForm = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// hide list selection if a list widget has been dragged into the editor
|
var hasSegmentSelection = WysijaForm.hasSegmentSelection();
|
||||||
$('mailpoet_settings_segment_selection')[
|
|
||||||
(($$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]').length > 0) === true)
|
if(hasSegmentSelection) {
|
||||||
? 'hide' : 'show'
|
$('mailpoet_form_segments').writeAttribute('required', false).disable();
|
||||||
]();
|
$('mailpoet_settings_segment_selection').hide();
|
||||||
|
} else {
|
||||||
|
$('mailpoet_form_segments').writeAttribute('required', true).enable();
|
||||||
|
$('mailpoet_settings_segment_selection').show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasSegmentSelection: function() {
|
||||||
|
return ($$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]').length > 0);
|
||||||
|
},
|
||||||
|
isSegmentSelectionValid: function() {
|
||||||
|
var segment_selection = $$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]')[0];
|
||||||
|
if(segment_selection !== undefined) {
|
||||||
|
var block = WysijaForm.get(segment_selection).block.getData();
|
||||||
|
return (
|
||||||
|
(block.params.values !== undefined)
|
||||||
|
&&
|
||||||
|
(block.params.values.length > 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
setBlockPositions: function(event, target) {
|
setBlockPositions: function(event, target) {
|
||||||
// release dragging lock
|
// release dragging lock
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { Router, Route, IndexRoute } from 'react-router'
|
import { Router, Route, IndexRoute, Link, useRouterHistory } from 'react-router'
|
||||||
|
import { createHashHistory } from 'history'
|
||||||
import FormList from 'forms/list.jsx'
|
import FormList from 'forms/list.jsx'
|
||||||
import createHashHistory from 'history/lib/createHashHistory'
|
|
||||||
|
|
||||||
let history = createHashHistory({ queryKey: false })
|
const history = useRouterHistory(createHashHistory)({ queryKey: false });
|
||||||
|
|
||||||
const App = React.createClass({
|
const App = React.createClass({
|
||||||
render() {
|
render() {
|
||||||
@ -12,7 +12,7 @@ const App = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let container = document.getElementById('forms_container');
|
const container = document.getElementById('forms_container');
|
||||||
|
|
||||||
if(container) {
|
if(container) {
|
||||||
ReactDOM.render((
|
ReactDOM.render((
|
||||||
|
@ -8,101 +8,112 @@ import MailPoet from 'mailpoet'
|
|||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Name',
|
label: MailPoet.I18n.t('formName'),
|
||||||
sortable: true
|
sortable: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'segments',
|
name: 'segments',
|
||||||
label: 'Lists',
|
label: MailPoet.I18n.t('segments')
|
||||||
sortable: false
|
},
|
||||||
|
{
|
||||||
|
name: 'signups',
|
||||||
|
label: MailPoet.I18n.t('signups')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'created_at',
|
name: 'created_at',
|
||||||
label: 'Created on',
|
label: MailPoet.I18n.t('createdOn'),
|
||||||
sortable: true
|
sortable: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
onTrash: function(response) {
|
onTrash: (response) => {
|
||||||
if(response) {
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
if(~~response === 1) {
|
|
||||||
message = (
|
|
||||||
'1 form was moved to the trash.'
|
|
||||||
);
|
|
||||||
} else if(~~response > 1) {
|
|
||||||
message = (
|
|
||||||
'%$1d forms were moved to the trash.'
|
|
||||||
).replace('%$1d', ~~response);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message !== null) {
|
if (count === 1) {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('oneFormTrashed')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('multipleFormsTrashed')
|
||||||
|
).replace('%$1d', count.toLocaleString());
|
||||||
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onDelete: function(response) {
|
onDelete: (response) => {
|
||||||
if(response) {
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
if(~~response === 1) {
|
|
||||||
message = (
|
|
||||||
'1 form was permanently deleted.'
|
|
||||||
);
|
|
||||||
} else if(~~response > 1) {
|
|
||||||
message = (
|
|
||||||
'%$1d forms were permanently deleted.'
|
|
||||||
).replace('%$1d', ~~response);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message !== null) {
|
if (count === 1) {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('oneFormDeleted')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('multipleFormsDeleted')
|
||||||
|
).replace('%$1d', count.toLocaleString());
|
||||||
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onRestore: function(response) {
|
onRestore: (response) => {
|
||||||
if(response) {
|
const count = ~~response.meta.count;
|
||||||
let message = null;
|
let message = null;
|
||||||
if(~~response === 1) {
|
|
||||||
message = (
|
|
||||||
'1 form has been restored from the trash.'
|
|
||||||
);
|
|
||||||
} else if(~~response > 1) {
|
|
||||||
message = (
|
|
||||||
'%$1d forms have been restored from the trash.'
|
|
||||||
).replace('%$1d', ~~response);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message !== null) {
|
if (count === 1) {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('oneFormRestored')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
message = (
|
||||||
|
MailPoet.I18n.t('multipleFormsRestored')
|
||||||
|
).replace('%$1d', count.toLocaleString());
|
||||||
|
}
|
||||||
MailPoet.Notice.success(message);
|
MailPoet.Notice.success(message);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bulk_actions = [
|
||||||
|
{
|
||||||
|
name: 'trash',
|
||||||
|
label: MailPoet.I18n.t('trash'),
|
||||||
|
onSuccess: messages.onTrash
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
const item_actions = [
|
const item_actions = [
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
label: 'Edit',
|
label: MailPoet.I18n.t('edit'),
|
||||||
link: function(item) {
|
link: function(item) {
|
||||||
return (
|
return (
|
||||||
<a href={ `admin.php?page=mailpoet-form-editor&id=${item.id}` }>Edit</a>
|
<a href={ `admin.php?page=mailpoet-form-editor&id=${item.id}` }>{MailPoet.I18n.t('edit')}</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'duplicate_form',
|
name: 'duplicate',
|
||||||
label: 'Duplicate',
|
label: MailPoet.I18n.t('duplicate'),
|
||||||
onClick: function(item, refresh) {
|
onClick: function(item, refresh) {
|
||||||
return MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: 'forms',
|
endpoint: 'forms',
|
||||||
action: 'duplicate',
|
action: 'duplicate',
|
||||||
data: item.id
|
data: {
|
||||||
}).done(function(response) {
|
id: item.id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
MailPoet.Notice.success(
|
MailPoet.Notice.success(
|
||||||
('Form "%$1s" has been duplicated.').replace('%$1s', response.name)
|
(MailPoet.I18n.t('formDuplicated')).replace('%$1s', response.data.name)
|
||||||
);
|
);
|
||||||
refresh();
|
refresh();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -111,22 +122,19 @@ const item_actions = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const bulk_actions = [
|
|
||||||
{
|
|
||||||
name: 'trash',
|
|
||||||
label: 'Trash',
|
|
||||||
onSuccess: messages.onTrash
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const FormList = React.createClass({
|
const FormList = React.createClass({
|
||||||
createForm() {
|
createForm() {
|
||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: 'forms',
|
endpoint: 'forms',
|
||||||
action: 'create'
|
action: 'create'
|
||||||
}).done(function(response) {
|
}).done((response) => {
|
||||||
if(response.result && response.form_id) {
|
window.location = mailpoet_form_edit_url + response.data.id;
|
||||||
window.location = mailpoet_form_edit_url + response.form_id;
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -143,19 +151,29 @@ const FormList = React.createClass({
|
|||||||
return segment.name;
|
return segment.name;
|
||||||
}).join(', ');
|
}).join(', ');
|
||||||
|
|
||||||
|
if (form.settings.segments_selected_by === 'user') {
|
||||||
|
segments = MailPoet.I18n.t('userChoice') + ' ' + segments;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<td className={ row_classes }>
|
<td className={ row_classes }>
|
||||||
<strong>
|
<strong>
|
||||||
<a>{ form.name }</a>
|
<a
|
||||||
|
className="row-title"
|
||||||
|
href={ `admin.php?page=mailpoet-form-editor&id=${form.id}` }
|
||||||
|
>{ form.name }</a>
|
||||||
</strong>
|
</strong>
|
||||||
{ actions }
|
{ actions }
|
||||||
</td>
|
</td>
|
||||||
<td className="column-format" data-colname="Lists">
|
<td className="column" data-colname={MailPoet.I18n.t('segments')}>
|
||||||
{ segments }
|
{ segments }
|
||||||
</td>
|
</td>
|
||||||
<td className="column-date" data-colname="Created on">
|
<td className="column" data-colname={MailPoet.I18n.t('signups')}>
|
||||||
<abbr>{ form.created_at }</abbr>
|
{ form.signups }
|
||||||
|
</td>
|
||||||
|
<td className="column-date" data-colname={MailPoet.I18n.t('createdOn')}>
|
||||||
|
<abbr>{ MailPoet.Date.format(form.created_at) }</abbr>
|
||||||
</td>
|
</td>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -163,20 +181,20 @@ const FormList = React.createClass({
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2 className="title">
|
<h1 className="title">
|
||||||
Forms <a
|
{MailPoet.I18n.t('pageTitle')} <a
|
||||||
className="add-new-h2"
|
className="page-title-action"
|
||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
onClick={ this.createForm }
|
onClick={ this.createForm }
|
||||||
>New</a>
|
>{MailPoet.I18n.t('new')}</a>
|
||||||
</h2>
|
</h1>
|
||||||
|
|
||||||
<Listing
|
<Listing
|
||||||
|
limit={ mailpoet_listing_per_page }
|
||||||
location={ this.props.location }
|
location={ this.props.location }
|
||||||
params={ this.props.params }
|
params={ this.props.params }
|
||||||
messages={ messages }
|
messages={ messages }
|
||||||
search={ false }
|
search={ false }
|
||||||
limit={ 1000 }
|
|
||||||
endpoint="forms"
|
endpoint="forms"
|
||||||
onRenderItem={ this.renderItem }
|
onRenderItem={ this.renderItem }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
|
@ -140,5 +140,20 @@ define('handlebars_helpers', ['handlebars'], function(Handlebars) {
|
|||||||
return parseInt(string, 10);
|
return parseInt(string, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('fontWithFallback', function(font) {
|
||||||
|
switch(font) {
|
||||||
|
case 'Arial': return new Handlebars.SafeString("Arial, 'Helvetica Neue', Helvetica, sans-serif");
|
||||||
|
case 'Comic Sans MS': return new Handlebars.SafeString("'Comic Sans MS', 'Marker Felt-Thin', Arial, sans-serif");
|
||||||
|
case 'Courier New': return new Handlebars.SafeString("'Courier New', Courier, 'Lucida Sans Typewriter', 'Lucida Typewriter', monospace");
|
||||||
|
case 'Georgia': return new Handlebars.SafeString("Georgia, Times, 'Times New Roman', serif");
|
||||||
|
case 'Lucida': return new Handlebars.SafeString("'Lucida Sans Unicode', 'Lucida Grande', sans-serif");
|
||||||
|
case 'Tahoma': return new Handlebars.SafeString("Tahoma, Verdana, Segoe, sans-serif");
|
||||||
|
case 'Times New Roman': return new Handlebars.SafeString("'Times New Roman', Times, Baskerville, Georgia, serif");
|
||||||
|
case 'Trebuchet MS': return new Handlebars.SafeString("'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif");
|
||||||
|
case 'Verdana': return new Handlebars.SafeString("Verdana, Geneva, sans-serif");
|
||||||
|
default: return font;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
window.Handlebars = Handlebars;
|
window.Handlebars = Handlebars;
|
||||||
});
|
});
|
||||||
|
25
assets/js/src/i18n.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
define('i18n',
|
||||||
|
[
|
||||||
|
'mailpoet',
|
||||||
|
'underscore',
|
||||||
|
], function(
|
||||||
|
MailPoet,
|
||||||
|
_
|
||||||
|
) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var translations = {};
|
||||||
|
|
||||||
|
MailPoet.I18n = {
|
||||||
|
add: function(key, value) {
|
||||||
|
translations[key] = value;
|
||||||
|
},
|
||||||
|
t: function(key) {
|
||||||
|
return translations[key] || 'TRANSLATION "%$1s" NOT FOUND'.replace("%$1s", key);
|
||||||
|
},
|
||||||
|
all: function() {
|
||||||
|
return translations;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
23
assets/js/src/iframe.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
define('iframe', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
||||||
|
'use strict';
|
||||||
|
MailPoet.Iframe = {
|
||||||
|
marginY: 20,
|
||||||
|
autoSize: function(iframe) {
|
||||||
|
if(!iframe) return;
|
||||||
|
|
||||||
|
this.setSize(
|
||||||
|
iframe,
|
||||||
|
iframe.contentWindow.document.body.scrollHeight
|
||||||
|
);
|
||||||
|
},
|
||||||
|
setSize: function(iframe, i) {
|
||||||
|
if(!iframe) return;
|
||||||
|
|
||||||
|
iframe.style.height = (
|
||||||
|
parseInt(i) + this.marginY
|
||||||
|
) + "px";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return MailPoet;
|
||||||
|
});
|
@ -1,8 +1,10 @@
|
|||||||
define([
|
define([
|
||||||
'react'
|
'react',
|
||||||
|
'mailpoet'
|
||||||
],
|
],
|
||||||
function(
|
function(
|
||||||
React
|
React,
|
||||||
|
MailPoet
|
||||||
) {
|
) {
|
||||||
var ListingBulkActions = React.createClass({
|
var ListingBulkActions = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
@ -45,13 +47,16 @@ function(
|
|||||||
|
|
||||||
data.action = this.state.action;
|
data.action = this.state.action;
|
||||||
|
|
||||||
var callback = function() {};
|
var onSuccess = function() {};
|
||||||
if(action['onSuccess'] !== undefined) {
|
if(action['onSuccess'] !== undefined) {
|
||||||
callback = action.onSuccess;
|
onSuccess = action.onSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data.action) {
|
if(data.action) {
|
||||||
this.props.onBulkAction(selected_ids, data, callback);
|
const promise = this.props.onBulkAction(selected_ids, data);
|
||||||
|
if (promise !== false) {
|
||||||
|
promise.then(onSuccess);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -82,7 +87,7 @@ function(
|
|||||||
<label
|
<label
|
||||||
className="screen-reader-text"
|
className="screen-reader-text"
|
||||||
htmlFor="bulk-action-selector-top">
|
htmlFor="bulk-action-selector-top">
|
||||||
Select bulk action
|
{MailPoet.I18n.t('selectBulkAction')}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
@ -91,7 +96,7 @@ function(
|
|||||||
value={ this.state.action }
|
value={ this.state.action }
|
||||||
onChange={this.handleChangeAction}
|
onChange={this.handleChangeAction}
|
||||||
>
|
>
|
||||||
<option value="">Bulk Actions</option>
|
<option value="">{MailPoet.I18n.t('bulkActions')}</option>
|
||||||
{ this.props.bulk_actions.map(function(action, index) {
|
{ this.props.bulk_actions.map(function(action, index) {
|
||||||
return (
|
return (
|
||||||
<option
|
<option
|
||||||
@ -104,7 +109,7 @@ function(
|
|||||||
<input
|
<input
|
||||||
onClick={ this.handleApplyAction }
|
onClick={ this.handleApplyAction }
|
||||||
type="submit"
|
type="submit"
|
||||||
defaultValue="Apply"
|
defaultValue={MailPoet.I18n.t('apply')}
|
||||||
className="button action" />
|
className="button action" />
|
||||||
|
|
||||||
{ this.state.extra }
|
{ this.state.extra }
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
define([
|
define([
|
||||||
'react',
|
'react',
|
||||||
'jquery'
|
'jquery',
|
||||||
|
'mailpoet'
|
||||||
],
|
],
|
||||||
function(
|
function(
|
||||||
React,
|
React,
|
||||||
jQuery
|
jQuery,
|
||||||
|
MailPoet
|
||||||
) {
|
) {
|
||||||
var ListingFilters = React.createClass({
|
var ListingFilters = React.createClass({
|
||||||
handleFilterAction: function() {
|
handleFilterAction: function() {
|
||||||
let filters = {}
|
let filters = {};
|
||||||
this.getAvailableFilters().map((filter, i) => {
|
this.getAvailableFilters().map((filter, i) => {
|
||||||
filters[this.refs['filter-'+i].name] = this.refs['filter-'+i].value
|
filters[this.refs['filter-'+i].name] = this.refs['filter-'+i].value
|
||||||
})
|
});
|
||||||
return this.props.onSelectFilter(filters);
|
return this.props.onSelectFilter(filters);
|
||||||
},
|
},
|
||||||
|
handleEmptyTrash: function() {
|
||||||
|
return this.props.onEmptyTrash();
|
||||||
|
},
|
||||||
getAvailableFilters: function() {
|
getAvailableFilters: function() {
|
||||||
let filters = this.props.filters;
|
let filters = this.props.filters;
|
||||||
|
|
||||||
return Object.keys(filters).filter(function(filter) {
|
return Object.keys(filters).filter(function(filter) {
|
||||||
return !(
|
return !(
|
||||||
filters[filter].length === 0
|
filters[filter].length === 0
|
||||||
@ -25,26 +29,29 @@ function(
|
|||||||
&& !filters[filter][0].value
|
&& !filters[filter][0].value
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
})
|
});
|
||||||
|
},
|
||||||
|
componentDidUpdate: function() {
|
||||||
|
const selected_filters = this.props.filter;
|
||||||
|
const available_filters = this.getAvailableFilters().map(
|
||||||
|
function(filter, i) {
|
||||||
|
if (selected_filters[filter] !== undefined && selected_filters[filter]) {
|
||||||
|
jQuery(this.refs['filter-'+i])
|
||||||
|
.val(selected_filters[filter])
|
||||||
|
.trigger('change');
|
||||||
|
}
|
||||||
|
}.bind(this)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
const filters = this.props.filters;
|
const filters = this.props.filters;
|
||||||
const selected_filters = this.props.filter;
|
|
||||||
|
|
||||||
const available_filters = this.getAvailableFilters()
|
const available_filters = this.getAvailableFilters()
|
||||||
.map(function(filter, i) {
|
.map(function(filter, i) {
|
||||||
let default_value = false;
|
|
||||||
if(selected_filters[filter] !== undefined && selected_filters[filter]) {
|
|
||||||
default_value = selected_filters[filter]
|
|
||||||
} else {
|
|
||||||
jQuery(`select[name="${filter}"]`).val('');
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
ref={ `filter-${i}` }
|
ref={ `filter-${i}` }
|
||||||
key={ `filter-${i}` }
|
key={ `filter-${i}` }
|
||||||
name={ filter }
|
name={ filter }
|
||||||
defaultValue={ default_value }
|
|
||||||
>
|
>
|
||||||
{ filters[filter].map(function(option, j) {
|
{ filters[filter].map(function(option, j) {
|
||||||
return (
|
return (
|
||||||
@ -58,22 +65,36 @@ function(
|
|||||||
);
|
);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
let button = false;
|
let button;
|
||||||
|
|
||||||
if (available_filters.length > 0) {
|
if (available_filters.length > 0) {
|
||||||
button = (
|
button = (
|
||||||
<input
|
<input
|
||||||
|
id="post-query-submit"
|
||||||
onClick={ this.handleFilterAction }
|
onClick={ this.handleFilterAction }
|
||||||
type="submit"
|
type="submit"
|
||||||
defaultValue="Filter"
|
defaultValue={MailPoet.I18n.t('filter')}
|
||||||
className="button" />
|
className="button" />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let empty_trash;
|
||||||
|
if (this.props.group === 'trash') {
|
||||||
|
empty_trash = (
|
||||||
|
<input
|
||||||
|
onClick={ this.handleEmptyTrash }
|
||||||
|
type="submit"
|
||||||
|
value={MailPoet.I18n.t('emptyTrash')}
|
||||||
|
className="button"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="alignleft actions actions">
|
<div className="alignleft actions actions">
|
||||||
{ available_filters }
|
{ available_filters }
|
||||||
{ button }
|
{ button }
|
||||||
|
{ empty_trash }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
className={classes}
|
className={classes}
|
||||||
onClick={this.handleSelect.bind(this, group.name)} >
|
onClick={this.handleSelect.bind(this, group.name)} >
|
||||||
{group.label} <span className="count">({ group.count })</span>
|
{group.label} <span className="count">({ group.count.toLocaleString() })</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
define(['react', 'classnames'], function(React, classNames) {
|
import MailPoet from 'mailpoet'
|
||||||
|
import React from 'react'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
var ListingHeader = React.createClass({
|
const ListingHeader = React.createClass({
|
||||||
handleSelectItems: function() {
|
handleSelectItems: function() {
|
||||||
return this.props.onSelectItems(
|
return this.props.onSelectItems(
|
||||||
this.refs.toggle.checked
|
this.refs.toggle.checked
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var columns = this.props.columns.map(function(column, index) {
|
const columns = this.props.columns.map(function(column, index) {
|
||||||
column.is_primary = (index === 0);
|
column.is_primary = (index === 0);
|
||||||
column.sorted = (this.props.sort_by === column.name)
|
column.sorted = (this.props.sort_by === column.name)
|
||||||
? this.props.sort_order
|
? this.props.sort_order
|
||||||
@ -21,14 +23,14 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
);
|
);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
var checkbox = false;
|
let checkbox;
|
||||||
|
|
||||||
if(this.props.is_selectable === true) {
|
if(this.props.is_selectable === true) {
|
||||||
checkbox = (
|
checkbox = (
|
||||||
<th
|
<th
|
||||||
className="manage-column column-cb check-column">
|
className="manage-column column-cb check-column">
|
||||||
<label className="screen-reader-text">
|
<label className="screen-reader-text">
|
||||||
{ 'Select All' }
|
{MailPoet.I18n.t('selectAll')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -49,21 +51,21 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var ListingColumn = React.createClass({
|
const ListingColumn = React.createClass({
|
||||||
handleSort: function() {
|
handleSort: function() {
|
||||||
var sort_by = this.props.column.name,
|
const sort_by = this.props.column.name;
|
||||||
sort_order = (this.props.column.sorted === 'asc') ? 'desc' : 'asc';
|
const sort_order = (this.props.column.sorted === 'asc') ? 'desc' : 'asc';
|
||||||
this.props.onSort(sort_by, sort_order);
|
this.props.onSort(sort_by, sort_order);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var classes = classNames(
|
const classes = classNames(
|
||||||
'manage-column',
|
'manage-column',
|
||||||
{ 'column-primary': this.props.column.is_primary },
|
{ 'column-primary': this.props.column.is_primary },
|
||||||
{ 'sortable': this.props.column.sortable },
|
{ 'sortable': this.props.column.sortable },
|
||||||
this.props.column.sorted,
|
this.props.column.sorted,
|
||||||
{ 'sorted': (this.props.sort_by === this.props.column.name) }
|
{ 'sorted': (this.props.sort_by === this.props.column.name) }
|
||||||
);
|
);
|
||||||
var label;
|
let label;
|
||||||
|
|
||||||
if(this.props.column.sortable === true) {
|
if(this.props.column.sortable === true) {
|
||||||
label = (
|
label = (
|
||||||
@ -79,12 +81,11 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
<th
|
<th
|
||||||
className={ classes }
|
className={ classes }
|
||||||
id={this.props.column.name }
|
id={this.props.column.name }
|
||||||
scope="col">
|
scope="col"
|
||||||
{label}
|
width={ this.props.column.width || null }
|
||||||
</th>
|
>{label}</th>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return ListingHeader;
|
module.exports = ListingHeader;
|
||||||
});
|
|
@ -1,36 +1,20 @@
|
|||||||
define(
|
import MailPoet from 'mailpoet'
|
||||||
[
|
import jQuery from 'jquery'
|
||||||
'mailpoet',
|
import React from 'react'
|
||||||
'jquery',
|
import _ from 'underscore'
|
||||||
'react',
|
import { Router, Link } from 'react-router'
|
||||||
'react-router',
|
import classNames from 'classnames'
|
||||||
'classnames',
|
import ListingBulkActions from 'listing/bulk_actions.jsx'
|
||||||
'listing/bulk_actions.jsx',
|
import ListingHeader from 'listing/header.jsx'
|
||||||
'listing/header.jsx',
|
import ListingPages from 'listing/pages.jsx'
|
||||||
'listing/pages.jsx',
|
import ListingSearch from 'listing/search.jsx'
|
||||||
'listing/search.jsx',
|
import ListingGroups from 'listing/groups.jsx'
|
||||||
'listing/groups.jsx',
|
import ListingFilters from 'listing/filters.jsx'
|
||||||
'listing/filters.jsx'
|
|
||||||
],
|
|
||||||
function(
|
|
||||||
MailPoet,
|
|
||||||
jQuery,
|
|
||||||
React,
|
|
||||||
Router,
|
|
||||||
classNames,
|
|
||||||
ListingBulkActions,
|
|
||||||
ListingHeader,
|
|
||||||
ListingPages,
|
|
||||||
ListingSearch,
|
|
||||||
ListingGroups,
|
|
||||||
ListingFilters
|
|
||||||
) {
|
|
||||||
var Link = Router.Link;
|
|
||||||
|
|
||||||
var ListingItem = React.createClass({
|
const ListingItem = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
toggled: true
|
expanded: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleSelectItem: function(e) {
|
handleSelectItem: function(e) {
|
||||||
@ -51,7 +35,7 @@ define(
|
|||||||
this.props.onDeleteItem(id);
|
this.props.onDeleteItem(id);
|
||||||
},
|
},
|
||||||
handleToggleItem: function(id) {
|
handleToggleItem: function(id) {
|
||||||
this.setState({ toggled: !this.state.toggled });
|
this.setState({ expanded: !this.state.expanded });
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var checkbox = false;
|
var checkbox = false;
|
||||||
@ -74,10 +58,11 @@ define(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var custom_actions = this.props.item_actions;
|
const custom_actions = this.props.item_actions;
|
||||||
var item_actions = false;
|
let item_actions = false;
|
||||||
|
|
||||||
if (custom_actions.length > 0) {
|
if (custom_actions.length > 0) {
|
||||||
|
let is_first = true;
|
||||||
item_actions = custom_actions.map(function(action, index) {
|
item_actions = custom_actions.map(function(action, index) {
|
||||||
if (action.display !== undefined) {
|
if (action.display !== undefined) {
|
||||||
if (action.display(this.props.item) === false) {
|
if (action.display(this.props.item) === false) {
|
||||||
@ -85,42 +70,44 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let custom_action = null;
|
||||||
|
|
||||||
if (action.name === 'trash') {
|
if (action.name === 'trash') {
|
||||||
return (
|
custom_action = (
|
||||||
<span key={ 'action-'+index } className="trash">
|
<span key={ 'action-'+index } className="trash">
|
||||||
{(index > 0) ? ' | ' : ''}
|
{(!is_first) ? ' | ' : ''}
|
||||||
<a
|
<a
|
||||||
href="javascript:;"
|
href="javascript:;"
|
||||||
onClick={ this.handleTrashItem.bind(
|
onClick={ this.handleTrashItem.bind(
|
||||||
null,
|
null,
|
||||||
this.props.item.id
|
this.props.item.id
|
||||||
) }>
|
) }>
|
||||||
Trash
|
{MailPoet.I18n.t('trash')}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else if (action.refresh) {
|
} else if (action.refresh) {
|
||||||
return (
|
custom_action = (
|
||||||
<span
|
<span
|
||||||
onClick={ this.props.onRefreshItems }
|
onClick={ this.props.onRefreshItems }
|
||||||
key={ 'action-'+index } className={ action.name }>
|
key={ 'action-'+index } className={ action.name }>
|
||||||
{(index > 0) ? ' | ' : ''}
|
{(!is_first) ? ' | ' : ''}
|
||||||
{ action.link(this.props.item) }
|
{ action.link(this.props.item) }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else if (action.link) {
|
} else if (action.link) {
|
||||||
return (
|
custom_action = (
|
||||||
<span
|
<span
|
||||||
key={ 'action-'+index } className={ action.name }>
|
key={ 'action-'+index } className={ action.name }>
|
||||||
{(index > 0) ? ' | ' : ''}
|
{(!is_first) ? ' | ' : ''}
|
||||||
{ action.link(this.props.item) }
|
{ action.link(this.props.item) }
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
custom_action = (
|
||||||
<span
|
<span
|
||||||
key={ 'action-'+index } className={ action.name }>
|
key={ 'action-'+index } className={ action.name }>
|
||||||
{(index > 0) ? ' | ' : ''}
|
{(!is_first) ? ' | ' : ''}
|
||||||
<a href="javascript:;" onClick={
|
<a href="javascript:;" onClick={
|
||||||
(action.onClick !== undefined)
|
(action.onClick !== undefined)
|
||||||
? action.onClick.bind(null,
|
? action.onClick.bind(null,
|
||||||
@ -132,17 +119,25 @@ define(
|
|||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (custom_action !== null && is_first === true) {
|
||||||
|
is_first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return custom_action;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
} else {
|
} else {
|
||||||
item_actions = (
|
item_actions = (
|
||||||
<span className="edit">
|
<span className="edit">
|
||||||
<Link to={ `/edit/${ this.props.item.id }` }>Edit</Link>
|
<Link to={ `/edit/${ this.props.item.id }` }>{MailPoet.I18n.t('edit')}</Link>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let actions;
|
||||||
|
|
||||||
if (this.props.group === 'trash') {
|
if (this.props.group === 'trash') {
|
||||||
var actions = (
|
actions = (
|
||||||
<div>
|
<div>
|
||||||
<div className="row-actions">
|
<div className="row-actions">
|
||||||
<span>
|
<span>
|
||||||
@ -152,7 +147,7 @@ define(
|
|||||||
null,
|
null,
|
||||||
this.props.item.id
|
this.props.item.id
|
||||||
)}
|
)}
|
||||||
>Restore</a>
|
>{MailPoet.I18n.t('restore')}</a>
|
||||||
</span>
|
</span>
|
||||||
{ ' | ' }
|
{ ' | ' }
|
||||||
<span className="delete">
|
<span className="delete">
|
||||||
@ -163,18 +158,18 @@ define(
|
|||||||
null,
|
null,
|
||||||
this.props.item.id
|
this.props.item.id
|
||||||
)}
|
)}
|
||||||
>Delete permanently</a>
|
>{MailPoet.I18n.t('deletePermanently')}</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={ this.handleToggleItem.bind(null, this.props.item.id) }
|
onClick={ this.handleToggleItem.bind(null, this.props.item.id) }
|
||||||
className="toggle-row" type="button">
|
className="toggle-row" type="button">
|
||||||
<span className="screen-reader-text">Show more details</span>
|
<span className="screen-reader-text">{MailPoet.I18n.t('showMoreDetails')}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
var actions = (
|
actions = (
|
||||||
<div>
|
<div>
|
||||||
<div className="row-actions">
|
<div className="row-actions">
|
||||||
{ item_actions }
|
{ item_actions }
|
||||||
@ -182,13 +177,13 @@ define(
|
|||||||
<button
|
<button
|
||||||
onClick={ this.handleToggleItem.bind(null, this.props.item.id) }
|
onClick={ this.handleToggleItem.bind(null, this.props.item.id) }
|
||||||
className="toggle-row" type="button">
|
className="toggle-row" type="button">
|
||||||
<span className="screen-reader-text">Show more details</span>
|
<span className="screen-reader-text">{MailPoet.I18n.t('showMoreDetails')}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var row_classes = classNames({ 'is-expanded': !this.state.toggled })
|
const row_classes = classNames({ 'is-expanded': this.state.expanded });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr className={ row_classes }>
|
<tr className={ row_classes }>
|
||||||
@ -200,7 +195,7 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var ListingItems = React.createClass({
|
const ListingItems = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.props.items.length === 0) {
|
if (this.props.items.length === 0) {
|
||||||
return (
|
return (
|
||||||
@ -214,16 +209,15 @@ define(
|
|||||||
className="colspanchange">
|
className="colspanchange">
|
||||||
{
|
{
|
||||||
(this.props.loading === true)
|
(this.props.loading === true)
|
||||||
? MailPoetI18n.loadingItems
|
? MailPoet.I18n.t('loadingItems')
|
||||||
: MailPoetI18n.noItemsFound
|
: MailPoet.I18n.t('noItemsFound')
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
const select_all_classes = classNames(
|
||||||
var selectAllClasses = classNames(
|
|
||||||
'mailpoet_select_all',
|
'mailpoet_select_all',
|
||||||
{ 'mailpoet_hidden': (
|
{ 'mailpoet_hidden': (
|
||||||
this.props.selection === false
|
this.props.selection === false
|
||||||
@ -234,15 +228,15 @@ define(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr className={ selectAllClasses }>
|
<tr className={ select_all_classes }>
|
||||||
<td colSpan={
|
<td colSpan={
|
||||||
this.props.columns.length
|
this.props.columns.length
|
||||||
+ (this.props.is_selectable ? 1 : 0)
|
+ (this.props.is_selectable ? 1 : 0)
|
||||||
}>
|
}>
|
||||||
{
|
{
|
||||||
(this.props.selection !== 'all')
|
(this.props.selection !== 'all')
|
||||||
? MailPoetI18n.selectAllLabel
|
? MailPoet.I18n.t('selectAllLabel')
|
||||||
: MailPoetI18n.selectedAllLabel.replace(
|
: MailPoet.I18n.t('selectedAllLabel').replace(
|
||||||
'%d',
|
'%d',
|
||||||
this.props.count
|
this.props.count
|
||||||
)
|
)
|
||||||
@ -252,8 +246,8 @@ define(
|
|||||||
onClick={ this.props.onSelectAll }
|
onClick={ this.props.onSelectAll }
|
||||||
href="javascript:;">{
|
href="javascript:;">{
|
||||||
(this.props.selection !== 'all')
|
(this.props.selection !== 'all')
|
||||||
? MailPoetI18n.selectAllLink
|
? MailPoet.I18n.t('selectAllLink')
|
||||||
: MailPoetI18n.clearSelection
|
: MailPoet.I18n.t('clearSelection')
|
||||||
}</a>
|
}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -285,10 +279,10 @@ define(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var Listing = React.createClass({
|
const Listing = React.createClass({
|
||||||
mixins: [
|
contextTypes: {
|
||||||
Router.History
|
router: React.PropTypes.object.isRequired
|
||||||
],
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -296,8 +290,8 @@ define(
|
|||||||
page: 1,
|
page: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
sort_by: 'id',
|
sort_by: null,
|
||||||
sort_order: 'desc',
|
sort_order: null,
|
||||||
items: [],
|
items: [],
|
||||||
groups: [],
|
groups: [],
|
||||||
group: 'all',
|
group: 'all',
|
||||||
@ -307,58 +301,67 @@ define(
|
|||||||
selection: false
|
selection: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
componentDidUpdate: function(prevProps, prevState) {
|
|
||||||
// reset group to "all" if trash gets emptied
|
|
||||||
if(
|
|
||||||
// we were viewing the trash
|
|
||||||
(prevState.group === 'trash' && prevState.count > 0)
|
|
||||||
&&
|
|
||||||
// we are still viewing the trash but there are no items left
|
|
||||||
(this.state.group === 'trash' && this.state.count === 0)
|
|
||||||
&&
|
|
||||||
// only do this when no filter is set
|
|
||||||
(Object.keys(this.state.filter).length === 0)
|
|
||||||
) {
|
|
||||||
this.handleGroup('all');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getParam: function(param) {
|
getParam: function(param) {
|
||||||
var regex = /(.*)\[(.*)\]/
|
const regex = /(.*)\[(.*)\]/;
|
||||||
var matches = regex.exec(param)
|
const matches = regex.exec(param);
|
||||||
return [matches[1], matches[2]]
|
return [matches[1], matches[2]];
|
||||||
},
|
},
|
||||||
initWithParams: function(params) {
|
initWithParams: function(params) {
|
||||||
let state = this.state || {}
|
let state = this.getInitialState();
|
||||||
let original_state = state
|
|
||||||
// check for url params
|
// check for url params
|
||||||
if(params.splat !== undefined) {
|
if (params.splat) {
|
||||||
params.splat.split('/').map(param => {
|
params.splat.split('/').map(param => {
|
||||||
let [key, value] = this.getParam(param);
|
let [key, value] = this.getParam(param);
|
||||||
switch(key) {
|
switch(key) {
|
||||||
case 'filter':
|
case 'filter':
|
||||||
let filters = {}
|
let filters = {};
|
||||||
value.split('&').map(function(pair) {
|
value.split('&').map(function(pair) {
|
||||||
let [k, v] = pair.split('=')
|
let [k, v] = pair.split('=')
|
||||||
filters[k] = v
|
filters[k] = v
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
state.filter = filters
|
state.filter = filters;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state[key] = value
|
state[key] = value;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// limit per page
|
||||||
if (this.props.limit !== undefined) {
|
if (this.props.limit !== undefined) {
|
||||||
state.limit = Math.abs(~~this.props.limit);
|
state.limit = Math.abs(~~this.props.limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort by
|
||||||
|
if (state.sort_by === null && this.props.sort_by !== undefined) {
|
||||||
|
state.sort_by = this.props.sort_by;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort order
|
||||||
|
if (state.sort_order === null && this.props.sort_order !== undefined) {
|
||||||
|
state.sort_order = this.props.sort_order;
|
||||||
|
}
|
||||||
|
|
||||||
this.setState(state, function() {
|
this.setState(state, function() {
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
getParams: function() {
|
||||||
|
// get all route parameters (without the "splat")
|
||||||
|
let params = _.omit(this.props.params, 'splat');
|
||||||
|
// TODO:
|
||||||
|
// find a way to set the "type" in the routes definition
|
||||||
|
// so that it appears in `this.props.params`
|
||||||
|
if (this.props.type) {
|
||||||
|
params.type = this.props.type;
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
},
|
||||||
setParams: function() {
|
setParams: function() {
|
||||||
var params = Object.keys(this.state)
|
if (this.props.location) {
|
||||||
|
let params = Object.keys(this.state)
|
||||||
.filter(key => {
|
.filter(key => {
|
||||||
return (
|
return (
|
||||||
[
|
[
|
||||||
@ -372,31 +375,56 @@ define(
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(key => {
|
.map(key => {
|
||||||
let value = this.state[key]
|
let value = this.state[key];
|
||||||
if (value === Object(value)) {
|
if (value === Object(value)) {
|
||||||
value = jQuery.param(value)
|
value = jQuery.param(value)
|
||||||
} else if (value === Boolean(value)) {
|
} else if (value === Boolean(value)) {
|
||||||
value = value.toString()
|
value = value.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(value !== '') {
|
if (value !== '' && value !== null) {
|
||||||
return `${key}[${value}]`
|
return `${key}[${value}]`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(key => { return (key !== undefined) })
|
.filter(key => { return (key !== undefined) })
|
||||||
.join('/');
|
.join('/');
|
||||||
params = '/'+params
|
|
||||||
|
|
||||||
if(this.props.location) {
|
// set url
|
||||||
if(this.props.location.pathname !== params) {
|
let url = this.getUrlWithParams(params);
|
||||||
this.history.pushState(null, `${params}`)
|
|
||||||
|
if (this.props.location.pathname !== url) {
|
||||||
|
this.context.router.push(`${url}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getUrlWithParams: function(params) {
|
||||||
|
let base_url = (this.props.base_url !== undefined)
|
||||||
|
? this.props.base_url
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (base_url !== null) {
|
||||||
|
base_url = this.setBaseUrlParams(base_url);
|
||||||
|
return `/${ base_url }/${ params }`;
|
||||||
|
} else {
|
||||||
|
return `/${ params }`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setBaseUrlParams: function(base_url) {
|
||||||
|
if (base_url.indexOf(':') !== -1) {
|
||||||
|
const params = this.getParams();
|
||||||
|
Object.keys(params).map((key) => {
|
||||||
|
if (base_url.indexOf(':'+key) !== -1) {
|
||||||
|
base_url = base_url.replace(':'+key, params[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return base_url;
|
||||||
|
},
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
if (this.isMounted()) {
|
if (this.isMounted()) {
|
||||||
const params = this.props.params || {}
|
const params = this.props.params || {};
|
||||||
this.initWithParams(params)
|
this.initWithParams(params);
|
||||||
|
|
||||||
if (this.props.auto_refresh) {
|
if (this.props.auto_refresh) {
|
||||||
jQuery(document).on('heartbeat-tick.mailpoet', function(e, data) {
|
jQuery(document).on('heartbeat-tick.mailpoet', function(e, data) {
|
||||||
@ -406,8 +434,8 @@ define(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentWillReceiveProps: function(nextProps) {
|
componentWillReceiveProps: function(nextProps) {
|
||||||
const params = nextProps.params || {}
|
const params = nextProps.params || {};
|
||||||
this.initWithParams(params)
|
this.initWithParams(params);
|
||||||
},
|
},
|
||||||
getItems: function() {
|
getItems: function() {
|
||||||
if (this.isMounted()) {
|
if (this.isMounted()) {
|
||||||
@ -419,6 +447,7 @@ define(
|
|||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'listing',
|
action: 'listing',
|
||||||
data: {
|
data: {
|
||||||
|
params: this.getParams(),
|
||||||
offset: (this.state.page - 1) * this.state.limit,
|
offset: (this.state.page - 1) * this.state.limit,
|
||||||
limit: this.state.limit,
|
limit: this.state.limit,
|
||||||
group: this.state.group,
|
group: this.state.group,
|
||||||
@ -427,21 +456,29 @@ define(
|
|||||||
sort_by: this.state.sort_by,
|
sort_by: this.state.sort_by,
|
||||||
sort_order: this.state.sort_order
|
sort_order: this.state.sort_order
|
||||||
}
|
}
|
||||||
}).done(function(response) {
|
}).always(() => {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
}).done((response) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
items: response.items || [],
|
items: response.data || [],
|
||||||
filters: response.filters || {},
|
filters: response.meta.filters || {},
|
||||||
groups: response.groups || [],
|
groups: response.meta.groups || [],
|
||||||
count: response.count || 0,
|
count: response.meta.count || 0
|
||||||
loading: false
|
}, () => {
|
||||||
}, function() {
|
// if viewing an empty trash
|
||||||
if(this.props['onGetItems'] !== undefined) {
|
if (this.state.group === 'trash' && response.meta.count === 0) {
|
||||||
this.props.onGetItems(
|
// redirect to default group
|
||||||
~~(this.state.groups[0]['count'])
|
this.handleGroup('all');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).fail(function(response) {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
}.bind(this));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleRestoreItem: function(id) {
|
handleRestoreItem: function(id) {
|
||||||
@ -453,8 +490,10 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'restore',
|
action: 'restore',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
if (
|
if (
|
||||||
this.props.messages !== undefined
|
this.props.messages !== undefined
|
||||||
&& this.props.messages['onRestore'] !== undefined
|
&& this.props.messages['onRestore'] !== undefined
|
||||||
@ -462,7 +501,12 @@ define(
|
|||||||
this.props.messages.onRestore(response);
|
this.props.messages.onRestore(response);
|
||||||
}
|
}
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleTrashItem: function(id) {
|
handleTrashItem: function(id) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -473,8 +517,10 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'trash',
|
action: 'trash',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
if (
|
if (
|
||||||
this.props.messages !== undefined
|
this.props.messages !== undefined
|
||||||
&& this.props.messages['onTrash'] !== undefined
|
&& this.props.messages['onTrash'] !== undefined
|
||||||
@ -482,7 +528,12 @@ define(
|
|||||||
this.props.messages.onTrash(response);
|
this.props.messages.onTrash(response);
|
||||||
}
|
}
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleDeleteItem: function(id) {
|
handleDeleteItem: function(id) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -493,8 +544,10 @@ define(
|
|||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'delete',
|
action: 'delete',
|
||||||
data: id
|
data: {
|
||||||
}).done(function(response) {
|
id: id
|
||||||
|
}
|
||||||
|
}).done((response) => {
|
||||||
if (
|
if (
|
||||||
this.props.messages !== undefined
|
this.props.messages !== undefined
|
||||||
&& this.props.messages['onDelete'] !== undefined
|
&& this.props.messages['onDelete'] !== undefined
|
||||||
@ -502,36 +555,61 @@ define(
|
|||||||
this.props.messages.onDelete(response);
|
this.props.messages.onDelete(response);
|
||||||
}
|
}
|
||||||
this.getItems();
|
this.getItems();
|
||||||
}.bind(this));
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
handleBulkAction: function(selected_ids, params, callback) {
|
handleEmptyTrash: function() {
|
||||||
|
return this.handleBulkAction('all', {
|
||||||
|
action: 'delete',
|
||||||
|
group: 'trash'
|
||||||
|
}).done((response) => {
|
||||||
|
MailPoet.Notice.success(
|
||||||
|
MailPoet.I18n.t('permanentlyDeleted').replace('%d', response.meta.count)
|
||||||
|
);
|
||||||
|
// redirect to default group
|
||||||
|
this.handleGroup('all');
|
||||||
|
}).fail((response) => {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map(function(error) { return error.message; }),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleBulkAction: function(selected_ids, params) {
|
||||||
if (
|
if (
|
||||||
this.state.selection === false
|
this.state.selection === false
|
||||||
&& this.state.selected_ids.length === 0
|
&& this.state.selected_ids.length === 0
|
||||||
|
&& selected_ids !== 'all'
|
||||||
) {
|
) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
|
|
||||||
var data = params || {};
|
var data = params || {};
|
||||||
data.listing = {
|
data.listing = {
|
||||||
|
params: this.getParams(),
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 0,
|
limit: 0,
|
||||||
filter: this.state.filter,
|
filter: this.state.filter,
|
||||||
group: this.state.group,
|
group: this.state.group,
|
||||||
search: this.state.search,
|
search: this.state.search
|
||||||
selection: selected_ids
|
}
|
||||||
|
if (selected_ids !== 'all') {
|
||||||
|
data.listing.selection = selected_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
MailPoet.Ajax.post({
|
return MailPoet.Ajax.post({
|
||||||
endpoint: this.props.endpoint,
|
endpoint: this.props.endpoint,
|
||||||
action: 'bulkAction',
|
action: 'bulkAction',
|
||||||
data: data
|
data: data
|
||||||
}).done(function(response) {
|
}).done(() => {
|
||||||
this.getItems();
|
this.getItems();
|
||||||
callback(response);
|
});
|
||||||
}.bind(this));
|
|
||||||
},
|
},
|
||||||
handleSearch: function(search) {
|
handleSearch: function(search) {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -541,16 +619,14 @@ define(
|
|||||||
selected_ids: []
|
selected_ids: []
|
||||||
}, function() {
|
}, function() {
|
||||||
this.setParams();
|
this.setParams();
|
||||||
this.getItems();
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
handleSort: function(sort_by, sort_order = 'asc') {
|
handleSort: function(sort_by, sort_order = 'asc') {
|
||||||
this.setState({
|
this.setState({
|
||||||
sort_by: sort_by,
|
sort_by: sort_by,
|
||||||
sort_order: sort_order,
|
sort_order: (sort_order === 'asc') ? 'asc' : 'desc',
|
||||||
}, function() {
|
}, function() {
|
||||||
this.setParams();
|
this.setParams();
|
||||||
this.getItems();
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
handleSelectItem: function(id, is_checked) {
|
handleSelectItem: function(id, is_checked) {
|
||||||
@ -610,7 +686,6 @@ define(
|
|||||||
page: 1
|
page: 1
|
||||||
}, function() {
|
}, function() {
|
||||||
this.setParams();
|
this.setParams();
|
||||||
this.getItems();
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
handleGroup: function(group) {
|
handleGroup: function(group) {
|
||||||
@ -624,7 +699,6 @@ define(
|
|||||||
page: 1
|
page: 1
|
||||||
}, function() {
|
}, function() {
|
||||||
this.setParams();
|
this.setParams();
|
||||||
this.getItems();
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
handleSetPage: function(page) {
|
handleSetPage: function(page) {
|
||||||
@ -634,43 +708,48 @@ define(
|
|||||||
selected_ids: []
|
selected_ids: []
|
||||||
}, function() {
|
}, function() {
|
||||||
this.setParams();
|
this.setParams();
|
||||||
this.getItems();
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
handleRenderItem: function(item, actions) {
|
handleRenderItem: function(item, actions) {
|
||||||
var render = this.props.onRenderItem(item, actions);
|
const render = this.props.onRenderItem(item, actions);
|
||||||
return render.props.children;
|
return render.props.children;
|
||||||
},
|
},
|
||||||
handleRefreshItems: function() {
|
handleRefreshItems: function() {
|
||||||
this.getItems();
|
this.getItems();
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var items = this.state.items,
|
const items = this.state.items;
|
||||||
sort_by = this.state.sort_by,
|
const sort_by = this.state.sort_by;
|
||||||
sort_order = this.state.sort_order;
|
const sort_order = this.state.sort_order;
|
||||||
|
|
||||||
|
// columns
|
||||||
|
let columns = this.props.columns || [];
|
||||||
|
columns = columns.filter(function(column) {
|
||||||
|
return (column.display === undefined || !!(column.display) === true);
|
||||||
|
});
|
||||||
|
|
||||||
// bulk actions
|
// bulk actions
|
||||||
var bulk_actions = this.props.bulk_actions || [];
|
let bulk_actions = this.props.bulk_actions || [];
|
||||||
|
|
||||||
if (this.state.group === 'trash' && bulk_actions.length > 0) {
|
if (this.state.group === 'trash' && bulk_actions.length > 0) {
|
||||||
bulk_actions = [
|
bulk_actions = [
|
||||||
{
|
{
|
||||||
name: 'restore',
|
name: 'restore',
|
||||||
label: 'Restore',
|
label: MailPoet.I18n.t('restore'),
|
||||||
onSuccess: this.props.messages.onRestore
|
onSuccess: this.props.messages.onRestore
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'delete',
|
name: 'delete',
|
||||||
label: 'Delete permanently',
|
label: MailPoet.I18n.t('deletePermanently'),
|
||||||
onSuccess: this.props.messages.onDelete
|
onSuccess: this.props.messages.onDelete
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// item actions
|
// item actions
|
||||||
var item_actions = this.props.item_actions || [];
|
const item_actions = this.props.item_actions || [];
|
||||||
|
|
||||||
var table_classes = classNames(
|
const table_classes = classNames(
|
||||||
'mailpoet_listing_table',
|
'mailpoet_listing_table',
|
||||||
'wp-list-table',
|
'wp-list-table',
|
||||||
'widefat',
|
'widefat',
|
||||||
@ -680,7 +759,7 @@ define(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// search
|
// search
|
||||||
var search = (
|
let search = (
|
||||||
<ListingSearch
|
<ListingSearch
|
||||||
onSearch={ this.handleSearch }
|
onSearch={ this.handleSearch }
|
||||||
search={ this.state.search }
|
search={ this.state.search }
|
||||||
@ -691,7 +770,7 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// groups
|
// groups
|
||||||
var groups = (
|
let groups = (
|
||||||
<ListingGroups
|
<ListingGroups
|
||||||
groups={ this.state.groups }
|
groups={ this.state.groups }
|
||||||
group={ this.state.group }
|
group={ this.state.group }
|
||||||
@ -708,6 +787,7 @@ define(
|
|||||||
{ search }
|
{ search }
|
||||||
<div className="tablenav top clearfix">
|
<div className="tablenav top clearfix">
|
||||||
<ListingBulkActions
|
<ListingBulkActions
|
||||||
|
count={ this.state.count }
|
||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
selection={ this.state.selection }
|
selection={ this.state.selection }
|
||||||
selected_ids={ this.state.selected_ids }
|
selected_ids={ this.state.selected_ids }
|
||||||
@ -715,7 +795,10 @@ define(
|
|||||||
<ListingFilters
|
<ListingFilters
|
||||||
filters={ this.state.filters }
|
filters={ this.state.filters }
|
||||||
filter={ this.state.filter }
|
filter={ this.state.filter }
|
||||||
onSelectFilter={ this.handleFilter } />
|
group={ this.state.group }
|
||||||
|
onSelectFilter={ this.handleFilter }
|
||||||
|
onEmptyTrash={ this.handleEmptyTrash }
|
||||||
|
/>
|
||||||
<ListingPages
|
<ListingPages
|
||||||
count={ this.state.count }
|
count={ this.state.count }
|
||||||
page={ this.state.page }
|
page={ this.state.page }
|
||||||
@ -728,9 +811,9 @@ define(
|
|||||||
onSort={ this.handleSort }
|
onSort={ this.handleSort }
|
||||||
onSelectItems={ this.handleSelectItems }
|
onSelectItems={ this.handleSelectItems }
|
||||||
selection={ this.state.selection }
|
selection={ this.state.selection }
|
||||||
sort_by={ this.state.sort_by }
|
sort_by={ sort_by }
|
||||||
sort_order={ this.state.sort_order }
|
sort_order={ sort_order }
|
||||||
columns={ this.props.columns }
|
columns={ columns }
|
||||||
is_selectable={ bulk_actions.length > 0 } />
|
is_selectable={ bulk_actions.length > 0 } />
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
@ -740,7 +823,7 @@ define(
|
|||||||
onRestoreItem={ this.handleRestoreItem }
|
onRestoreItem={ this.handleRestoreItem }
|
||||||
onTrashItem={ this.handleTrashItem }
|
onTrashItem={ this.handleTrashItem }
|
||||||
onRefreshItems={ this.handleRefreshItems }
|
onRefreshItems={ this.handleRefreshItems }
|
||||||
columns={ this.props.columns }
|
columns={ columns }
|
||||||
is_selectable={ bulk_actions.length > 0 }
|
is_selectable={ bulk_actions.length > 0 }
|
||||||
onSelectItem={ this.handleSelectItem }
|
onSelectItem={ this.handleSelectItem }
|
||||||
onSelectAll={ this.handleSelectAll }
|
onSelectAll={ this.handleSelectAll }
|
||||||
@ -758,15 +841,16 @@ define(
|
|||||||
onSort={ this.handleSort }
|
onSort={ this.handleSort }
|
||||||
onSelectItems={ this.handleSelectItems }
|
onSelectItems={ this.handleSelectItems }
|
||||||
selection={ this.state.selection }
|
selection={ this.state.selection }
|
||||||
sort_by={ this.state.sort_by }
|
sort_by={ sort_by }
|
||||||
sort_order={ this.state.sort_order }
|
sort_order={ sort_order }
|
||||||
columns={ this.props.columns }
|
columns={ columns }
|
||||||
is_selectable={ bulk_actions.length > 0 } />
|
is_selectable={ bulk_actions.length > 0 } />
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<div className="tablenav bottom">
|
<div className="tablenav bottom">
|
||||||
<ListingBulkActions
|
<ListingBulkActions
|
||||||
|
count={ this.state.count }
|
||||||
bulk_actions={ bulk_actions }
|
bulk_actions={ bulk_actions }
|
||||||
selection={ this.state.selection }
|
selection={ this.state.selection }
|
||||||
selected_ids={ this.state.selected_ids }
|
selected_ids={ this.state.selected_ids }
|
||||||
@ -782,6 +866,4 @@ define(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return Listing;
|
module.exports = Listing;
|
||||||
}
|
|
||||||
);
|
|
@ -1,4 +1,12 @@
|
|||||||
define(['react', 'classnames'], function(React, classNames) {
|
define([
|
||||||
|
'react',
|
||||||
|
'classnames',
|
||||||
|
'mailpoet'
|
||||||
|
], function(
|
||||||
|
React,
|
||||||
|
classNames,
|
||||||
|
MailPoet
|
||||||
|
) {
|
||||||
|
|
||||||
var ListingPages = React.createClass({
|
var ListingPages = React.createClass({
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
@ -7,7 +15,11 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setPage: function(page) {
|
setPage: function(page) {
|
||||||
this.props.onSetPage(page);
|
this.setState({
|
||||||
|
page: null
|
||||||
|
}, function () {
|
||||||
|
this.props.onSetPage(this.constrainPage(page));
|
||||||
|
}.bind(this));
|
||||||
},
|
},
|
||||||
setFirstPage: function() {
|
setFirstPage: function() {
|
||||||
this.setPage(1);
|
this.setPage(1);
|
||||||
@ -16,10 +28,14 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
this.setPage(this.getLastPage());
|
this.setPage(this.getLastPage());
|
||||||
},
|
},
|
||||||
setPreviousPage: function() {
|
setPreviousPage: function() {
|
||||||
this.setPage(this.constrainPage(this.props.page - 1));
|
this.setPage(this.constrainPage(
|
||||||
|
parseInt(this.props.page, 10) - 1)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
setNextPage: function() {
|
setNextPage: function() {
|
||||||
this.setPage(this.constrainPage(this.props.page + 1));
|
this.setPage(this.constrainPage(
|
||||||
|
parseInt(this.props.page, 10) + 1)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
constrainPage: function(page) {
|
constrainPage: function(page) {
|
||||||
return Math.min(Math.max(1, Math.abs(~~page)), this.getLastPage());
|
return Math.min(Math.max(1, Math.abs(~~page)), this.getLastPage());
|
||||||
@ -27,14 +43,16 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
handleSetManualPage: function(e) {
|
handleSetManualPage: function(e) {
|
||||||
if(e.which === 13) {
|
if(e.which === 13) {
|
||||||
this.setPage(this.state.page);
|
this.setPage(this.state.page);
|
||||||
this.setState({ page: null });
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleChangeManualPage: function(e) {
|
handleChangeManualPage: function(e) {
|
||||||
this.setState({
|
this.setState({
|
||||||
page: this.constrainPage(e.target.value)
|
page: e.target.value
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleBlurManualPage: function(e) {
|
||||||
|
this.setPage(e.target.value);
|
||||||
|
},
|
||||||
getLastPage: function() {
|
getLastPage: function() {
|
||||||
return Math.ceil(this.props.count / this.props.limit);
|
return Math.ceil(this.props.count / this.props.limit);
|
||||||
},
|
},
|
||||||
@ -62,7 +80,7 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
<a href="javascript:;"
|
<a href="javascript:;"
|
||||||
onClick={ this.setPreviousPage }
|
onClick={ this.setPreviousPage }
|
||||||
className="prev-page">
|
className="prev-page">
|
||||||
<span className="screen-reader-text">Previous page</span>
|
<span className="screen-reader-text">{MailPoet.I18n.t('previousPage')}</span>
|
||||||
<span aria-hidden="true">‹</span>
|
<span aria-hidden="true">‹</span>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
@ -73,7 +91,7 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
<a href="javascript:;"
|
<a href="javascript:;"
|
||||||
onClick={ this.setFirstPage }
|
onClick={ this.setFirstPage }
|
||||||
className="first-page">
|
className="first-page">
|
||||||
<span className="screen-reader-text">First page</span>
|
<span className="screen-reader-text">{MailPoet.I18n.t('firstPage')}</span>
|
||||||
<span aria-hidden="true">«</span>
|
<span aria-hidden="true">«</span>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
@ -84,7 +102,7 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
<a href="javascript:;"
|
<a href="javascript:;"
|
||||||
onClick={ this.setNextPage }
|
onClick={ this.setNextPage }
|
||||||
className="next-page">
|
className="next-page">
|
||||||
<span className="screen-reader-text">Next page</span>
|
<span className="screen-reader-text">{MailPoet.I18n.t('nextPage')}</span>
|
||||||
<span aria-hidden="true">›</span>
|
<span aria-hidden="true">›</span>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
@ -95,12 +113,17 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
<a href="javascript:;"
|
<a href="javascript:;"
|
||||||
onClick={ this.setLastPage }
|
onClick={ this.setLastPage }
|
||||||
className="last-page">
|
className="last-page">
|
||||||
<span className="screen-reader-text">Last page</span>
|
<span className="screen-reader-text">{MailPoet.I18n.t('lastPage')}</span>
|
||||||
<span aria-hidden="true">»</span>
|
<span aria-hidden="true">»</span>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pageValue = this.props.page;
|
||||||
|
if(this.state.page !== null) {
|
||||||
|
pageValue = this.state.page;
|
||||||
|
}
|
||||||
|
|
||||||
pagination = (
|
pagination = (
|
||||||
<span className="pagination-links">
|
<span className="pagination-links">
|
||||||
{firstPage}
|
{firstPage}
|
||||||
@ -110,21 +133,22 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
<span className="paging-input">
|
<span className="paging-input">
|
||||||
<label
|
<label
|
||||||
className="screen-reader-text"
|
className="screen-reader-text"
|
||||||
htmlFor="current-page-selector">Current Page</label>
|
htmlFor="current-page-selector">{MailPoet.I18n.t('currentPage')}</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
onChange={ this.handleChangeManualPage }
|
onChange={ this.handleChangeManualPage }
|
||||||
onKeyUp={ this.handleSetManualPage }
|
onKeyUp={ this.handleSetManualPage }
|
||||||
|
onBlur={ this.handleBlurManualPage }
|
||||||
aria-describedby="table-paging"
|
aria-describedby="table-paging"
|
||||||
size="1"
|
size="2"
|
||||||
ref="page"
|
ref="page"
|
||||||
value={ this.state.page || this.props.page }
|
value={ pageValue }
|
||||||
name="paged"
|
name="paged"
|
||||||
id="current-page-selector"
|
id="current-page-selector"
|
||||||
className="current-page" />
|
className="current-page" />
|
||||||
of
|
{MailPoet.I18n.t('pageOutOf')}
|
||||||
<span className="total-pages">
|
<span className="total-pages">
|
||||||
{Math.ceil(this.props.count / this.props.limit)}
|
{Math.ceil(this.props.count / this.props.limit).toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -142,7 +166,9 @@ define(['react', 'classnames'], function(React, classNames) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ classes }>
|
<div className={ classes }>
|
||||||
<span className="displaying-num">{ this.props.count } items</span>
|
<span className="displaying-num">{
|
||||||
|
MailPoet.I18n.t('numberOfItems').replace('%$1d', this.props.count.toLocaleString())
|
||||||
|
}</span>
|
||||||
{ pagination }
|
{ pagination }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|