Compare commits
1211
Commits
work
..
0.7-stable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76bcbce2ef | ||
|
|
7da7e853a3 | ||
|
|
6ae66f4dbf | ||
|
|
a98d4de1e3 | ||
|
|
5e4d66ad50 | ||
|
|
982d6bc748 | ||
|
|
3169291039 | ||
|
|
de86f4b965 | ||
|
|
bf45264131 | ||
|
|
1602fd0dfd | ||
|
|
12c4119abd | ||
|
|
f3a52d2e98 | ||
|
|
ba1af78dc8 | ||
|
|
59427dcfbf | ||
|
|
50755b5913 | ||
|
|
5b0051e710 | ||
|
|
8af523c694 | ||
|
|
2f84506227 | ||
|
|
6e7012c40f | ||
|
|
dfcd0f15ae | ||
|
|
8bfe71e803 | ||
|
|
1c1c9fa517 | ||
|
|
a55317f09c | ||
|
|
fcc5d2847c | ||
|
|
e5b3c31e70 | ||
|
|
2af910e8e6 | ||
|
|
9c5ec2974d | ||
|
|
6f6f1f1ba3 | ||
|
|
3f62305e91 | ||
|
|
15ecbbf928 | ||
|
|
2074f0ab41 | ||
|
|
290bd1756d | ||
|
|
729d1176ea | ||
|
|
c0db7007fa | ||
|
|
d7e3c4df26 | ||
|
|
76ec11422d | ||
|
|
8bc721c264 | ||
|
|
914d1e6645 | ||
|
|
5f346bbf2b | ||
|
|
10191813ec | ||
|
|
be071deae2 | ||
|
|
a381b0978f | ||
|
|
0dfa2ad3cf | ||
|
|
1bb51f743a | ||
|
|
85858cebe6 | ||
|
|
6331809bd9 | ||
|
|
b9e380c9fe | ||
|
|
8960200409 | ||
|
|
ef80597c39 | ||
|
|
ecc742f3ce | ||
|
|
7a434c902a | ||
|
|
d37a30846f | ||
|
|
805864590a | ||
|
|
1c49bd4258 | ||
|
|
051875429e | ||
|
|
6936eb1022 | ||
|
|
de5b0ad0a8 | ||
|
|
472654aebe | ||
|
|
5f78b8a9a0 | ||
|
|
7fb72e671b | ||
|
|
180fe8f6a4 | ||
|
|
60c12ca3ab | ||
|
|
a8e6f68aaf | ||
|
|
27cf6d8d64 | ||
|
|
09bf503fd2 | ||
|
|
35a14cbfdc | ||
|
|
bbf422e229 | ||
|
|
8ed97f43d2 | ||
|
|
4ff77cc624 | ||
|
|
0cccce0c43 | ||
|
|
43fc812e0e | ||
|
|
f162337e1b | ||
|
|
93a33c6286 | ||
|
|
3e102f281d | ||
|
|
7673d69b96 | ||
|
|
1c4bcc5b55 | ||
|
|
8cb5acf453 | ||
|
|
030afe7428 | ||
|
|
93d1b2e0a4 | ||
|
|
cab300e650 | ||
|
|
f271e772af | ||
|
|
4bd35dae8d | ||
|
|
2d01398d67 | ||
|
|
f5b5688e8a | ||
|
|
2eb085506b | ||
|
|
a8fcf8487d | ||
|
|
5b6978a1f3 | ||
|
|
888b254844 | ||
|
|
83061e9ca2 | ||
|
|
451aa6ba4e | ||
|
|
01fdaf5977 | ||
|
|
a59e6bfb02 | ||
|
|
185ecd5854 | ||
|
|
aec989707e | ||
|
|
993b60d61e | ||
|
|
4957752d12 | ||
|
|
b8b991a7dc | ||
|
|
cdf3e2b6ef | ||
|
|
84d2ea054d | ||
|
|
076d9e7ade | ||
|
|
c67c375357 | ||
|
|
87fb78be0b | ||
|
|
eafaae73b7 | ||
|
|
4f16dc53a4 | ||
|
|
ea161c9ea4 | ||
|
|
2c1e63720e | ||
|
|
d4429a544c | ||
|
|
3a9b0988c7 | ||
|
|
6fcc512cb7 | ||
|
|
3a75b6771f | ||
|
|
a9c972fbb3 | ||
|
|
71d3bb2f7b | ||
|
|
624723d0ce | ||
|
|
64fb0a561a | ||
|
|
76a29ae337 | ||
|
|
4f35ec97e8 | ||
|
|
8195f95464 | ||
|
|
494a6ecfb0 | ||
|
|
66594d46b2 | ||
|
|
0ec13848b0 | ||
|
|
a92cce3851 | ||
|
|
522b9e6b5b | ||
|
|
07882590bb | ||
|
|
9b59ea7256 | ||
|
|
1830064918 | ||
|
|
a4c6c62c8b | ||
|
|
4458a7282b | ||
|
|
e8035c22b2 | ||
|
|
482d9a4e82 | ||
|
|
533994e5ea | ||
|
|
e951d84584 | ||
|
|
bbe8ea29e8 | ||
|
|
fbcdfee622 | ||
|
|
a70737ad59 | ||
|
|
745fec76d0 | ||
|
|
1eca3947a1 | ||
|
|
d09f7d73b3 | ||
|
|
c61424e57a | ||
|
|
b0754ca720 | ||
|
|
4f9f3097d9 | ||
|
|
d8c97b32dd | ||
|
|
918937c873 | ||
|
|
942091f9e8 | ||
|
|
8ea2ecb983 | ||
|
|
7ee55562ff | ||
|
|
c01c64e978 | ||
|
|
87742f23ed | ||
|
|
9daf39ec52 | ||
|
|
4b15dc10c1 | ||
|
|
b6bd5c7f12 | ||
|
|
1ddb59df2a | ||
|
|
200842ba5e | ||
|
|
421d420311 | ||
|
|
8531e176aa | ||
|
|
328df74dd1 | ||
|
|
792b7f30e3 | ||
|
|
b0bb41ad35 | ||
|
|
b935aebd99 | ||
|
|
ade572048a | ||
|
|
7d10755072 | ||
|
|
3f4a8469ac | ||
|
|
d461363d27 | ||
|
|
948097bc4d | ||
|
|
09bd61da74 | ||
|
|
652dc1a73a | ||
|
|
e5daf25618 | ||
|
|
5d6d0136c1 | ||
|
|
d69a05a6ee | ||
|
|
33493f8010 | ||
|
|
a798a1ac4d | ||
|
|
53a04b0a44 | ||
|
|
0153954ebb | ||
|
|
153c4c242d | ||
|
|
0582337372 | ||
|
|
1c8cf4ef83 | ||
|
|
abb0b15407 | ||
|
|
384a444cee | ||
|
|
38307c0979 | ||
|
|
96b78fdae5 | ||
|
|
377a45ae1a | ||
|
|
29e297d273 | ||
|
|
71d089c833 | ||
|
|
8adb320978 | ||
|
|
0b6a010a12 | ||
|
|
4dc7f662e3 | ||
|
|
a2626bbccf | ||
|
|
616899d879 | ||
|
|
30a7314b86 | ||
|
|
c5d998528f | ||
|
|
93ef8b7f77 | ||
|
|
15ed53cf17 | ||
|
|
5152771fdd | ||
|
|
913a806f90 | ||
|
|
d859d38dd9 | ||
|
|
14b3d6d012 | ||
|
|
4155c97222 | ||
|
|
43a6f312ed | ||
|
|
6d109258c9 | ||
|
|
9a2ec76a81 | ||
|
|
c80c1e1ead | ||
|
|
943ba3e34f | ||
|
|
68d3305ae2 | ||
|
|
fde2a497da | ||
|
|
14b2d3f4b9 | ||
|
|
54ff294da1 | ||
|
|
80a60247f5 | ||
|
|
a3dda6dc4a | ||
|
|
4e244be21c | ||
|
|
09cfef094c | ||
|
|
9c451ac157 | ||
|
|
5dd3c239d3 | ||
|
|
0beafecd3b | ||
|
|
2920daf2c8 | ||
|
|
c3d909e0cc | ||
|
|
1ecef3a95a | ||
|
|
b124501a4e | ||
|
|
225637c5dc | ||
|
|
0123dc3651 | ||
|
|
12c0f5f66e | ||
|
|
45b69c4a65 | ||
|
|
bea49ae245 | ||
|
|
4abb82fd7b | ||
|
|
79f92a675a | ||
|
|
3d5d1a38e3 | ||
|
|
e13f49d919 | ||
|
|
7a1e928b8d | ||
|
|
b0f3de5c3b | ||
|
|
2247700f24 | ||
|
|
d8ac6d2b79 | ||
|
|
2d9e669e85 | ||
|
|
d54ba39e7a | ||
|
|
91dc13f4b2 | ||
|
|
97e7432ce6 | ||
|
|
dad5f6d403 | ||
|
|
c65ab7c0f2 | ||
|
|
d6bfb7fa4d | ||
|
|
59c5d995c3 | ||
|
|
df99d8f308 | ||
|
|
d5b9dedca2 | ||
|
|
0b4a02f607 | ||
|
|
b6549d763a | ||
|
|
5e2a01656d | ||
|
|
d79c20c4f2 | ||
|
|
889bf388be | ||
|
|
16e9ffce0d | ||
|
|
44ac1a0deb | ||
|
|
1b002983c3 | ||
|
|
1535ac1220 | ||
|
|
2a945f794f | ||
|
|
0faa4568a0 | ||
|
|
3e031b4243 | ||
|
|
32b9bf0ef2 | ||
|
|
1c5a9b1773 | ||
|
|
061977d77d | ||
|
|
049051103b | ||
|
|
18066ba8bf | ||
|
|
ad25d15d6c | ||
|
|
e228110614 | ||
|
|
8a39862b19 | ||
|
|
bf3066d698 | ||
|
|
35c17355fb | ||
|
|
702b521b45 | ||
|
|
4e1e5985a1 | ||
|
|
8b710cf9de | ||
|
|
df30e18a8c | ||
|
|
64eaf328ea | ||
|
|
941f9bf3dd | ||
|
|
a39f655a7c | ||
|
|
84cdc8f2bc | ||
|
|
b2b56adbfa | ||
|
|
a80dbc49b1 | ||
|
|
78d9ae9754 | ||
|
|
3d920c13b4 | ||
|
|
976a31e941 | ||
|
|
4a729036bf | ||
|
|
c9fd7513ed | ||
|
|
8d9b04865b | ||
|
|
4024f4ac39 | ||
|
|
6ae87d7c4c | ||
|
|
860ff9345f | ||
|
|
bd85c0cbb1 | ||
|
|
832c7eaaa5 | ||
|
|
b21e85b6dc | ||
|
|
3e0acc0b7e | ||
|
|
636579b17d | ||
|
|
97f0da0b1a | ||
|
|
9072753489 | ||
|
|
66420fe4b7 | ||
|
|
5bc7dc77e2 | ||
|
|
9a1b46fe42 | ||
|
|
7eec539222 | ||
|
|
7f3c516940 | ||
|
|
3ff95e4031 | ||
|
|
bb8d360188 | ||
|
|
9595029709 | ||
|
|
31c6ebb310 | ||
|
|
3d5381b24b | ||
|
|
a456225852 | ||
|
|
5f871e9657 | ||
|
|
bf3b2ec973 | ||
|
|
49bdf62243 | ||
|
|
e219af1fbd | ||
|
|
4a2efa9252 | ||
|
|
8e00f57a88 | ||
|
|
524cd689cf | ||
|
|
b4eafd9ea8 | ||
|
|
2bcd448dda | ||
|
|
1af9c47a27 | ||
|
|
ea35fff5bf | ||
|
|
124ef65c1f | ||
|
|
361c50c1f4 | ||
|
|
27d6334afa | ||
|
|
963b1283c2 | ||
|
|
777edc13c1 | ||
|
|
d1a3fbea40 | ||
|
|
58610ec52a | ||
|
|
38b185f1dc | ||
|
|
e69631f26c | ||
|
|
47f399104b | ||
|
|
86319feef2 | ||
|
|
eb7cbd481e | ||
|
|
17c7886791 | ||
|
|
48949f979a | ||
|
|
86d756d22d | ||
|
|
ab4ff48abc | ||
|
|
63ef594033 | ||
|
|
bd8eded670 | ||
|
|
d5cc40c9b6 | ||
|
|
76ed8cc200 | ||
|
|
3539bef96b | ||
|
|
e29539df9c | ||
|
|
7e9c454478 | ||
|
|
c00b8fd12e | ||
|
|
6d9490ddcc | ||
|
|
f58db70bde | ||
|
|
51adc242a3 | ||
|
|
7fae4b0892 | ||
|
|
6239e319ac | ||
|
|
60c82a03db | ||
|
|
36c0ab196c | ||
|
|
a7c2b63fb6 | ||
|
|
5e38bd9363 | ||
|
|
a79cf8d574 | ||
|
|
3c44aac1f5 | ||
|
|
355289fa67 | ||
|
|
b536f4c657 | ||
|
|
d00014221e | ||
|
|
3b4cfe0ba8 | ||
|
|
056e3703da | ||
|
|
92a23c05bb | ||
|
|
7d8af70a63 | ||
|
|
8c65cc4712 | ||
|
|
e4724c7626 | ||
|
|
6e74a06808 | ||
|
|
bc060b31ae | ||
|
|
aebcfb1eda | ||
|
|
457c9a8e72 | ||
|
|
3f2f7153a9 | ||
|
|
f5d68cf688 | ||
|
|
81ada666bb | ||
|
|
db002edabd | ||
|
|
3baf086e2d | ||
|
|
2cf11bd64e | ||
|
|
bf6e02c739 | ||
|
|
233990dac3 | ||
|
|
c383486d71 | ||
|
|
508b0bbb8e | ||
|
|
3937caeb3c | ||
|
|
f2a12d9eb5 | ||
|
|
acad206063 | ||
|
|
f80f04e379 | ||
|
|
fde4a42e2a | ||
|
|
29b3614bcb | ||
|
|
866e9e2503 | ||
|
|
c21ee95ade | ||
|
|
7704e2d919 | ||
|
|
0634591b3d | ||
|
|
5e6fa147da | ||
|
|
8d91afc33e | ||
|
|
987a5aa221 | ||
|
|
99f9aea80a | ||
|
|
deb182337d | ||
|
|
a1f3497ec4 | ||
|
|
9c9ae21771 | ||
|
|
f8aa2dc9b7 | ||
|
|
bb2de53d93 | ||
|
|
e2c606e974 | ||
|
|
9ad79612fe | ||
|
|
1469a4c8df | ||
|
|
76cdef46f2 | ||
|
|
e4ce95c3a1 | ||
|
|
4951676172 | ||
|
|
b0a8888e35 | ||
|
|
833c7bd659 | ||
|
|
5944696b6d | ||
|
|
a727f0d25a | ||
|
|
0fe5c7b3e0 | ||
|
|
843d04f0e3 | ||
|
|
8a8f819d27 | ||
|
|
a8419c1425 | ||
|
|
362364fd6f | ||
|
|
b0bb1baeaa | ||
|
|
1454a711ca | ||
|
|
fa95501fe5 | ||
|
|
a069c4afcf | ||
|
|
cc8220dde8 | ||
|
|
63ceea2e21 | ||
|
|
ad68a82be1 | ||
|
|
8509cf80f0 | ||
|
|
26a1ae4808 | ||
|
|
040cfa6ae2 | ||
|
|
d0af24870e | ||
|
|
308118ce97 | ||
|
|
7535c211d5 | ||
|
|
d46e3a501e | ||
|
|
d4e47d5d64 | ||
|
|
11cf016c58 | ||
|
|
bd434427e6 | ||
|
|
4ded4277c5 | ||
|
|
b60bedafc0 | ||
|
|
9a3d743ae5 | ||
|
|
0af6f34758 | ||
|
|
bb4acc02d0 | ||
|
|
d9e6359a83 | ||
|
|
8610b191ae | ||
|
|
01ef9f12c8 | ||
|
|
24ec30b10c | ||
|
|
152a5da64d | ||
|
|
295e8c86ab | ||
|
|
5d1d778ed5 | ||
|
|
8f7f305f7c | ||
|
|
33003e5b2d | ||
|
|
8ca4d35dcc | ||
|
|
b30b6717a2 | ||
|
|
cedca57620 | ||
|
|
0d605006a3 | ||
|
|
a200e97667 | ||
|
|
2ee11c9089 | ||
|
|
01105966d9 | ||
|
|
90d33c3e51 | ||
|
|
eacd050630 | ||
|
|
0e4e0a795a | ||
|
|
ecfc40629f | ||
|
|
0006c5f3b0 | ||
|
|
3c42abe07e | ||
|
|
11cc0a4857 | ||
|
|
11f7a13971 | ||
|
|
d10e9f1157 | ||
|
|
f3eeff03c4 | ||
|
|
49eb65e925 | ||
|
|
4c509c9423 | ||
|
|
9ce5713ee4 | ||
|
|
b9cc65db61 | ||
|
|
74ecb37be6 | ||
|
|
7d54215ccb | ||
|
|
58b67fa914 | ||
|
|
f55a5e4572 | ||
|
|
a53c86f063 | ||
|
|
dead6a28f8 | ||
|
|
0682b8cfc4 | ||
|
|
4b3ff7af50 | ||
|
|
65e05d822a | ||
|
|
bce286f458 | ||
|
|
b950caa21e | ||
|
|
3a0cd55622 | ||
|
|
f7daee47a6 | ||
|
|
7486125e6d | ||
|
|
ff2e031400 | ||
|
|
2ce184d1de | ||
|
|
3844e4bca8 | ||
|
|
38f540a701 | ||
|
|
5f10cc8673 | ||
|
|
45203143c1 | ||
|
|
6b63889fcd | ||
|
|
824a67ab5a | ||
|
|
2c4647f8c6 | ||
|
|
df631e8c06 | ||
|
|
ec51cdd0f9 | ||
|
|
cdb2781b48 | ||
|
|
bb724e75c0 | ||
|
|
5259dec061 | ||
|
|
75c4c4f6b3 | ||
|
|
fa094a3fe5 | ||
|
|
31467731fa | ||
|
|
57d3dd3b80 | ||
|
|
26528d1004 | ||
|
|
df8945177a | ||
|
|
69c2965051 | ||
|
|
e8971e5f83 | ||
|
|
73dba2ac04 | ||
|
|
fd7910efc9 | ||
|
|
185547af69 | ||
|
|
c216ab325b | ||
|
|
479b9b5433 | ||
|
|
f6f1fee92f | ||
|
|
a32d6a49c0 | ||
|
|
586231067b | ||
|
|
cb8bee3a4e | ||
|
|
20b4e226fe | ||
|
|
c3e3a1891b | ||
|
|
47e7ceacd7 | ||
|
|
48fb20f540 | ||
|
|
0fc93a1197 | ||
|
|
0f966dbcfd | ||
|
|
ca094446b3 | ||
|
|
50096526bc | ||
|
|
c6e8cf5c21 | ||
|
|
c6e61a5f19 | ||
|
|
514cdacc87 | ||
|
|
96b4ac12cb | ||
|
|
e5f5671d66 | ||
|
|
427b47b4d7 | ||
|
|
c2220cffcf | ||
|
|
3e86dde31e | ||
|
|
665497f5fb | ||
|
|
dc74a1780f | ||
|
|
3cacd4b3b9 | ||
|
|
b4d66593ef | ||
|
|
cae547a7ea | ||
|
|
f2a5304d64 | ||
|
|
b64e89daec | ||
|
|
66c8c1e292 | ||
|
|
05e27d0d83 | ||
|
|
e1bb4a5baa | ||
|
|
20aff7cc70 | ||
|
|
d823c28484 | ||
|
|
a96421019f | ||
|
|
d723bea502 | ||
|
|
4b430e6ce2 | ||
|
|
19f2853a2a | ||
|
|
24b000fb24 | ||
|
|
964c550a60 | ||
|
|
650888c73b | ||
|
|
042ef42da0 | ||
|
|
42fe6c6e04 | ||
|
|
dfffa0a7f8 | ||
|
|
f3673aff28 | ||
|
|
dd6f438fd1 | ||
|
|
9a360bd574 | ||
|
|
dbcf2065b8 | ||
|
|
e4f0864e3a | ||
|
|
a42a115b8f | ||
|
|
2b77964468 | ||
|
|
fe7c0d6484 | ||
|
|
384cbadce6 | ||
|
|
827e998afe | ||
|
|
43f583d332 | ||
|
|
99dcf2ffe5 | ||
|
|
31eda0fcb2 | ||
|
|
83eed09109 | ||
|
|
25012efc9c | ||
|
|
eb371db5b9 | ||
|
|
f23daffd7d | ||
|
|
29413d6bee | ||
|
|
fc64fc3e9c | ||
|
|
a2206ab5a0 | ||
|
|
00bf5f04db | ||
|
|
780d5fa070 | ||
|
|
1c69c43293 | ||
|
|
fa969504d4 | ||
|
|
3c6ddc9cec | ||
|
|
89b349818b | ||
|
|
4967f10356 | ||
|
|
f2a058f8cf | ||
|
|
23264ec3eb | ||
|
|
1fa1f62018 | ||
|
|
8929bfca63 | ||
|
|
21c97c6a13 | ||
|
|
29348fafb7 | ||
|
|
74ed14f8a2 | ||
|
|
6db28b3899 | ||
|
|
1590ad2518 | ||
|
|
b4d9ca8875 | ||
|
|
f6fe15716e | ||
|
|
f3364b9dce | ||
|
|
7d899166c6 | ||
|
|
27d6da9457 | ||
|
|
7e4611ad31 | ||
|
|
fdf842a4c4 | ||
|
|
b812705976 | ||
|
|
98a01d62c2 | ||
|
|
422677b9b7 | ||
|
|
42db3cac06 | ||
|
|
22c5e0d614 | ||
|
|
22ad806a43 | ||
|
|
0803e6fcaa | ||
|
|
1b2e80545a | ||
|
|
8dcc041244 | ||
|
|
c27106d859 | ||
|
|
a19a0d7b92 | ||
|
|
17a3f9e44c | ||
|
|
f16ab838d8 | ||
|
|
6260892949 | ||
|
|
8a3e713f2f | ||
|
|
324b904ed5 | ||
|
|
b1cafef07a | ||
|
|
70da1c7771 | ||
|
|
3ae8c53cba | ||
|
|
eb6ab2af50 | ||
|
|
72b5cd3889 | ||
|
|
a2439f3b34 | ||
|
|
e76d153064 | ||
|
|
521f4a6ddb | ||
|
|
296b6aee5a | ||
|
|
c6ac590d17 | ||
|
|
1281d99f30 | ||
|
|
c68dac7e9a | ||
|
|
6bdc13b33d | ||
|
|
404bfce446 | ||
|
|
1187ad96ac | ||
|
|
840f18b1c7 | ||
|
|
088563db3e | ||
|
|
bd6ab74318 | ||
|
|
fc1024a52a | ||
|
|
05ff26c141 | ||
|
|
39c9874a41 | ||
|
|
317b460d96 | ||
|
|
c8b3c8dfec | ||
|
|
603e11d7a5 | ||
|
|
8da5bad295 | ||
|
|
452a20a69a | ||
|
|
edba1f692b | ||
|
|
c1eb587c6d | ||
|
|
db4781d068 | ||
|
|
4fa51992b5 | ||
|
|
b96dc97d15 | ||
|
|
0a629237fd | ||
|
|
f44f6c7876 | ||
|
|
4dad4fab50 | ||
|
|
72714d86f6 | ||
|
|
c754e017dc | ||
|
|
138566de0b | ||
|
|
1e28f7758f | ||
|
|
f601d5fb9e | ||
|
|
d1780270da | ||
|
|
00238738b1 | ||
|
|
7b366758fd | ||
|
|
a7033c8bac | ||
|
|
446889b3f0 | ||
|
|
4cedecad4d | ||
|
|
1f991c6a79 | ||
|
|
2f0edb0b61 | ||
|
|
5b35bfd434 | ||
|
|
889d50089d | ||
|
|
a5849ee044 | ||
|
|
38e0c237a4 | ||
|
|
c4239a4fd2 | ||
|
|
7379d4e2d0 | ||
|
|
f94be4f8ab | ||
|
|
3eec500320 | ||
|
|
c16e27625c | ||
|
|
5313f48ff4 | ||
|
|
0061a3f04a | ||
|
|
7e755a53b8 | ||
|
|
ecf208f660 | ||
|
|
b3f3634df3 | ||
|
|
29c623fa58 | ||
|
|
343cab8148 | ||
|
|
f179eee7a0 | ||
|
|
5b4812add8 | ||
|
|
005ce1b21d | ||
|
|
1dcf50b59a | ||
|
|
a8b202c9bc | ||
|
|
64d805b009 | ||
|
|
79b8bd0a38 | ||
|
|
cf4e216502 | ||
|
|
1eff42eda6 | ||
|
|
5478e5cbae | ||
|
|
29f25601bb | ||
|
|
e4f2e0fd37 | ||
|
|
4e65be9ed1 | ||
|
|
6862b97909 | ||
|
|
64e91b2e13 | ||
|
|
9f0ddb89a0 | ||
|
|
e9ba8a4494 | ||
|
|
58ea44a462 | ||
|
|
7681487af4 | ||
|
|
c4fee11969 | ||
|
|
5bd26ede42 | ||
|
|
3c8e7c79b6 | ||
|
|
3be226d0c4 | ||
|
|
dfaf8f7e6a | ||
|
|
acebceb1d7 | ||
|
|
2d5ac54d2e | ||
|
|
7701de9ae4 | ||
|
|
46745614b4 | ||
|
|
efbe29249c | ||
|
|
188077d634 | ||
|
|
f8da6fb679 | ||
|
|
6edfcd83c1 | ||
|
|
fcefdb22bf | ||
|
|
7363428703 | ||
|
|
25f8c64f92 | ||
|
|
fd2839c833 | ||
|
|
1cb5fc747f | ||
|
|
4670426e4e | ||
|
|
05c1888703 | ||
|
|
e94e88e3ad | ||
|
|
9c38458f8b | ||
|
|
98cf33070f | ||
|
|
5e20417e6d | ||
|
|
bf74efcd11 | ||
|
|
384aa50be3 | ||
|
|
8687401d65 | ||
|
|
7eba6786d3 | ||
|
|
65be9d3c86 | ||
|
|
87bad767c6 | ||
|
|
f816d4f378 | ||
|
|
184be9d0e3 | ||
|
|
7eb3b186c4 | ||
|
|
ba1b857197 | ||
|
|
faa3d984ab | ||
|
|
6d7a855ca2 | ||
|
|
600018d5ad | ||
|
|
ec44c94c12 | ||
|
|
48c2a690c2 | ||
|
|
1a2aee84b2 | ||
|
|
1c44600c62 | ||
|
|
5332c4362c | ||
|
|
f2acb56041 | ||
|
|
ff1343882a | ||
|
|
2dbb397818 | ||
|
|
136a2a614b | ||
|
|
a681d8bf4d | ||
|
|
438161ad1f | ||
|
|
4dddb606a6 | ||
|
|
22c7419a70 | ||
|
|
7fb03b1ca3 | ||
|
|
97f6315bd0 | ||
|
|
e7ff47cff5 | ||
|
|
4a20ece43e | ||
|
|
b2d4666bf1 | ||
|
|
515caa8f37 | ||
|
|
4cf1b68969 | ||
|
|
413247ee5b | ||
|
|
70374d084e | ||
|
|
f335e943ad | ||
|
|
f04225321c | ||
|
|
f12315075f | ||
|
|
c99da15445 | ||
|
|
ef39db234b | ||
|
|
8af6d24a36 | ||
|
|
f8ef65e8f6 | ||
|
|
6446c312be | ||
|
|
4a524ff911 | ||
|
|
9fe0dd051d | ||
|
|
3782501275 | ||
|
|
d34ea9a569 | ||
|
|
bb1fccb7b7 | ||
|
|
777c9acae8 | ||
|
|
7b13b58a2f | ||
|
|
b11dd1f213 | ||
|
|
7ca7e4bad5 | ||
|
|
bca5bd9c62 | ||
|
|
b90e84b9fe | ||
|
|
75582f80f8 | ||
|
|
270e3a4345 | ||
|
|
0fab627a3c | ||
|
|
599e49e4d0 | ||
|
|
cff3950e6b | ||
|
|
42193960f2 | ||
|
|
98d08439dc | ||
|
|
8614c00c8a | ||
|
|
df0a49ff14 | ||
|
|
50429d0819 | ||
|
|
5c88c1f50b | ||
|
|
d85f5518d9 | ||
|
|
8e24c6458d | ||
|
|
b748455d96 | ||
|
|
7eb6471559 | ||
|
|
56513a8c66 | ||
|
|
8b1455c945 | ||
|
|
b9be1d1268 | ||
|
|
71e6f22670 | ||
|
|
0dbbf776c6 | ||
|
|
3eed7e622c | ||
|
|
a6a181c70c | ||
|
|
92b02014d2 | ||
|
|
987e843cd1 | ||
|
|
5050586a9e | ||
|
|
da4fd6b71a | ||
|
|
e07c44543f | ||
|
|
78b5e57a4a | ||
|
|
10a49d476d | ||
|
|
0759212a44 | ||
|
|
7eda64e464 | ||
|
|
124cca3af0 | ||
|
|
7faf77804d | ||
|
|
d94bcd285a | ||
|
|
9af49e07f3 | ||
|
|
0f0ab74560 | ||
|
|
5288b8550b | ||
|
|
66d789229d | ||
|
|
bba9be6a4d | ||
|
|
ebe10fa645 | ||
|
|
833c5035a6 | ||
|
|
aa3445bdb6 | ||
|
|
66fe12db71 | ||
|
|
5db3396c07 | ||
|
|
c1a18a2889 | ||
|
|
89db185726 | ||
|
|
a301d0eb4e | ||
|
|
076655cdd8 | ||
|
|
8e4a5996b0 | ||
|
|
52547466f0 | ||
|
|
4967fa8733 | ||
|
|
8065001c0d | ||
|
|
72a5839931 | ||
|
|
c995be94d9 | ||
|
|
018b81a46a | ||
|
|
941a240535 | ||
|
|
ed5b5d0559 | ||
|
|
104b7d457d | ||
|
|
feb973b970 | ||
|
|
e02068eb2a | ||
|
|
eea1878a3b | ||
|
|
4499c7a030 | ||
|
|
2f1d8630f1 | ||
|
|
cf59496957 | ||
|
|
32de29ea35 | ||
|
|
8d7de50ca8 | ||
|
|
3d685f7bec | ||
|
|
05b08ae38f | ||
|
|
623d2f25b1 | ||
|
|
634d3557f2 | ||
|
|
6957eceee0 | ||
|
|
5097f6394d | ||
|
|
77cfc1cc59 | ||
|
|
5d8200b9fc | ||
|
|
18255881ca | ||
|
|
2fb84af3e9 | ||
|
|
907f906ec6 | ||
|
|
acfb87a07b | ||
|
|
c10541feb7 | ||
|
|
e72778ea84 | ||
|
|
a824017d8c | ||
|
|
d570bc5cc5 | ||
|
|
559b2069ac | ||
|
|
6c5e89ede0 | ||
|
|
6a8ddc954f | ||
|
|
8f1c0eb2dd | ||
|
|
8c01275ee9 | ||
|
|
d6f4208a15 | ||
|
|
2e78bc1bc4 | ||
|
|
20feb44564 | ||
|
|
1506d3ddab | ||
|
|
5cb64fff91 | ||
|
|
1adf56664d | ||
|
|
183ede84fd | ||
|
|
bd9a44c225 | ||
|
|
30734ba8e8 | ||
|
|
cf4651b6bb | ||
|
|
14314b77ee | ||
|
|
ef71edd331 | ||
|
|
708c3c9ec6 | ||
|
|
c1a5c5b9f8 | ||
|
|
1cc7006555 | ||
|
|
3f87f3c47a | ||
|
|
f3a1b4e38c | ||
|
|
7eb4abae80 | ||
|
|
0ea1b712be | ||
|
|
9cf96580bf | ||
|
|
46d67cb349 | ||
|
|
f7d5141251 | ||
|
|
8e11dac375 | ||
|
|
adee6de140 | ||
|
|
4ed89dc2d3 | ||
|
|
8e6d575d4e | ||
|
|
e227b92972 | ||
|
|
a9a082f05c | ||
|
|
be54cb9531 | ||
|
|
18a6b8e101 | ||
|
|
52ced19e2e | ||
|
|
1c0971b12c | ||
|
|
2db9bdf7a2 | ||
|
|
a09b2a23b9 | ||
|
|
6d2ecefca0 | ||
|
|
568c22016a | ||
|
|
6e1b9326e4 | ||
|
|
3c8a38212e | ||
|
|
eba4af7a9f | ||
|
|
f8a5725214 | ||
|
|
791077c240 | ||
|
|
bd8de9a6f8 | ||
|
|
0a82489ddc | ||
|
|
006b8716ed | ||
|
|
4ff8386e3d | ||
|
|
cb6c8bee47 | ||
|
|
3a35883250 | ||
|
|
2a00565bc4 | ||
|
|
5e0e951867 | ||
|
|
4c75bd404b | ||
|
|
2b70760594 | ||
|
|
d8ce97f766 | ||
|
|
cf221c8f75 | ||
|
|
b938c60396 | ||
|
|
3a28fa01b0 | ||
|
|
8a84884d50 | ||
|
|
b103052ff0 | ||
|
|
71b6dd232e | ||
|
|
1f7863e323 | ||
|
|
e951209d68 | ||
|
|
0ef114e006 | ||
|
|
887f11435b | ||
|
|
d7f1b873c8 | ||
|
|
16f9f50f50 | ||
|
|
6f1dcdc08f | ||
|
|
3cd50da3b0 | ||
|
|
0125ec3b48 | ||
|
|
7611f52faf | ||
|
|
669b2342ff | ||
|
|
1493c2a9b4 | ||
|
|
724ca74f51 | ||
|
|
76d4ac17a2 | ||
|
|
8d54d97007 | ||
|
|
7cf2d889d8 | ||
|
|
59a2d1c974 | ||
|
|
5108a9c6fe | ||
|
|
6e98df0e28 | ||
|
|
f3f75f557a | ||
|
|
8bf5759d26 | ||
|
|
cbf797ed95 | ||
|
|
17c4d733d0 | ||
|
|
dd52fb7e2e | ||
|
|
b1f5103c75 | ||
|
|
f19e8af33b | ||
|
|
a559c0cfc2 | ||
|
|
5132252daa | ||
|
|
dfb81dd89c | ||
|
|
59e3802c74 | ||
|
|
a1d2acd574 | ||
|
|
8bb60b6474 | ||
|
|
143be7ee02 | ||
|
|
d967bb4a54 | ||
|
|
fd37f37ee4 | ||
|
|
db3e8616c8 | ||
|
|
8fdef1f820 | ||
|
|
b481e76ee2 | ||
|
|
3477f9bfe0 | ||
|
|
10cf1ccc1a | ||
|
|
22b42dc90a | ||
|
|
e6f58e4dcc | ||
|
|
192b9008bd | ||
|
|
56d0af472d | ||
|
|
85f32b956f | ||
|
|
027bf93849 | ||
|
|
071f8e18d0 | ||
|
|
19d962c3aa | ||
|
|
dae2d4686e | ||
|
|
fc3ee67b1f | ||
|
|
a54a15523b | ||
|
|
5b135c07d0 | ||
|
|
dd83445fd7 | ||
|
|
290485b144 | ||
|
|
c514316a2e | ||
|
|
8b98ceb92c | ||
|
|
7a20a4d32b | ||
|
|
8cbb78bb1d | ||
|
|
ef84339003 | ||
|
|
909954ac34 | ||
|
|
d996643540 | ||
|
|
074a4a6e0e | ||
|
|
a6248cba19 | ||
|
|
6a875eb691 | ||
|
|
83c96d4f3e | ||
|
|
1fcc9e977f | ||
|
|
c56b95ed68 | ||
|
|
bb3a5bcfd7 | ||
|
|
35678a1c09 | ||
|
|
c622ad0b50 | ||
|
|
75324e4859 | ||
|
|
93f07c78d6 | ||
|
|
59a619ebbb | ||
|
|
77938cc11e | ||
|
|
ae998984a0 | ||
|
|
2e31311e3c | ||
|
|
32782a7f9f | ||
|
|
4f2d74e25f | ||
|
|
c9ed3fdae3 | ||
|
|
7b164b5cd4 | ||
|
|
dd54b1aacb | ||
|
|
8fa96feb1f | ||
|
|
ddd0796e40 | ||
|
|
4ef86b965b | ||
|
|
1cc6dd871b | ||
|
|
4564519a56 | ||
|
|
5a241fd12e | ||
|
|
840fcf2fa9 | ||
|
|
75e3ab737c | ||
|
|
516cedaa47 | ||
|
|
3881ade96d | ||
|
|
f4842d6eed | ||
|
|
10e77d865b | ||
|
|
92725e5803 | ||
|
|
73510949ba | ||
|
|
08ff4dfb21 | ||
|
|
2e72f2eca8 | ||
|
|
9845bbddce | ||
|
|
81b3ad5b87 | ||
|
|
6c4f196f6e | ||
|
|
022b4ae57c | ||
|
|
d185e2f9e0 | ||
|
|
2b7c31feb5 | ||
|
|
7dd312b1ac | ||
|
|
4ff7b395dd | ||
|
|
66044c620b | ||
|
|
52c1718ee8 | ||
|
|
8b180aa606 | ||
|
|
ccaf6c8df0 | ||
|
|
879a614cde | ||
|
|
8c3dc34359 | ||
|
|
f82654f158 | ||
|
|
c365614548 | ||
|
|
a3c2c4a48a | ||
|
|
8316e78667 | ||
|
|
4a988b0f92 | ||
|
|
b5e80bf90f | ||
|
|
da426fa652 | ||
|
|
39e65a41a2 | ||
|
|
1eb17b08f9 | ||
|
|
318c8717b8 | ||
|
|
7184632b84 | ||
|
|
1e4a7d55e0 | ||
|
|
5101c55e10 | ||
|
|
c1537b5291 | ||
|
|
4c767d636a | ||
|
|
aa91ca0a8d | ||
|
|
d3b831bf7b | ||
|
|
fa688d48e6 | ||
|
|
671a0fa101 | ||
|
|
99f006f2c9 | ||
|
|
f9c400a727 | ||
|
|
fe22797d69 | ||
|
|
d29ba0b80f | ||
|
|
18fd46ab6b | ||
|
|
ec7ac956e4 | ||
|
|
99c560295f | ||
|
|
90c7cf9763 | ||
|
|
3dc9ceaadf | ||
|
|
23f6185bfe | ||
|
|
1cb0294388 | ||
|
|
2d47a6d71c | ||
|
|
22c2209cf9 | ||
|
|
471679b0f0 | ||
|
|
862c9d76e6 | ||
|
|
2c187c43bf | ||
|
|
486b4e9ea2 | ||
|
|
5f361e71df | ||
|
|
13881f5a5b | ||
|
|
c38a2112c6 | ||
|
|
a9fc777b20 | ||
|
|
ab15456119 | ||
|
|
0d55613359 | ||
|
|
845460b165 | ||
|
|
7c27fb7c1d | ||
|
|
e51c20c496 | ||
|
|
190fef513f | ||
|
|
b9ef10fe3f | ||
|
|
2b9777555f | ||
|
|
1f79394ac4 | ||
|
|
e2e111f95e | ||
|
|
8985d05a66 | ||
|
|
4e03668eec | ||
|
|
2789b08dd0 | ||
|
|
66a02688ad | ||
|
|
681bbf02ae | ||
|
|
c80de840d1 | ||
|
|
bd3458da6e | ||
|
|
4ccbc65628 | ||
|
|
9a2753931b | ||
|
|
0b4d4db131 | ||
|
|
a1b12335ab | ||
|
|
a8137d5d17 | ||
|
|
1e5362b1f7 | ||
|
|
51ea8b0295 | ||
|
|
f35194e604 | ||
|
|
3ef57c1ac3 | ||
|
|
69b7f9e9a2 | ||
|
|
220641909c | ||
|
|
31bc6054a3 | ||
|
|
94391723c0 | ||
|
|
5fd3decb16 | ||
|
|
d7c015a884 | ||
|
|
8ed55e8d7a | ||
|
|
979892a109 | ||
|
|
776d5ce554 | ||
|
|
28ea323791 | ||
|
|
18787caab9 | ||
|
|
390d6023c6 | ||
|
|
e1ef9a5c72 | ||
|
|
f3babef54a | ||
|
|
2dc3850798 | ||
|
|
18001e5a5b | ||
|
|
32f6cb7c13 | ||
|
|
9f76b4d2ef | ||
|
|
a9efe82117 | ||
|
|
4ee55dc456 | ||
|
|
470ef4d11e | ||
|
|
57d4e698fe | ||
|
|
f50544bb15 | ||
|
|
e3becc7c3c | ||
|
|
e7caec6e7d | ||
|
|
6487c1803f | ||
|
|
ff65a5b22a | ||
|
|
7a03cf92ba | ||
|
|
e6fa690d65 | ||
|
|
95cc65f14e | ||
|
|
b3a3d3e2fa | ||
|
|
0820e745d6 | ||
|
|
2197fa3120 | ||
|
|
b4d4b80dcd | ||
|
|
3bfaa20c05 | ||
|
|
58f8a23d58 | ||
|
|
1f3380bfad | ||
|
|
451ec23060 | ||
|
|
4c84165aa0 | ||
|
|
a6c8feea21 | ||
|
|
718de6c7fd | ||
|
|
d81a135704 | ||
|
|
1a90fbee8b | ||
|
|
2ac30707d2 | ||
|
|
58a36e3604 | ||
|
|
676fe403ab | ||
|
|
13611bf0ab | ||
|
|
ad02b3fb7b | ||
|
|
d3600e729f | ||
|
|
6c8e1514aa | ||
|
|
bc44158501 | ||
|
|
918123cd06 | ||
|
|
2b86ef8e28 | ||
|
|
3e28dc669b | ||
|
|
bee3f353fc | ||
|
|
005f4baaa4 | ||
|
|
2b0142580f | ||
|
|
236c735d08 | ||
|
|
e5562afcd3 | ||
|
|
256eb6250e | ||
|
|
e50ba150c3 | ||
|
|
bab9c40dcc | ||
|
|
55ed70529a | ||
|
|
28c6aa4e6d | ||
|
|
ab88b27622 | ||
|
|
2c335dbf32 | ||
|
|
d6d1502200 | ||
|
|
4bb61ade27 | ||
|
|
96f83cc8f0 | ||
|
|
eabc04d836 | ||
|
|
b3be8745b0 | ||
|
|
aa28c3d7ba | ||
|
|
948e2190f8 | ||
|
|
362633d486 | ||
|
|
120e39ba80 | ||
|
|
98d4bdb7df | ||
|
|
2c6e3cb02d | ||
|
|
9c70084ea5 | ||
|
|
9b2bd72e1f | ||
|
|
707360169e | ||
|
|
418b8d861a | ||
|
|
42181112ff | ||
|
|
67e81b0ae9 | ||
|
|
51317b350c | ||
|
|
c83e794871 | ||
|
|
26ec775854 | ||
|
|
5e9e01bf7f | ||
|
|
f7df1b7d55 | ||
|
|
abb5d019cd | ||
|
|
474b5a52d6 | ||
|
|
63d3b12bb5 | ||
|
|
7136b85f21 | ||
|
|
6707034768 | ||
|
|
ef99d3c4ce | ||
|
|
4c9f27e550 | ||
|
|
55dded8e5f | ||
|
|
0778ac8c1b | ||
|
|
3628515b31 | ||
|
|
51e0989c49 | ||
|
|
79cbe8d199 | ||
|
|
a2d4ca095a | ||
|
|
7473be4072 | ||
|
|
6a0022d7a1 | ||
|
|
e4d4a12c6a | ||
|
|
4a1cfb3df9 | ||
|
|
b00769f606 | ||
|
|
6e367354e9 | ||
|
|
e5e8318c70 | ||
|
|
d9135ce1e7 | ||
|
|
aa17905081 | ||
|
|
fbafa95791 | ||
|
|
dc26a9cd39 | ||
|
|
5f185b6c05 | ||
|
|
893a433165 | ||
|
|
552d99d664 | ||
|
|
54aeec7b5f | ||
|
|
d2b89f5f9b | ||
|
|
6b08e1b315 | ||
|
|
18ee1fef41 | ||
|
|
2a96f56956 | ||
|
|
3903eddded | ||
|
|
b862c447f1 | ||
|
|
5b47d7bfcc | ||
|
|
310a0f924a | ||
|
|
7e57db1edb | ||
|
|
71c3ad642c | ||
|
|
bc51f529e9 | ||
|
|
a573da3b98 | ||
|
|
f37089f547 | ||
|
|
366ca57c36 | ||
|
|
b1ede59d02 | ||
|
|
6b7650e2f0 | ||
|
|
73e0b8f8b3 | ||
|
|
d19142e209 |
No files matched your search
File renamed without changes.
File renamed without changes.
+3
-1
@@ -43,7 +43,7 @@ class AccountController < ApplicationController
|
|||||||
self.logged_user = nil
|
self.logged_user = nil
|
||||||
else
|
else
|
||||||
# Authenticate user
|
# Authenticate user
|
||||||
user = User.try_to_login(params[:login], params[:password])
|
user = User.try_to_login(params[:username], params[:password])
|
||||||
if user
|
if user
|
||||||
self.logged_user = user
|
self.logged_user = user
|
||||||
# generate a key and set cookie if autologin
|
# generate a key and set cookie if autologin
|
||||||
@@ -56,6 +56,8 @@ class AccountController < ApplicationController
|
|||||||
flash.now[:error] = l(:notice_account_invalid_creditentials)
|
flash.now[:error] = l(:notice_account_invalid_creditentials)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rescue User::OnTheFlyCreationFailure
|
||||||
|
flash.now[:error] = 'Redmine could not retrieve the required information from the LDAP to create your account. Please, contact your Redmine administrator.'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Log out current user and redirect to welcome page
|
# Log out current user and redirect to welcome page
|
||||||
+1
-1
@@ -28,7 +28,7 @@ class AdminController < ApplicationController
|
|||||||
|
|
||||||
def projects
|
def projects
|
||||||
sort_init 'name', 'asc'
|
sort_init 'name', 'asc'
|
||||||
sort_update
|
sort_update %w(name is_public created_on)
|
||||||
|
|
||||||
@status = params[:status] ? params[:status].to_i : 0
|
@status = params[:status] ? params[:status].to_i : 0
|
||||||
conditions = nil
|
conditions = nil
|
||||||
@@ -15,11 +15,7 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'uri'
|
|
||||||
|
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
layout 'base'
|
|
||||||
|
|
||||||
before_filter :user_setup, :check_if_login_required, :set_localization
|
before_filter :user_setup, :check_if_login_required, :set_localization
|
||||||
filter_parameter_logging :password
|
filter_parameter_logging :password
|
||||||
|
|
||||||
@@ -81,7 +77,8 @@ class ApplicationController < ActionController::Base
|
|||||||
|
|
||||||
def require_login
|
def require_login
|
||||||
if !User.current.logged?
|
if !User.current.logged?
|
||||||
redirect_to :controller => "account", :action => "login", :back_url => request.request_uri
|
store_location
|
||||||
|
redirect_to :controller => "account", :action => "login"
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
@@ -118,16 +115,20 @@ class ApplicationController < ActionController::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# store current uri in session.
|
||||||
|
# return to this location by calling redirect_back_or_default
|
||||||
|
def store_location
|
||||||
|
session[:return_to_params] = params
|
||||||
|
end
|
||||||
|
|
||||||
|
# move to the last store_location call or to the passed default one
|
||||||
def redirect_back_or_default(default)
|
def redirect_back_or_default(default)
|
||||||
back_url = params[:back_url]
|
if session[:return_to_params].nil?
|
||||||
if !back_url.blank?
|
redirect_to default
|
||||||
uri = URI.parse(back_url)
|
else
|
||||||
# do not redirect user to another host
|
redirect_to session[:return_to_params]
|
||||||
if uri.relative? || (uri.host == request.host)
|
session[:return_to_params] = nil
|
||||||
redirect_to(back_url) and return
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
redirect_to default
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_403
|
def render_403
|
||||||
+1
-1
@@ -21,7 +21,7 @@ class AttachmentsController < ApplicationController
|
|||||||
|
|
||||||
def download
|
def download
|
||||||
# images are sent inline
|
# images are sent inline
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename,
|
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
|
||||||
:type => @attachment.content_type,
|
:type => @attachment.content_type,
|
||||||
:disposition => (@attachment.image? ? 'inline' : 'attachment')
|
:disposition => (@attachment.image? ? 'inline' : 'attachment')
|
||||||
rescue
|
rescue
|
||||||
File renamed without changes.
+4
-3
@@ -36,12 +36,13 @@ class BoardsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
sort_init "#{Message.table_name}.updated_on", "desc"
|
sort_init 'updated_on', 'desc'
|
||||||
sort_update
|
sort_update 'created_on' => "#{Message.table_name}.created_on",
|
||||||
|
'updated_on' => "#{Message.table_name}.updated_on"
|
||||||
|
|
||||||
@topic_count = @board.topics.count
|
@topic_count = @board.topics.count
|
||||||
@topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
|
@topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
|
||||||
@topics = @board.topics.find :all, :order => "#{Message.table_name}.sticky DESC, #{sort_clause}",
|
@topics = @board.topics.find :all, :order => ["#{Message.table_name}.sticky DESC", sort_clause].compact.join(', '),
|
||||||
:include => [:author, {:last_reply => :author}],
|
:include => [:author, {:last_reply => :author}],
|
||||||
:limit => @topic_pages.items_per_page,
|
:limit => @topic_pages.items_per_page,
|
||||||
:offset => @topic_pages.current.offset
|
:offset => @topic_pages.current.offset
|
||||||
File renamed without changes.
+4
-1
@@ -21,6 +21,8 @@ class DocumentsController < ApplicationController
|
|||||||
before_filter :find_document, :except => [:index, :new]
|
before_filter :find_document, :except => [:index, :new]
|
||||||
before_filter :authorize
|
before_filter :authorize
|
||||||
|
|
||||||
|
helper :attachments
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
|
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
|
||||||
documents = @project.documents.find :all, :include => [:attachments, :category]
|
documents = @project.documents.find :all, :include => [:attachments, :category]
|
||||||
@@ -67,7 +69,8 @@ class DocumentsController < ApplicationController
|
|||||||
def download
|
def download
|
||||||
@attachment = @document.attachments.find(params[:attachment_id])
|
@attachment = @document.attachments.find(params[:attachment_id])
|
||||||
@attachment.increment_download
|
@attachment.increment_download
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename, :type => @attachment.content_type
|
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
|
||||||
|
:type => @attachment.content_type
|
||||||
rescue
|
rescue
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
File renamed without changes.
+1
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class IssueCategoriesController < ApplicationController
|
class IssueCategoriesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :settings
|
menu_item :settings
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
File renamed without changes.
File renamed without changes.
@@ -16,9 +16,10 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class IssuesController < ApplicationController
|
class IssuesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :new_issue, :only => :new
|
menu_item :new_issue, :only => :new
|
||||||
|
|
||||||
before_filter :find_issue, :only => [:show, :edit, :reply, :destroy_attachment]
|
before_filter :find_issue, :only => [:show, :edit, :destroy_attachment]
|
||||||
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
|
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
|
||||||
before_filter :find_project, :only => [:new, :update_form, :preview]
|
before_filter :find_project, :only => [:new, :update_form, :preview]
|
||||||
before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu]
|
before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu]
|
||||||
@@ -42,12 +43,12 @@ class IssuesController < ApplicationController
|
|||||||
helper :sort
|
helper :sort
|
||||||
include SortHelper
|
include SortHelper
|
||||||
include IssuesHelper
|
include IssuesHelper
|
||||||
helper :timelog
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
sort_init "#{Issue.table_name}.id", "desc"
|
|
||||||
sort_update
|
|
||||||
retrieve_query
|
retrieve_query
|
||||||
|
sort_init 'id', 'desc'
|
||||||
|
sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h}))
|
||||||
|
|
||||||
if @query.valid?
|
if @query.valid?
|
||||||
limit = per_page_option
|
limit = per_page_option
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
@@ -65,7 +66,7 @@ class IssuesController < ApplicationController
|
|||||||
:offset => @issue_pages.current.offset
|
:offset => @issue_pages.current.offset
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
|
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
|
||||||
format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
|
format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
|
||||||
format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
|
format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
|
||||||
format.pdf { send_data(render(:template => 'issues/index.rfpdf', :layout => false), :type => 'application/pdf', :filename => 'export.pdf') }
|
format.pdf { send_data(render(:template => 'issues/index.rfpdf', :layout => false), :type => 'application/pdf', :filename => 'export.pdf') }
|
||||||
end
|
end
|
||||||
@@ -78,9 +79,10 @@ class IssuesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def changes
|
def changes
|
||||||
sort_init "#{Issue.table_name}.id", "desc"
|
|
||||||
sort_update
|
|
||||||
retrieve_query
|
retrieve_query
|
||||||
|
sort_init 'id', 'desc'
|
||||||
|
sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h}))
|
||||||
|
|
||||||
if @query.valid?
|
if @query.valid?
|
||||||
@journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
|
@journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
|
||||||
:conditions => @query.statement,
|
:conditions => @query.statement,
|
||||||
@@ -94,11 +96,13 @@ class IssuesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
|
||||||
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
|
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
|
||||||
@journals.each_with_index {|j,i| j.indice = i+1}
|
@journals.each_with_index {|j,i| j.indice = i+1}
|
||||||
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
||||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||||
|
@activities = Enumeration::get_values('ACTI')
|
||||||
@priorities = Enumeration::get_values('IPRI')
|
@priorities = Enumeration::get_values('IPRI')
|
||||||
@time_entry = TimeEntry.new
|
@time_entry = TimeEntry.new
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
@@ -111,18 +115,15 @@ class IssuesController < ApplicationController
|
|||||||
# Add a new issue
|
# Add a new issue
|
||||||
# The new issue will be created from an existing one if copy_from parameter is given
|
# The new issue will be created from an existing one if copy_from parameter is given
|
||||||
def new
|
def new
|
||||||
@issue = Issue.new
|
@issue = params[:copy_from] ? Issue.new.copy_from(params[:copy_from]) : Issue.new(params[:issue])
|
||||||
@issue.copy_from(params[:copy_from]) if params[:copy_from]
|
|
||||||
@issue.project = @project
|
@issue.project = @project
|
||||||
# Tracker must be set before custom field values
|
@issue.author = User.current
|
||||||
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
|
@issue.tracker ||= @project.trackers.find(params[:tracker_id] ? params[:tracker_id] : :first)
|
||||||
if @issue.tracker.nil?
|
if @issue.tracker.nil?
|
||||||
flash.now[:error] = 'No tracker is associated to this project. Please check the Project settings.'
|
flash.now[:error] = 'No tracker is associated to this project. Please check the Project settings.'
|
||||||
render :nothing => true, :layout => true
|
render :nothing => true, :layout => true
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@issue.attributes = params[:issue]
|
|
||||||
@issue.author = User.current
|
|
||||||
|
|
||||||
default_status = IssueStatus.default
|
default_status = IssueStatus.default
|
||||||
unless default_status
|
unless default_status
|
||||||
@@ -135,10 +136,17 @@ class IssuesController < ApplicationController
|
|||||||
|
|
||||||
if request.get? || request.xhr?
|
if request.get? || request.xhr?
|
||||||
@issue.start_date ||= Date.today
|
@issue.start_date ||= Date.today
|
||||||
|
@custom_values = @issue.custom_values.empty? ?
|
||||||
|
@project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) } :
|
||||||
|
@issue.custom_values
|
||||||
else
|
else
|
||||||
requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
|
requested_status = (params[:issue] && params[:issue][:status_id] ? IssueStatus.find_by_id(params[:issue][:status_id]) : default_status)
|
||||||
# Check that the user is allowed to apply the requested status
|
# Check that the user is allowed to apply the requested status
|
||||||
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
|
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
|
||||||
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x,
|
||||||
|
:customized => @issue,
|
||||||
|
:value => (params[:custom_fields] ? params[:custom_fields][x.id.to_s] : nil)) }
|
||||||
|
@issue.custom_values = @custom_values
|
||||||
if @issue.save
|
if @issue.save
|
||||||
attach_files(@issue, params[:attachments])
|
attach_files(@issue, params[:attachments])
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
@@ -157,9 +165,10 @@ class IssuesController < ApplicationController
|
|||||||
|
|
||||||
def edit
|
def edit
|
||||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||||
|
@activities = Enumeration::get_values('ACTI')
|
||||||
@priorities = Enumeration::get_values('IPRI')
|
@priorities = Enumeration::get_values('IPRI')
|
||||||
|
@custom_values = []
|
||||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||||
@time_entry = TimeEntry.new
|
|
||||||
|
|
||||||
@notes = params[:notes]
|
@notes = params[:notes]
|
||||||
journal = @issue.init_journal(User.current, @notes)
|
journal = @issue.init_journal(User.current, @notes)
|
||||||
@@ -171,12 +180,19 @@ class IssuesController < ApplicationController
|
|||||||
@issue.attributes = attrs
|
@issue.attributes = attrs
|
||||||
end
|
end
|
||||||
|
|
||||||
if request.post?
|
if request.get?
|
||||||
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
|
||||||
|
else
|
||||||
|
# Update custom fields if user has :edit permission
|
||||||
|
if @edit_allowed && params[:custom_fields]
|
||||||
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
|
||||||
|
@issue.custom_values = @custom_values
|
||||||
|
end
|
||||||
@time_entry = TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
|
@time_entry = TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
|
||||||
@time_entry.attributes = params[:time_entry]
|
@time_entry.attributes = params[:time_entry]
|
||||||
attachments = attach_files(@issue, params[:attachments])
|
attachments = attach_files(@issue, params[:attachments])
|
||||||
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
|
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
|
||||||
if (@time_entry.hours.nil? || @time_entry.valid?) && @issue.save
|
if @issue.save
|
||||||
# Log spend time
|
# Log spend time
|
||||||
if current_role.allowed_to?(:log_time)
|
if current_role.allowed_to?(:log_time)
|
||||||
@time_entry.save
|
@time_entry.save
|
||||||
@@ -194,26 +210,6 @@ class IssuesController < ApplicationController
|
|||||||
flash.now[:error] = l(:notice_locking_conflict)
|
flash.now[:error] = l(:notice_locking_conflict)
|
||||||
end
|
end
|
||||||
|
|
||||||
def reply
|
|
||||||
journal = Journal.find(params[:journal_id]) if params[:journal_id]
|
|
||||||
if journal
|
|
||||||
user = journal.user
|
|
||||||
text = journal.notes
|
|
||||||
else
|
|
||||||
user = @issue.author
|
|
||||||
text = @issue.description
|
|
||||||
end
|
|
||||||
content = "#{ll(Setting.default_language, :text_user_wrote, user)}\\n> "
|
|
||||||
content << text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub('"', '\"').gsub(/(\r?\n|\r\n?)/, "\\n> ") + "\\n\\n"
|
|
||||||
render(:update) { |page|
|
|
||||||
page.<< "$('notes').value = \"#{content}\";"
|
|
||||||
page.show 'update'
|
|
||||||
page << "Form.Element.focus('notes');"
|
|
||||||
page << "Element.scrollTo('update');"
|
|
||||||
page << "$('notes').scrollTop = $('notes').scrollHeight - $('notes').clientHeight;"
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Bulk edit a set of issues
|
# Bulk edit a set of issues
|
||||||
def bulk_edit
|
def bulk_edit
|
||||||
if request.post?
|
if request.post?
|
||||||
@@ -233,7 +229,6 @@ class IssuesController < ApplicationController
|
|||||||
issue.start_date = params[:start_date] unless params[:start_date].blank?
|
issue.start_date = params[:start_date] unless params[:start_date].blank?
|
||||||
issue.due_date = params[:due_date] unless params[:due_date].blank?
|
issue.due_date = params[:due_date] unless params[:due_date].blank?
|
||||||
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
|
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
|
||||||
call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
|
|
||||||
# Don't save any change to the issue if the user is not authorized to apply the requested status
|
# Don't save any change to the issue if the user is not authorized to apply the requested status
|
||||||
if (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
|
if (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
|
||||||
# Send notification for each issue (if changed)
|
# Send notification for each issue (if changed)
|
||||||
@@ -272,7 +267,6 @@ class IssuesController < ApplicationController
|
|||||||
new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
|
new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
|
||||||
unsaved_issue_ids = []
|
unsaved_issue_ids = []
|
||||||
@issues.each do |issue|
|
@issues.each do |issue|
|
||||||
issue.init_journal(User.current)
|
|
||||||
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker)
|
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker)
|
||||||
end
|
end
|
||||||
if unsaved_issue_ids.empty?
|
if unsaved_issue_ids.empty?
|
||||||
@@ -334,7 +328,6 @@ class IssuesController < ApplicationController
|
|||||||
@project = projects.first if projects.size == 1
|
@project = projects.first if projects.size == 1
|
||||||
|
|
||||||
@can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
|
@can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
|
||||||
:log_time => (@project && User.current.allowed_to?(:log_time, @project)),
|
|
||||||
:update => (@issue && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && !@allowed_statuses.empty?))),
|
:update => (@issue && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && !@allowed_statuses.empty?))),
|
||||||
:move => (@project && User.current.allowed_to?(:move_issues, @project)),
|
:move => (@project && User.current.allowed_to?(:move_issues, @project)),
|
||||||
:copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
|
:copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class JournalsController < ApplicationController
|
class JournalsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :find_journal
|
before_filter :find_journal
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
File renamed without changes.
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class MessagesController < ApplicationController
|
class MessagesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :boards
|
menu_item :boards
|
||||||
before_filter :find_board, :only => [:new, :preview]
|
before_filter :find_board, :only => [:new, :preview]
|
||||||
before_filter :find_message, :except => [:new, :preview]
|
before_filter :find_message, :except => [:new, :preview]
|
||||||
@@ -16,9 +16,10 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class MyController < ApplicationController
|
class MyController < ApplicationController
|
||||||
before_filter :require_login
|
|
||||||
|
|
||||||
helper :issues
|
helper :issues
|
||||||
|
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_login
|
||||||
|
|
||||||
BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
|
BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
|
||||||
'issuesreportedbyme' => :label_reported_issues,
|
'issuesreportedbyme' => :label_reported_issues,
|
||||||
+2
-1
@@ -16,8 +16,9 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class NewsController < ApplicationController
|
class NewsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :find_news, :except => [:new, :index, :preview]
|
before_filter :find_news, :except => [:new, :index, :preview]
|
||||||
before_filter :find_project, :only => [:new, :preview]
|
before_filter :find_project, :only => :new
|
||||||
before_filter :authorize, :except => [:index, :preview]
|
before_filter :authorize, :except => [:index, :preview]
|
||||||
before_filter :find_optional_project, :only => :index
|
before_filter :find_optional_project, :only => :index
|
||||||
accept_key_auth :index
|
accept_key_auth :index
|
||||||
+108
-35
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class ProjectsController < ApplicationController
|
class ProjectsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :overview
|
menu_item :overview
|
||||||
menu_item :activity, :only => :activity
|
menu_item :activity, :only => :activity
|
||||||
menu_item :roadmap, :only => :roadmap
|
menu_item :roadmap, :only => :roadmap
|
||||||
@@ -43,36 +44,37 @@ class ProjectsController < ApplicationController
|
|||||||
include RepositoriesHelper
|
include RepositoriesHelper
|
||||||
include ProjectsHelper
|
include ProjectsHelper
|
||||||
|
|
||||||
# Lists visible projects
|
|
||||||
def index
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list' unless request.xhr?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Lists visible projects
|
||||||
|
def list
|
||||||
projects = Project.find :all,
|
projects = Project.find :all,
|
||||||
:conditions => Project.visible_by(User.current),
|
:conditions => Project.visible_by(User.current),
|
||||||
:include => :parent
|
:include => :parent
|
||||||
respond_to do |format|
|
@project_tree = projects.group_by {|p| p.parent || p}
|
||||||
format.html {
|
@project_tree.each_key {|p| @project_tree[p] -= [p]}
|
||||||
@project_tree = projects.group_by {|p| p.parent || p}
|
|
||||||
@project_tree.keys.each {|p| @project_tree[p] -= [p]}
|
|
||||||
}
|
|
||||||
format.atom {
|
|
||||||
render_feed(projects.sort_by(&:created_on).reverse.slice(0, Setting.feeds_limit.to_i),
|
|
||||||
:title => "#{Setting.app_title}: #{l(:label_project_latest)}")
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add a new project
|
# Add a new project
|
||||||
def add
|
def add
|
||||||
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
@custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
||||||
@trackers = Tracker.all
|
@trackers = Tracker.all
|
||||||
@root_projects = Project.find(:all,
|
@root_projects = Project.find(:all,
|
||||||
:conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
|
:conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
|
||||||
:order => 'name')
|
:order => 'name')
|
||||||
@project = Project.new(params[:project])
|
@project = Project.new(params[:project])
|
||||||
if request.get?
|
if request.get?
|
||||||
|
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
|
||||||
@project.trackers = Tracker.all
|
@project.trackers = Tracker.all
|
||||||
@project.is_public = Setting.default_projects_public?
|
@project.is_public = Setting.default_projects_public?
|
||||||
@project.enabled_module_names = Redmine::AccessControl.available_project_modules
|
@project.enabled_module_names = Redmine::AccessControl.available_project_modules
|
||||||
else
|
else
|
||||||
|
@project.custom_fields = CustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
|
||||||
|
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
|
||||||
|
@project.custom_values = @custom_values
|
||||||
@project.enabled_module_names = params[:enabled_modules]
|
@project.enabled_module_names = params[:enabled_modules]
|
||||||
if @project.save
|
if @project.save
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
@@ -83,6 +85,7 @@ class ProjectsController < ApplicationController
|
|||||||
|
|
||||||
# Show @project
|
# Show @project
|
||||||
def show
|
def show
|
||||||
|
@custom_values = @project.custom_values.find(:all, :include => :custom_field, :order => "#{CustomField.table_name}.position")
|
||||||
@members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
|
@members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
|
||||||
@subprojects = @project.children.find(:all, :conditions => Project.visible_by(User.current))
|
@subprojects = @project.children.find(:all, :conditions => Project.visible_by(User.current))
|
||||||
@news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
|
@news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
|
||||||
@@ -109,10 +112,11 @@ class ProjectsController < ApplicationController
|
|||||||
@root_projects = Project.find(:all,
|
@root_projects = Project.find(:all,
|
||||||
:conditions => ["parent_id IS NULL AND status = #{Project::STATUS_ACTIVE} AND id <> ?", @project.id],
|
:conditions => ["parent_id IS NULL AND status = #{Project::STATUS_ACTIVE} AND id <> ?", @project.id],
|
||||||
:order => 'name')
|
:order => 'name')
|
||||||
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
@custom_fields = IssueCustomField.find(:all)
|
||||||
@issue_category ||= IssueCategory.new
|
@issue_category ||= IssueCategory.new
|
||||||
@member ||= @project.members.new
|
@member ||= @project.members.new
|
||||||
@trackers = Tracker.all
|
@trackers = Tracker.all
|
||||||
|
@custom_values ||= ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
|
||||||
@repository ||= @project.repository
|
@repository ||= @project.repository
|
||||||
@wiki ||= @project.wiki
|
@wiki ||= @project.wiki
|
||||||
end
|
end
|
||||||
@@ -120,6 +124,10 @@ class ProjectsController < ApplicationController
|
|||||||
# Edit @project
|
# Edit @project
|
||||||
def edit
|
def edit
|
||||||
if request.post?
|
if request.post?
|
||||||
|
if params[:custom_fields]
|
||||||
|
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
|
||||||
|
@project.custom_values = @custom_values
|
||||||
|
end
|
||||||
@project.attributes = params[:project]
|
@project.attributes = params[:project]
|
||||||
if @project.save
|
if @project.save
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
@@ -196,8 +204,12 @@ class ProjectsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def list_files
|
def list_files
|
||||||
sort_init "#{Attachment.table_name}.filename", "asc"
|
sort_init 'filename', 'asc'
|
||||||
sort_update
|
sort_update 'filename' => "#{Attachment.table_name}.filename",
|
||||||
|
'created_on' => "#{Attachment.table_name}.created_on",
|
||||||
|
'size' => "#{Attachment.table_name}.filesize",
|
||||||
|
'downloads' => "#{Attachment.table_name}.downloads"
|
||||||
|
|
||||||
@versions = @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse
|
@versions = @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse
|
||||||
render :layout => !request.xhr?
|
render :layout => !request.xhr?
|
||||||
end
|
end
|
||||||
@@ -225,23 +237,91 @@ class ProjectsController < ApplicationController
|
|||||||
|
|
||||||
@date_to ||= Date.today + 1
|
@date_to ||= Date.today + 1
|
||||||
@date_from = @date_to - @days
|
@date_from = @date_to - @days
|
||||||
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
|
|
||||||
|
|
||||||
@activity = Redmine::Activity::Fetcher.new(User.current, :project => @project, :with_subprojects => @with_subprojects)
|
@event_types = %w(issues news files documents changesets wiki_pages messages)
|
||||||
@activity.scope_select {|t| !params["show_#{t}"].nil?}
|
if @project
|
||||||
@activity.default_scope! if @activity.scope.empty?
|
@event_types.delete('wiki_pages') unless @project.wiki
|
||||||
|
@event_types.delete('changesets') unless @project.repository
|
||||||
|
@event_types.delete('messages') unless @project.boards.any?
|
||||||
|
# only show what the user is allowed to view
|
||||||
|
@event_types = @event_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, @project)}
|
||||||
|
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
|
||||||
|
end
|
||||||
|
@scope = @event_types.select {|t| params["show_#{t}"]}
|
||||||
|
# default events if none is specified in parameters
|
||||||
|
@scope = (@event_types - %w(wiki_pages messages))if @scope.empty?
|
||||||
|
|
||||||
|
@events = []
|
||||||
|
|
||||||
|
if @scope.include?('issues')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_issues, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Issue.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Issue.find(:all, :include => [:project, :author, :tracker], :conditions => cond.conditions)
|
||||||
|
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_issues, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Journal.table_name}.journalized_type = 'Issue' AND #{JournalDetail.table_name}.prop_key = 'status_id' AND #{Journal.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Journal.find(:all, :include => [{:issue => :project}, :details, :user], :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('news')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_news, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{News.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += News.find(:all, :include => [:project, :author], :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('files')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_files, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Attachment.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*",
|
||||||
|
:joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
|
||||||
|
"LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id",
|
||||||
|
:conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('documents')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_documents, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Document.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Document.find(:all, :include => :project, :conditions => cond.conditions)
|
||||||
|
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_documents, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Attachment.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*",
|
||||||
|
:joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
|
||||||
|
"LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id",
|
||||||
|
:conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('wiki_pages')
|
||||||
|
select = "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
|
||||||
|
"#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
|
||||||
|
"#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
|
||||||
|
"#{WikiContent.versioned_table_name}.id"
|
||||||
|
joins = "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
|
||||||
|
"LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
|
||||||
|
"LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"
|
||||||
|
|
||||||
events = @activity.events(@date_from, @date_to)
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_wiki_pages, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{WikiContent.versioned_table_name}.updated_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('changesets')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_changesets, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Changeset.find(:all, :include => {:repository => :project}, :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('messages')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_messages, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Message.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Message.find(:all, :include => [{:board => :project}, :author], :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
@events_by_day = @events.group_by(&:event_date)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {
|
format.html { render :layout => false if request.xhr? }
|
||||||
@events_by_day = events.group_by(&:event_date)
|
format.atom { render_feed(@events, :title => "#{@project || Setting.app_title}: #{l(:label_activity)}") }
|
||||||
render :layout => false if request.xhr?
|
|
||||||
}
|
|
||||||
format.atom {
|
|
||||||
title = (@activity.scope.size == 1) ? l("label_#{@activity.scope.first.singularize}_plural") : l(:label_activity)
|
|
||||||
render_feed(events, :title => "#{@project || Setting.app_title}: #{title}")
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -306,18 +386,11 @@ class ProjectsController < ApplicationController
|
|||||||
|
|
||||||
@events = []
|
@events = []
|
||||||
@project.issues_with_subprojects(@with_subprojects) do
|
@project.issues_with_subprojects(@with_subprojects) do
|
||||||
# Issues that have start and due dates
|
|
||||||
@events += Issue.find(:all,
|
@events += Issue.find(:all,
|
||||||
:order => "start_date, due_date",
|
:order => "start_date, due_date",
|
||||||
:include => [:tracker, :status, :assigned_to, :priority, :project],
|
:include => [:tracker, :status, :assigned_to, :priority, :project],
|
||||||
:conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
|
:conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
|
||||||
) unless @selected_tracker_ids.empty?
|
) unless @selected_tracker_ids.empty?
|
||||||
# Issues that don't have a due date but that are assigned to a version with a date
|
|
||||||
@events += Issue.find(:all,
|
|
||||||
:order => "start_date, effective_date",
|
|
||||||
:include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version],
|
|
||||||
:conditions => ["(((start_date>=? and start_date<=?) or (effective_date>=? and effective_date<=?) or (start_date<? and effective_date>?)) and start_date is not null and due_date is null and effective_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
|
|
||||||
) unless @selected_tracker_ids.empty?
|
|
||||||
@events += Version.find(:all, :include => :project,
|
@events += Version.find(:all, :include => :project,
|
||||||
:conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
|
:conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
end
|
end
|
||||||
+1
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class QueriesController < ApplicationController
|
class QueriesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :issues
|
menu_item :issues
|
||||||
before_filter :find_query, :except => :new
|
before_filter :find_query, :except => :new
|
||||||
before_filter :find_optional_project, :only => :new
|
before_filter :find_optional_project, :only => :new
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class ReportsController < ApplicationController
|
class ReportsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :issues
|
menu_item :issues
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
+39
-39
@@ -23,21 +23,20 @@ class ChangesetNotFound < Exception; end
|
|||||||
class InvalidRevisionParam < Exception; end
|
class InvalidRevisionParam < Exception; end
|
||||||
|
|
||||||
class RepositoriesController < ApplicationController
|
class RepositoriesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :repository
|
menu_item :repository
|
||||||
before_filter :find_repository, :except => :edit
|
before_filter :find_repository, :except => :edit
|
||||||
before_filter :find_project, :only => :edit
|
before_filter :find_project, :only => :edit
|
||||||
before_filter :authorize
|
before_filter :authorize
|
||||||
accept_key_auth :revisions
|
accept_key_auth :revisions
|
||||||
|
|
||||||
rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
|
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@repository = @project.repository
|
@repository = @project.repository
|
||||||
if !@repository
|
if !@repository
|
||||||
@repository = Repository.factory(params[:repository_scm])
|
@repository = Repository.factory(params[:repository_scm])
|
||||||
@repository.project = @project if @repository
|
@repository.project = @project
|
||||||
end
|
end
|
||||||
if request.post? && @repository
|
if request.post?
|
||||||
@repository.attributes = params[:repository]
|
@repository.attributes = params[:repository]
|
||||||
@repository.save
|
@repository.save
|
||||||
end
|
end
|
||||||
@@ -57,6 +56,8 @@ class RepositoriesController < ApplicationController
|
|||||||
# latest changesets
|
# latest changesets
|
||||||
@changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
|
@changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
|
||||||
show_error_not_found unless @entries || @changesets.any?
|
show_error_not_found unless @entries || @changesets.any?
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def browse
|
def browse
|
||||||
@@ -65,16 +66,18 @@ class RepositoriesController < ApplicationController
|
|||||||
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
|
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
|
||||||
else
|
else
|
||||||
show_error_not_found and return unless @entries
|
show_error_not_found and return unless @entries
|
||||||
@properties = @repository.properties(@path, @rev)
|
|
||||||
render :action => 'browse'
|
render :action => 'browse'
|
||||||
end
|
end
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def changes
|
def changes
|
||||||
@entry = @repository.entry(@path, @rev)
|
@entry = @repository.scm.entry(@path, @rev)
|
||||||
show_error_not_found and return unless @entry
|
show_error_not_found and return unless @entry
|
||||||
@changesets = @repository.changesets_for_path(@path)
|
@changesets = @repository.changesets_for_path(@path)
|
||||||
@properties = @repository.properties(@path, @rev)
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions
|
def revisions
|
||||||
@@ -93,13 +96,13 @@ class RepositoriesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def entry
|
def entry
|
||||||
@entry = @repository.entry(@path, @rev)
|
@entry = @repository.scm.entry(@path, @rev)
|
||||||
show_error_not_found and return unless @entry
|
show_error_not_found and return unless @entry
|
||||||
|
|
||||||
# If the entry is a dir, show the browser
|
# If the entry is a dir, show the browser
|
||||||
browse and return if @entry.is_dir?
|
browse and return if @entry.is_dir?
|
||||||
|
|
||||||
@content = @repository.cat(@path, @rev)
|
@content = @repository.scm.cat(@path, @rev)
|
||||||
show_error_not_found and return unless @content
|
show_error_not_found and return unless @content
|
||||||
if 'raw' == params[:format] || @content.is_binary_data?
|
if 'raw' == params[:format] || @content.is_binary_data?
|
||||||
# Force the download if it's a binary file
|
# Force the download if it's a binary file
|
||||||
@@ -107,12 +110,16 @@ class RepositoriesController < ApplicationController
|
|||||||
else
|
else
|
||||||
# Prevent empty lines when displaying a file with Windows style eol
|
# Prevent empty lines when displaying a file with Windows style eol
|
||||||
@content.gsub!("\r\n", "\n")
|
@content.gsub!("\r\n", "\n")
|
||||||
end
|
end
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def annotate
|
def annotate
|
||||||
@annotate = @repository.scm.annotate(@path, @rev)
|
@annotate = @repository.scm.annotate(@path, @rev)
|
||||||
render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
|
render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revision
|
def revision
|
||||||
@@ -130,33 +137,27 @@ class RepositoriesController < ApplicationController
|
|||||||
end
|
end
|
||||||
rescue ChangesetNotFound
|
rescue ChangesetNotFound
|
||||||
show_error_not_found
|
show_error_not_found
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff
|
def diff
|
||||||
if params[:format] == 'diff'
|
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
|
||||||
@diff = @repository.diff(@path, @rev, @rev_to)
|
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
|
||||||
show_error_not_found and return unless @diff
|
|
||||||
filename = "changeset_r#{@rev}"
|
# Save diff type as user preference
|
||||||
filename << "_r#{@rev_to}" if @rev_to
|
if User.current.logged? && @diff_type != User.current.pref[:diff_type]
|
||||||
send_data @diff.join, :filename => "#{filename}.diff",
|
User.current.pref[:diff_type] = @diff_type
|
||||||
:type => 'text/x-patch',
|
User.current.preference.save
|
||||||
:disposition => 'attachment'
|
|
||||||
else
|
|
||||||
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
|
|
||||||
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
|
|
||||||
|
|
||||||
# Save diff type as user preference
|
|
||||||
if User.current.logged? && @diff_type != User.current.pref[:diff_type]
|
|
||||||
User.current.pref[:diff_type] = @diff_type
|
|
||||||
User.current.preference.save
|
|
||||||
end
|
|
||||||
|
|
||||||
@cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
|
|
||||||
unless read_fragment(@cache_key)
|
|
||||||
@diff = @repository.diff(@path, @rev, @rev_to)
|
|
||||||
show_error_not_found unless @diff
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
|
||||||
|
unless read_fragment(@cache_key)
|
||||||
|
@diff = @repository.diff(@path, @rev, @rev_to, @diff_type)
|
||||||
|
show_error_not_found unless @diff
|
||||||
|
end
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def stats
|
def stats
|
||||||
@@ -206,9 +207,8 @@ private
|
|||||||
render_error l(:error_scm_not_found)
|
render_error l(:error_scm_not_found)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Handler for Redmine::Scm::Adapters::CommandFailed exception
|
def show_error_command_failed(msg)
|
||||||
def show_error_command_failed(exception)
|
render_error l(:error_scm_command_failed, msg)
|
||||||
render_error l(:error_scm_command_failed, exception.message)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def graph_commits_per_month(repository)
|
def graph_commits_per_month(repository)
|
||||||
@@ -229,7 +229,7 @@ private
|
|||||||
|
|
||||||
graph = SVG::Graph::Bar.new(
|
graph = SVG::Graph::Bar.new(
|
||||||
:height => 300,
|
:height => 300,
|
||||||
:width => 800,
|
:width => 500,
|
||||||
:fields => fields.reverse,
|
:fields => fields.reverse,
|
||||||
:stack => :side,
|
:stack => :side,
|
||||||
:scale_integers => true,
|
:scale_integers => true,
|
||||||
@@ -271,8 +271,8 @@ private
|
|||||||
fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
|
fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
|
||||||
|
|
||||||
graph = SVG::Graph::BarHorizontal.new(
|
graph = SVG::Graph::BarHorizontal.new(
|
||||||
:height => 400,
|
:height => 300,
|
||||||
:width => 800,
|
:width => 500,
|
||||||
:fields => fields,
|
:fields => fields,
|
||||||
:stack => :side,
|
:stack => :side,
|
||||||
:scale_integers => true,
|
:scale_integers => true,
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class RolesController < ApplicationController
|
class RolesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :require_admin
|
before_filter :require_admin
|
||||||
|
|
||||||
verify :method => :post, :only => [ :destroy, :move ],
|
verify :method => :post, :only => [ :destroy, :move ],
|
||||||
+5
-6
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
class SearchController < ApplicationController
|
class SearchController < ApplicationController
|
||||||
layout 'base'
|
layout 'base'
|
||||||
|
|
||||||
|
before_filter :find_optional_project
|
||||||
|
|
||||||
helper :messages
|
helper :messages
|
||||||
include MessagesHelper
|
include MessagesHelper
|
||||||
@@ -36,11 +38,6 @@ class SearchController < ApplicationController
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:id]
|
|
||||||
find_project
|
|
||||||
return unless check_project_privacy
|
|
||||||
end
|
|
||||||
|
|
||||||
if @project
|
if @project
|
||||||
# only show what the user is allowed to view
|
# only show what the user is allowed to view
|
||||||
@object_types = %w(issues news documents changesets wiki_pages messages)
|
@object_types = %w(issues news documents changesets wiki_pages messages)
|
||||||
@@ -104,8 +101,10 @@ class SearchController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_project
|
def find_optional_project
|
||||||
|
return true unless params[:id]
|
||||||
@project = Project.find(params[:id])
|
@project = Project.find(params[:id])
|
||||||
|
check_project_privacy
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
+2
-2
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class SettingsController < ApplicationController
|
class SettingsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :require_admin
|
before_filter :require_admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@@ -38,7 +39,6 @@ class SettingsController < ApplicationController
|
|||||||
end
|
end
|
||||||
@options = {}
|
@options = {}
|
||||||
@options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
|
@options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
|
||||||
@deliveries = ActionMailer::Base.perform_deliveries
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def plugin
|
def plugin
|
||||||
@@ -49,7 +49,7 @@ class SettingsController < ApplicationController
|
|||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'plugin', :id => params[:id]
|
redirect_to :action => 'plugin', :id => params[:id]
|
||||||
end
|
end
|
||||||
@partial = @plugin.settings[:partial]
|
@partial = "../../vendor/plugins/#{plugin_id}/app/views/" + @plugin.settings[:partial]
|
||||||
@settings = Setting["plugin_#{plugin_id}"]
|
@settings = Setting["plugin_#{plugin_id}"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
File renamed without changes.
+10
-18
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class TimelogController < ApplicationController
|
class TimelogController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :issues
|
menu_item :issues
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
@@ -53,15 +54,8 @@ class TimelogController < ApplicationController
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Add list and boolean custom fields as available criterias
|
# Add list and boolean custom fields as available criterias
|
||||||
@project.all_issue_custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
@project.all_custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
||||||
@available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)",
|
@available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM custom_values c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = issues.id)",
|
||||||
:format => cf.field_format,
|
|
||||||
:label => cf.name}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add list and boolean time entry custom fields
|
|
||||||
TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
|
||||||
@available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
|
|
||||||
:format => cf.field_format,
|
:format => cf.field_format,
|
||||||
:label => cf.name}
|
:label => cf.name}
|
||||||
end
|
end
|
||||||
@@ -135,7 +129,12 @@ class TimelogController < ApplicationController
|
|||||||
|
|
||||||
def details
|
def details
|
||||||
sort_init 'spent_on', 'desc'
|
sort_init 'spent_on', 'desc'
|
||||||
sort_update
|
sort_update 'spent_on' => 'spent_on',
|
||||||
|
'user' => 'user_id',
|
||||||
|
'activity' => 'activity_id',
|
||||||
|
'project' => "#{Project.table_name}.name",
|
||||||
|
'issue' => 'issue_id',
|
||||||
|
'hours' => 'hours'
|
||||||
|
|
||||||
cond = ARCondition.new
|
cond = ARCondition.new
|
||||||
cond << (@issue.nil? ? @project.project_condition(Setting.display_subprojects_issues?) :
|
cond << (@issue.nil? ? @project.project_condition(Setting.display_subprojects_issues?) :
|
||||||
@@ -160,14 +159,6 @@ class TimelogController < ApplicationController
|
|||||||
|
|
||||||
render :layout => !request.xhr?
|
render :layout => !request.xhr?
|
||||||
}
|
}
|
||||||
format.atom {
|
|
||||||
entries = TimeEntry.find(:all,
|
|
||||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
|
||||||
:conditions => cond.conditions,
|
|
||||||
:order => "#{TimeEntry.table_name}.created_on DESC",
|
|
||||||
:limit => Setting.feeds_limit.to_i)
|
|
||||||
render_feed(entries, :title => l(:label_spent_time))
|
|
||||||
}
|
|
||||||
format.csv {
|
format.csv {
|
||||||
# Export all entries
|
# Export all entries
|
||||||
@entries = TimeEntry.find(:all,
|
@entries = TimeEntry.find(:all,
|
||||||
@@ -189,6 +180,7 @@ class TimelogController < ApplicationController
|
|||||||
redirect_to(params[:back_url].blank? ? {:action => 'details', :project_id => @time_entry.project} : params[:back_url])
|
redirect_to(params[:back_url].blank? ? {:action => 'details', :project_id => @time_entry.project} : params[:back_url])
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@activities = Enumeration::get_values('ACTI')
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
+1
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class TrackersController < ApplicationController
|
class TrackersController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :require_admin
|
before_filter :require_admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
+5
-4
@@ -31,10 +31,10 @@ class UsersController < ApplicationController
|
|||||||
|
|
||||||
def list
|
def list
|
||||||
sort_init 'login', 'asc'
|
sort_init 'login', 'asc'
|
||||||
sort_update
|
sort_update %w(login firstname lastname mail admin created_on last_login_on)
|
||||||
|
|
||||||
@status = params[:status] ? params[:status].to_i : 1
|
@status = params[:status] ? params[:status].to_i : 1
|
||||||
conditions = nil
|
conditions = "status <> 0"
|
||||||
conditions = ["status=?", @status] unless @status == 0
|
conditions = ["status=?", @status] unless @status == 0
|
||||||
|
|
||||||
@user_count = User.count(:conditions => conditions)
|
@user_count = User.count(:conditions => conditions)
|
||||||
@@ -83,7 +83,8 @@ class UsersController < ApplicationController
|
|||||||
end
|
end
|
||||||
if @user.update_attributes(params[:user])
|
if @user.update_attributes(params[:user])
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'list'
|
# Give a string to redirect_to otherwise it would use status param as the response code
|
||||||
|
redirect_to(url_for(:action => 'list', :status => params[:status], :page => params[:page]))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@auth_sources = AuthSource.find(:all)
|
@auth_sources = AuthSource.find(:all)
|
||||||
+3
-3
@@ -17,10 +17,9 @@
|
|||||||
|
|
||||||
class VersionsController < ApplicationController
|
class VersionsController < ApplicationController
|
||||||
layout 'base'
|
layout 'base'
|
||||||
|
menu_item :roadmap
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
cache_sweeper :version_sweeper, :only => [ :edit, :destroy ]
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -42,7 +41,8 @@ class VersionsController < ApplicationController
|
|||||||
def download
|
def download
|
||||||
@attachment = @version.attachments.find(params[:attachment_id])
|
@attachment = @version.attachments.find(params[:attachment_id])
|
||||||
@attachment.increment_download
|
@attachment.increment_download
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename, :type => @attachment.content_type
|
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
|
||||||
|
:type => @attachment.content_type
|
||||||
rescue
|
rescue
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class WikisController < ApplicationController
|
class WikisController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :settings
|
menu_item :settings
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
File renamed without changes.
File renamed without changes.
@@ -15,9 +15,6 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'coderay'
|
|
||||||
require 'coderay/helpers/file_type'
|
|
||||||
|
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
include Redmine::WikiFormatting::Macros::Definitions
|
include Redmine::WikiFormatting::Macros::Definitions
|
||||||
|
|
||||||
@@ -41,23 +38,9 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def link_to_issue(issue, options={})
|
def link_to_issue(issue, options={})
|
||||||
options[:class] ||= ''
|
|
||||||
options[:class] << ' issue'
|
|
||||||
options[:class] << ' closed' if issue.closed?
|
|
||||||
link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
|
link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
|
||||||
end
|
end
|
||||||
|
|
||||||
# Generates a link to an attachment.
|
|
||||||
# Options:
|
|
||||||
# * :text - Link text (default to attachment filename)
|
|
||||||
# * :download - Force download (default: false)
|
|
||||||
def link_to_attachment(attachment, options={})
|
|
||||||
text = options.delete(:text) || attachment.filename
|
|
||||||
action = options.delete(:download) ? 'download' : 'show'
|
|
||||||
|
|
||||||
link_to(h(text), {:controller => 'attachments', :action => action, :id => attachment, :filename => attachment.filename }, options)
|
|
||||||
end
|
|
||||||
|
|
||||||
def toggle_link(name, id, options={})
|
def toggle_link(name, id, options={})
|
||||||
onclick = "Element.toggle('#{id}'); "
|
onclick = "Element.toggle('#{id}'); "
|
||||||
onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
|
onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
|
||||||
@@ -65,6 +48,14 @@ module ApplicationHelper
|
|||||||
link_to(name, "#", :onclick => onclick)
|
link_to(name, "#", :onclick => onclick)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_and_goto_link(name, id, options={})
|
||||||
|
onclick = "Element.show('#{id}'); "
|
||||||
|
onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
|
||||||
|
onclick << "Element.scrollTo('#{id}'); "
|
||||||
|
onclick << "return false;"
|
||||||
|
link_to(name, "#", options.merge(:onclick => onclick))
|
||||||
|
end
|
||||||
|
|
||||||
def image_to_function(name, function, html_options = {})
|
def image_to_function(name, function, html_options = {})
|
||||||
html_options.symbolize_keys!
|
html_options.symbolize_keys!
|
||||||
tag(:input, html_options.merge({
|
tag(:input, html_options.merge({
|
||||||
@@ -89,7 +80,11 @@ module ApplicationHelper
|
|||||||
return nil unless time
|
return nil unless time
|
||||||
time = time.to_time if time.is_a?(String)
|
time = time.to_time if time.is_a?(String)
|
||||||
zone = User.current.time_zone
|
zone = User.current.time_zone
|
||||||
local = zone ? time.in_time_zone(zone) : (time.utc? ? time.utc_to_local : time)
|
if time.utc?
|
||||||
|
local = zone ? zone.adjust(time) : time.getlocal
|
||||||
|
else
|
||||||
|
local = zone ? zone.adjust(time.getutc) : time
|
||||||
|
end
|
||||||
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
|
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
|
||||||
@time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
|
@time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
|
||||||
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
|
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
|
||||||
@@ -106,8 +101,7 @@ module ApplicationHelper
|
|||||||
|
|
||||||
def authoring(created, author)
|
def authoring(created, author)
|
||||||
time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
|
time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
|
||||||
author_tag = (author.is_a?(User) && !author.anonymous?) ? link_to(h(author), :controller => 'account', :action => 'show', :id => author) : h(author || 'Anonymous')
|
l(:label_added_time_by, author || 'Anonymous', time_tag)
|
||||||
l(:label_added_time_by, author_tag, time_tag)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def l_or_humanize(s)
|
def l_or_humanize(s)
|
||||||
@@ -122,15 +116,6 @@ module ApplicationHelper
|
|||||||
l(:actionview_datehelper_select_month_names).split(',')[month-1]
|
l(:actionview_datehelper_select_month_names).split(',')[month-1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def syntax_highlight(name, content)
|
|
||||||
type = CodeRay::FileType[name]
|
|
||||||
type ? CodeRay.scan(content, type).html : h(content)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_path_param(path)
|
|
||||||
path.to_s.split(%r{[/\\]}).select {|p| !p.blank?}
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_links_full(paginator, count=nil, options={})
|
def pagination_links_full(paginator, count=nil, options={})
|
||||||
page_param = options.delete(:page_param) || :page
|
page_param = options.delete(:page_param) || :page
|
||||||
url_param = params.dup
|
url_param = params.dup
|
||||||
@@ -177,8 +162,7 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def breadcrumb(*args)
|
def breadcrumb(*args)
|
||||||
elements = args.flatten
|
content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb')
|
||||||
elements.any? ? content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb') : nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def html_title(*args)
|
def html_title(*args)
|
||||||
@@ -206,7 +190,7 @@ module ApplicationHelper
|
|||||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||||
case args.size
|
case args.size
|
||||||
when 1
|
when 1
|
||||||
obj = options[:object]
|
obj = nil
|
||||||
text = args.shift
|
text = args.shift
|
||||||
when 2
|
when 2
|
||||||
obj = args.shift
|
obj = args.shift
|
||||||
@@ -246,12 +230,12 @@ module ApplicationHelper
|
|||||||
case options[:wiki_links]
|
case options[:wiki_links]
|
||||||
when :local
|
when :local
|
||||||
# used for local links to html files
|
# used for local links to html files
|
||||||
format_wiki_link = Proc.new {|project, title, anchor| "#{title}.html" }
|
format_wiki_link = Proc.new {|project, title| "#{title}.html" }
|
||||||
when :anchor
|
when :anchor
|
||||||
# used for single-file wiki export
|
# used for single-file wiki export
|
||||||
format_wiki_link = Proc.new {|project, title, anchor| "##{title}" }
|
format_wiki_link = Proc.new {|project, title| "##{title}" }
|
||||||
else
|
else
|
||||||
format_wiki_link = Proc.new {|project, title, anchor| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title, :anchor => anchor) }
|
format_wiki_link = Proc.new {|project, title| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title) }
|
||||||
end
|
end
|
||||||
|
|
||||||
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
|
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
|
||||||
@@ -277,14 +261,9 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
if link_project && link_project.wiki
|
if link_project && link_project.wiki
|
||||||
# extract anchor
|
|
||||||
anchor = nil
|
|
||||||
if page =~ /^(.+?)\#(.+)$/
|
|
||||||
page, anchor = $1, $2
|
|
||||||
end
|
|
||||||
# check if page exists
|
# check if page exists
|
||||||
wiki_page = link_project.wiki.find_page(page)
|
wiki_page = link_project.wiki.find_page(page)
|
||||||
link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page), anchor),
|
link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
|
||||||
:class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
:class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
||||||
else
|
else
|
||||||
# project or wiki doesn't exist
|
# project or wiki doesn't exist
|
||||||
@@ -319,9 +298,7 @@ module ApplicationHelper
|
|||||||
# source:some/file#L120 -> Link to line 120 of the file
|
# source:some/file#L120 -> Link to line 120 of the file
|
||||||
# source:some/file@52#L120 -> Link to line 120 of the file's revision 52
|
# source:some/file@52#L120 -> Link to line 120 of the file's revision 52
|
||||||
# export:some/file -> Force the download of the file
|
# export:some/file -> Force the download of the file
|
||||||
# Forum messages:
|
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
|
||||||
# message#1218 -> Link to message with id 1218
|
|
||||||
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|\s|<|$)}) do |m|
|
|
||||||
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
|
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
|
||||||
link = nil
|
link = nil
|
||||||
if esc.nil?
|
if esc.nil?
|
||||||
@@ -351,16 +328,6 @@ module ApplicationHelper
|
|||||||
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
|
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
|
||||||
:class => 'version'
|
:class => 'version'
|
||||||
end
|
end
|
||||||
when 'message'
|
|
||||||
if message = Message.find_by_id(oid, :include => [:parent, {:board => :project}], :conditions => Project.visible_by(User.current))
|
|
||||||
link = link_to h(truncate(message.subject, 60)), {:only_path => only_path,
|
|
||||||
:controller => 'messages',
|
|
||||||
:action => 'show',
|
|
||||||
:board_id => message.board,
|
|
||||||
:id => message.root,
|
|
||||||
:anchor => (message.parent ? "message-#{message.id}" : nil)},
|
|
||||||
:class => 'message'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
elsif sep == ':'
|
elsif sep == ':'
|
||||||
# removes the double quotes if any
|
# removes the double quotes if any
|
||||||
@@ -386,8 +353,7 @@ module ApplicationHelper
|
|||||||
if project && project.repository
|
if project && project.repository
|
||||||
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
|
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
|
||||||
path, rev, anchor = $1, $3, $5
|
path, rev, anchor = $1, $3, $5
|
||||||
link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project,
|
link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, :path => path,
|
||||||
:path => to_path_param(path),
|
|
||||||
:rev => rev,
|
:rev => rev,
|
||||||
:anchor => anchor,
|
:anchor => anchor,
|
||||||
:format => (prefix == 'export' ? 'raw' : nil)},
|
:format => (prefix == 'export' ? 'raw' : nil)},
|
||||||
@@ -469,8 +435,7 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def back_url_hidden_field_tag
|
def back_url_hidden_field_tag
|
||||||
back_url = params[:back_url] || request.env['HTTP_REFERER']
|
hidden_field_tag 'back_url', (params[:back_url] || request.env['HTTP_REFERER'])
|
||||||
hidden_field_tag('back_url', back_url) unless back_url.blank?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_all_links(form_name)
|
def check_all_links(form_name)
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+9
-2
@@ -17,6 +17,13 @@
|
|||||||
|
|
||||||
module CustomFieldsHelper
|
module CustomFieldsHelper
|
||||||
|
|
||||||
|
def custom_fields_tabs
|
||||||
|
tabs = [{:name => 'IssueCustomField', :label => :label_issue_plural},
|
||||||
|
{:name => 'ProjectCustomField', :label => :label_project_plural},
|
||||||
|
{:name => 'UserCustomField', :label => :label_user_plural}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
# Return custom field html tag corresponding to its format
|
# Return custom field html tag corresponding to its format
|
||||||
def custom_field_tag(custom_value)
|
def custom_field_tag(custom_value)
|
||||||
custom_field = custom_value.custom_field
|
custom_field = custom_value.custom_field
|
||||||
@@ -28,7 +35,7 @@ module CustomFieldsHelper
|
|||||||
text_field('custom_value', 'value', :name => field_name, :id => field_id, :size => 10) +
|
text_field('custom_value', 'value', :name => field_name, :id => field_id, :size => 10) +
|
||||||
calendar_for(field_id)
|
calendar_for(field_id)
|
||||||
when "text"
|
when "text"
|
||||||
text_area 'custom_value', 'value', :name => field_name, :id => field_id, :cols => 60, :rows => 3
|
text_area 'custom_value', 'value', :name => field_name, :id => field_id, :rows => 3, :style => 'width:99%'
|
||||||
when "bool"
|
when "bool"
|
||||||
check_box 'custom_value', 'value', :name => field_name, :id => field_id
|
check_box 'custom_value', 'value', :name => field_name, :id => field_id
|
||||||
when "list"
|
when "list"
|
||||||
@@ -62,7 +69,7 @@ module CustomFieldsHelper
|
|||||||
return "" unless value && !value.empty?
|
return "" unless value && !value.empty?
|
||||||
case field_format
|
case field_format
|
||||||
when "date"
|
when "date"
|
||||||
begin; l_date(value.to_date); rescue; value end
|
begin; format_date(value.to_date); rescue; value end
|
||||||
when "bool"
|
when "bool"
|
||||||
l_YesNo(value == "1")
|
l_YesNo(value == "1")
|
||||||
else
|
else
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -54,15 +54,9 @@ module IssuesHelper
|
|||||||
when 'due_date', 'start_date'
|
when 'due_date', 'start_date'
|
||||||
value = format_date(detail.value.to_date) if detail.value
|
value = format_date(detail.value.to_date) if detail.value
|
||||||
old_value = format_date(detail.old_value.to_date) if detail.old_value
|
old_value = format_date(detail.old_value.to_date) if detail.old_value
|
||||||
when 'project_id'
|
|
||||||
p = Project.find_by_id(detail.value) and value = p.name if detail.value
|
|
||||||
p = Project.find_by_id(detail.old_value) and old_value = p.name if detail.old_value
|
|
||||||
when 'status_id'
|
when 'status_id'
|
||||||
s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
|
s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
|
||||||
s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
|
s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
|
||||||
when 'tracker_id'
|
|
||||||
t = Tracker.find_by_id(detail.value) and value = t.name if detail.value
|
|
||||||
t = Tracker.find_by_id(detail.old_value) and old_value = t.name if detail.old_value
|
|
||||||
when 'assigned_to_id'
|
when 'assigned_to_id'
|
||||||
u = User.find_by_id(detail.value) and value = u.name if detail.value
|
u = User.find_by_id(detail.value) and value = u.name if detail.value
|
||||||
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
|
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
|
||||||
@@ -86,8 +80,7 @@ module IssuesHelper
|
|||||||
when 'attachment'
|
when 'attachment'
|
||||||
label = l(:label_attachment)
|
label = l(:label_attachment)
|
||||||
end
|
end
|
||||||
call_hook(:helper_issues_show_detail_after_setting, {:detail => detail, :label => label, :value => value, :old_value => old_value })
|
|
||||||
|
|
||||||
label ||= detail.prop_key
|
label ||= detail.prop_key
|
||||||
value ||= detail.value
|
value ||= detail.value
|
||||||
old_value ||= detail.old_value
|
old_value ||= detail.old_value
|
||||||
@@ -96,9 +89,9 @@ module IssuesHelper
|
|||||||
label = content_tag('strong', label)
|
label = content_tag('strong', label)
|
||||||
old_value = content_tag("i", h(old_value)) if detail.old_value
|
old_value = content_tag("i", h(old_value)) if detail.old_value
|
||||||
old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
|
old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
|
||||||
if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key)
|
if detail.property == 'attachment' && !value.blank? && Attachment.find_by_id(detail.prop_key)
|
||||||
# Link to the attachment if it has not been removed
|
# Link to the attachment if it has not been removed
|
||||||
value = link_to_attachment(a)
|
value = link_to(value, :controller => 'attachments', :action => 'download', :id => detail.prop_key)
|
||||||
else
|
else
|
||||||
value = content_tag("i", h(value)) if value
|
value = content_tag("i", h(value)) if value
|
||||||
end
|
end
|
||||||
@@ -127,7 +120,6 @@ module IssuesHelper
|
|||||||
|
|
||||||
def issues_to_csv(issues, project = nil)
|
def issues_to_csv(issues, project = nil)
|
||||||
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
||||||
decimal_separator = l(:general_csv_decimal_separator)
|
|
||||||
export = StringIO.new
|
export = StringIO.new
|
||||||
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
||||||
# csv header fields
|
# csv header fields
|
||||||
@@ -150,7 +142,7 @@ module IssuesHelper
|
|||||||
]
|
]
|
||||||
# Export project custom fields if project is given
|
# Export project custom fields if project is given
|
||||||
# otherwise export custom fields marked as "For all projects"
|
# otherwise export custom fields marked as "For all projects"
|
||||||
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_issue_custom_fields
|
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_custom_fields
|
||||||
custom_fields.each {|f| headers << f.name}
|
custom_fields.each {|f| headers << f.name}
|
||||||
# Description in the last column
|
# Description in the last column
|
||||||
headers << l(:field_description)
|
headers << l(:field_description)
|
||||||
@@ -170,7 +162,7 @@ module IssuesHelper
|
|||||||
format_date(issue.start_date),
|
format_date(issue.start_date),
|
||||||
format_date(issue.due_date),
|
format_date(issue.due_date),
|
||||||
issue.done_ratio,
|
issue.done_ratio,
|
||||||
issue.estimated_hours.to_s.gsub('.', decimal_separator),
|
issue.estimated_hours,
|
||||||
format_time(issue.created_on),
|
format_time(issue.created_on),
|
||||||
format_time(issue.updated_on)
|
format_time(issue.updated_on)
|
||||||
]
|
]
|
||||||
@@ -19,16 +19,13 @@ module JournalsHelper
|
|||||||
def render_notes(journal, options={})
|
def render_notes(journal, options={})
|
||||||
content = ''
|
content = ''
|
||||||
editable = journal.editable_by?(User.current)
|
editable = journal.editable_by?(User.current)
|
||||||
links = []
|
if editable && !journal.notes.blank?
|
||||||
if !journal.notes.blank?
|
links = []
|
||||||
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
|
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
|
||||||
{ :controller => 'journals', :action => 'edit', :id => journal },
|
{ :controller => 'journals', :action => 'edit', :id => journal },
|
||||||
:title => l(:button_edit)) if editable
|
:title => l(:button_edit))
|
||||||
links << link_to_remote(image_tag('comment.png'),
|
content << content_tag('div', links.join(' '), :class => 'contextual')
|
||||||
{ :url => {:controller => 'issues', :action => 'reply', :id => journal.journalized, :journal_id => journal} },
|
|
||||||
:title => l(:button_reply)) if options[:reply_links]
|
|
||||||
end
|
end
|
||||||
content << content_tag('div', links.join(' '), :class => 'contextual') unless links.empty?
|
|
||||||
content << textilizable(journal, :notes)
|
content << textilizable(journal, :notes)
|
||||||
content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => (editable ? 'wiki editable' : 'wiki'))
|
content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => (editable ? 'wiki editable' : 'wiki'))
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -30,7 +30,7 @@ module ProjectsHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def format_activity_description(text)
|
def format_activity_description(text)
|
||||||
h(truncate(text.to_s, 250).gsub(%r{<(pre|code)>.*$}m, '...'))
|
h(truncate(text, 250))
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_settings_tabs
|
def project_settings_tabs
|
||||||
@@ -22,8 +22,8 @@ module QueriesHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def column_header(column)
|
def column_header(column)
|
||||||
column.sortable ? sort_header_tag(column.sortable, :caption => column.caption,
|
column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
|
||||||
:default_order => column.default_order) :
|
:default_order => column.default_order) :
|
||||||
content_tag('th', column.caption)
|
content_tag('th', column.caption)
|
||||||
end
|
end
|
||||||
|
|
||||||
File renamed without changes.
+13
-2
@@ -25,6 +25,10 @@ module RepositoriesHelper
|
|||||||
type ? CodeRay.scan(content, type).html : h(content)
|
type ? CodeRay.scan(content, type).html : h(content)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def format_revision(txt)
|
||||||
|
txt.to_s[0,8]
|
||||||
|
end
|
||||||
|
|
||||||
def to_utf8(str)
|
def to_utf8(str)
|
||||||
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
|
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
|
||||||
@encodings ||= Setting.repositories_encodings.split(',').collect(&:strip)
|
@encodings ||= Setting.repositories_encodings.split(',').collect(&:strip)
|
||||||
@@ -54,8 +58,11 @@ module RepositoriesHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def with_leading_slash(path)
|
def with_leading_slash(path)
|
||||||
path ||= ''
|
path.to_s.starts_with?('/') ? path : "/#{path}"
|
||||||
path.starts_with?('/') ? path : "/#{path}"
|
end
|
||||||
|
|
||||||
|
def without_leading_slash(path)
|
||||||
|
path.gsub(%r{^/+}, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
def subversion_field_tags(form, repository)
|
def subversion_field_tags(form, repository)
|
||||||
@@ -76,6 +83,10 @@ module RepositoriesHelper
|
|||||||
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
|
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def git_field_tags(form, repository)
|
||||||
|
content_tag('p', form.text_field(:url, :label => 'Path to .git directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
|
||||||
|
end
|
||||||
|
|
||||||
def cvs_field_tags(form, repository)
|
def cvs_field_tags(form, repository)
|
||||||
content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
|
content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
|
||||||
content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
|
content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
|
||||||
File renamed without changes.
File renamed without changes.
@@ -19,7 +19,6 @@ module SettingsHelper
|
|||||||
def administration_settings_tabs
|
def administration_settings_tabs
|
||||||
tabs = [{:name => 'general', :partial => 'settings/general', :label => :label_general},
|
tabs = [{:name => 'general', :partial => 'settings/general', :label => :label_general},
|
||||||
{:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
|
{:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
|
||||||
{:name => 'projects', :partial => 'settings/projects', :label => :label_project_plural},
|
|
||||||
{:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
|
{:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
|
||||||
{:name => 'notifications', :partial => 'settings/notifications', :label => l(:field_mail_notification)},
|
{:name => 'notifications', :partial => 'settings/notifications', :label => l(:field_mail_notification)},
|
||||||
{:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
|
{:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
|
||||||
@@ -67,23 +67,31 @@ module SortHelper
|
|||||||
|
|
||||||
# Updates the sort state. Call this in the controller prior to calling
|
# Updates the sort state. Call this in the controller prior to calling
|
||||||
# sort_clause.
|
# sort_clause.
|
||||||
#
|
# sort_keys can be either an array or a hash of allowed keys
|
||||||
def sort_update()
|
def sort_update(sort_keys)
|
||||||
if params[:sort_key]
|
sort_key = params[:sort_key]
|
||||||
sort = {:key => params[:sort_key], :order => params[:sort_order]}
|
sort_key = nil unless (sort_keys.is_a?(Array) ? sort_keys.include?(sort_key) : sort_keys[sort_key])
|
||||||
|
|
||||||
|
sort_order = (params[:sort_order] == 'desc' ? 'DESC' : 'ASC')
|
||||||
|
|
||||||
|
if sort_key
|
||||||
|
sort = {:key => sort_key, :order => sort_order}
|
||||||
elsif session[@sort_name]
|
elsif session[@sort_name]
|
||||||
sort = session[@sort_name] # Previous sort.
|
sort = session[@sort_name] # Previous sort.
|
||||||
else
|
else
|
||||||
sort = @sort_default
|
sort = @sort_default
|
||||||
end
|
end
|
||||||
session[@sort_name] = sort
|
session[@sort_name] = sort
|
||||||
|
|
||||||
|
sort_column = (sort_keys.is_a?(Hash) ? sort_keys[sort[:key]] : sort[:key])
|
||||||
|
@sort_clause = (sort_column.blank? ? nil : "#{sort_column} #{sort[:order]}")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an SQL sort clause corresponding to the current sort state.
|
# Returns an SQL sort clause corresponding to the current sort state.
|
||||||
# Use this to sort the controller's table items collection.
|
# Use this to sort the controller's table items collection.
|
||||||
#
|
#
|
||||||
def sort_clause()
|
def sort_clause()
|
||||||
session[@sort_name][:key] + ' ' + (session[@sort_name][:order] || 'ASC')
|
@sort_clause
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a link which sorts by the named column.
|
# Returns a link which sorts by the named column.
|
||||||
@@ -16,14 +16,6 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
module TimelogHelper
|
module TimelogHelper
|
||||||
def activity_collection_for_select_options
|
|
||||||
activities = Enumeration::get_values('ACTI')
|
|
||||||
collection = []
|
|
||||||
collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
|
|
||||||
activities.each { |a| collection << [a.name, a.id] }
|
|
||||||
collection
|
|
||||||
end
|
|
||||||
|
|
||||||
def select_hours(data, criteria, value)
|
def select_hours(data, criteria, value)
|
||||||
data.select {|row| row[criteria] == value}
|
data.select {|row| row[criteria] == value}
|
||||||
end
|
end
|
||||||
@@ -52,8 +44,6 @@ module TimelogHelper
|
|||||||
|
|
||||||
def entries_to_csv(entries)
|
def entries_to_csv(entries)
|
||||||
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
||||||
decimal_separator = l(:general_csv_decimal_separator)
|
|
||||||
custom_fields = TimeEntryCustomField.find(:all)
|
|
||||||
export = StringIO.new
|
export = StringIO.new
|
||||||
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
||||||
# csv header fields
|
# csv header fields
|
||||||
@@ -67,9 +57,6 @@ module TimelogHelper
|
|||||||
l(:field_hours),
|
l(:field_hours),
|
||||||
l(:field_comments)
|
l(:field_comments)
|
||||||
]
|
]
|
||||||
# Export custom fields
|
|
||||||
headers += custom_fields.collect(&:name)
|
|
||||||
|
|
||||||
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
||||||
# csv lines
|
# csv lines
|
||||||
entries.each do |entry|
|
entries.each do |entry|
|
||||||
@@ -80,11 +67,9 @@ module TimelogHelper
|
|||||||
(entry.issue ? entry.issue.id : nil),
|
(entry.issue ? entry.issue.id : nil),
|
||||||
(entry.issue ? entry.issue.tracker : nil),
|
(entry.issue ? entry.issue.tracker : nil),
|
||||||
(entry.issue ? entry.issue.subject : nil),
|
(entry.issue ? entry.issue.subject : nil),
|
||||||
entry.hours.to_s.gsub('.', decimal_separator),
|
entry.hours,
|
||||||
entry.comments
|
entry.comments
|
||||||
]
|
]
|
||||||
fields += custom_fields.collect {|f| show_value(entry.custom_value_for(f)) }
|
|
||||||
|
|
||||||
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
File renamed without changes.
@@ -16,21 +16,11 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
module UsersHelper
|
module UsersHelper
|
||||||
def users_status_options_for_select(selected)
|
def status_options_for_select(selected)
|
||||||
user_count_by_status = User.count(:group => 'status').to_hash
|
|
||||||
options_for_select([[l(:label_all), ''],
|
options_for_select([[l(:label_all), ''],
|
||||||
["#{l(:status_active)} (#{user_count_by_status[1].to_i})", 1],
|
[l(:status_active), 1],
|
||||||
["#{l(:status_registered)} (#{user_count_by_status[2].to_i})", 2],
|
[l(:status_registered), 2],
|
||||||
["#{l(:status_locked)} (#{user_count_by_status[3].to_i})", 3]], selected)
|
[l(:status_locked), 3]], selected)
|
||||||
end
|
|
||||||
|
|
||||||
# Options for the new membership projects combo-box
|
|
||||||
def options_for_membership_project_select(user, projects)
|
|
||||||
options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---")
|
|
||||||
options << project_tree_options_for_select(projects) do |p|
|
|
||||||
{:disabled => (user.projects.include?(p))}
|
|
||||||
end
|
|
||||||
options
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_status_link(user)
|
def change_status_link(user)
|
||||||
@@ -44,10 +34,4 @@ module UsersHelper
|
|||||||
link_to l(:button_lock), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :post, :class => 'icon icon-lock'
|
link_to l(:button_lock), url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :post, :class => 'icon icon-lock'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_settings_tabs
|
|
||||||
tabs = [{:name => 'general', :partial => 'users/general', :label => :label_general},
|
|
||||||
{:name => 'memberships', :partial => 'users/memberships', :label => :label_project_plural}
|
|
||||||
]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -26,19 +26,7 @@ class Attachment < ActiveRecord::Base
|
|||||||
validates_length_of :disk_filename, :maximum => 255
|
validates_length_of :disk_filename, :maximum => 255
|
||||||
|
|
||||||
acts_as_event :title => :filename,
|
acts_as_event :title => :filename,
|
||||||
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}}
|
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id}}
|
||||||
|
|
||||||
acts_as_activity_provider :type => 'files',
|
|
||||||
:permission => :view_files,
|
|
||||||
:find_options => {:select => "#{Attachment.table_name}.*",
|
|
||||||
:joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
|
|
||||||
"LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id"}
|
|
||||||
|
|
||||||
acts_as_activity_provider :type => 'documents',
|
|
||||||
:permission => :view_documents,
|
|
||||||
:find_options => {:select => "#{Attachment.table_name}.*",
|
|
||||||
:joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
|
|
||||||
"LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id"}
|
|
||||||
|
|
||||||
cattr_accessor :storage_path
|
cattr_accessor :storage_path
|
||||||
@@storage_path = "#{RAILS_ROOT}/files"
|
@@storage_path = "#{RAILS_ROOT}/files"
|
||||||
@@ -80,7 +68,9 @@ class Attachment < ActiveRecord::Base
|
|||||||
|
|
||||||
# Deletes file on the disk
|
# Deletes file on the disk
|
||||||
def after_destroy
|
def after_destroy
|
||||||
File.delete(diskfile) if !filename.blank? && File.exist?(diskfile)
|
if self.filename?
|
||||||
|
File.delete(diskfile) if File.exist?(diskfile)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns file's location on disk
|
# Returns file's location on disk
|
||||||
@@ -100,14 +90,6 @@ class Attachment < ActiveRecord::Base
|
|||||||
self.filename =~ /\.(jpe?g|gif|png)$/i
|
self.filename =~ /\.(jpe?g|gif|png)$/i
|
||||||
end
|
end
|
||||||
|
|
||||||
def is_text?
|
|
||||||
Redmine::MimeType.is_type?('text', filename)
|
|
||||||
end
|
|
||||||
|
|
||||||
def is_diff?
|
|
||||||
self.filename =~ /\.(patch|diff)$/i
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def sanitize_filename(value)
|
def sanitize_filename(value)
|
||||||
# get only the filename, not the whole path
|
# get only the filename, not the whole path
|
||||||
File renamed without changes.
@@ -20,10 +20,7 @@ require 'iconv'
|
|||||||
|
|
||||||
class AuthSourceLdap < AuthSource
|
class AuthSourceLdap < AuthSource
|
||||||
validates_presence_of :host, :port, :attr_login
|
validates_presence_of :host, :port, :attr_login
|
||||||
validates_length_of :name, :host, :account_password, :maximum => 60, :allow_nil => true
|
validates_presence_of :attr_firstname, :attr_lastname, :attr_mail, :if => Proc.new { |a| a.onthefly_register? }
|
||||||
validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
|
|
||||||
validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
|
|
||||||
validates_numericality_of :port, :only_integer => true
|
|
||||||
|
|
||||||
def after_initialize
|
def after_initialize
|
||||||
self.port = 389 if self.port == 0
|
self.port = 389 if self.port == 0
|
||||||
File renamed without changes.
File renamed without changes.
@@ -27,12 +27,9 @@ class Changeset < ActiveRecord::Base
|
|||||||
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project_id, :rev => o.revision}}
|
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project_id, :rev => o.revision}}
|
||||||
|
|
||||||
acts_as_searchable :columns => 'comments',
|
acts_as_searchable :columns => 'comments',
|
||||||
:include => {:repository => :project},
|
:include => :repository,
|
||||||
:project_key => "#{Repository.table_name}.project_id",
|
:project_key => "#{Repository.table_name}.project_id",
|
||||||
:date_column => 'committed_on'
|
:date_column => 'committed_on'
|
||||||
|
|
||||||
acts_as_activity_provider :timestamp => "#{table_name}.committed_on",
|
|
||||||
:find_options => {:include => {:repository => :project}}
|
|
||||||
|
|
||||||
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
|
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
|
||||||
validates_uniqueness_of :revision, :scope => :repository_id
|
validates_uniqueness_of :revision, :scope => :repository_id
|
||||||
File renamed without changes.
@@ -30,7 +30,7 @@ class CustomField < ActiveRecord::Base
|
|||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
validates_presence_of :name, :field_format
|
validates_presence_of :name, :field_format
|
||||||
validates_uniqueness_of :name, :scope => :type
|
validates_uniqueness_of :name
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
|
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
|
||||||
validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
|
validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
|
||||||
@@ -66,7 +66,7 @@ class CustomField < ActiveRecord::Base
|
|||||||
|
|
||||||
# to move in project_custom_field
|
# to move in project_custom_field
|
||||||
def self.for_all
|
def self.for_all
|
||||||
find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
|
find(:all, :conditions => ["is_for_all=?", true])
|
||||||
end
|
end
|
||||||
|
|
||||||
def type_name
|
def type_name
|
||||||
@@ -25,11 +25,6 @@ class CustomValue < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if the boolean custom value is true
|
|
||||||
def true?
|
|
||||||
self.value == '1'
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def validate
|
def validate
|
||||||
if value.blank?
|
if value.blank?
|
||||||
File renamed without changes.
File renamed without changes.
@@ -23,7 +23,6 @@ class Enumeration < ActiveRecord::Base
|
|||||||
validates_presence_of :opt, :name
|
validates_presence_of :opt, :name
|
||||||
validates_uniqueness_of :name, :scope => [:opt]
|
validates_uniqueness_of :name, :scope => [:opt]
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
|
|
||||||
|
|
||||||
OPTIONS = {
|
OPTIONS = {
|
||||||
"IPRI" => :enumeration_issue_priorities,
|
"IPRI" => :enumeration_issue_priorities,
|
||||||
@@ -27,7 +27,7 @@ class Issue < ActiveRecord::Base
|
|||||||
|
|
||||||
has_many :journals, :as => :journalized, :dependent => :destroy
|
has_many :journals, :as => :journalized, :dependent => :destroy
|
||||||
has_many :attachments, :as => :container, :dependent => :destroy
|
has_many :attachments, :as => :container, :dependent => :destroy
|
||||||
has_many :time_entries, :dependent => :nullify
|
has_many :time_entries, :dependent => :delete_all
|
||||||
has_many :custom_values, :dependent => :delete_all, :as => :customized
|
has_many :custom_values, :dependent => :delete_all, :as => :customized
|
||||||
has_many :custom_fields, :through => :custom_values
|
has_many :custom_fields, :through => :custom_values
|
||||||
has_and_belongs_to_many :changesets, :order => "revision ASC"
|
has_and_belongs_to_many :changesets, :order => "revision ASC"
|
||||||
@@ -66,8 +66,10 @@ class Issue < ActiveRecord::Base
|
|||||||
transaction do
|
transaction do
|
||||||
if new_project && project_id != new_project.id
|
if new_project && project_id != new_project.id
|
||||||
# delete issue relations
|
# delete issue relations
|
||||||
self.relations_from.clear
|
unless Setting.cross_project_issue_relations?
|
||||||
self.relations_to.clear
|
self.relations_from.clear
|
||||||
|
self.relations_to.clear
|
||||||
|
end
|
||||||
# issue is moved to another project
|
# issue is moved to another project
|
||||||
self.category = nil
|
self.category = nil
|
||||||
self.fixed_version = nil
|
self.fixed_version = nil
|
||||||
@@ -91,7 +93,11 @@ class Issue < ActiveRecord::Base
|
|||||||
self.priority = nil
|
self.priority = nil
|
||||||
write_attribute(:priority_id, pid)
|
write_attribute(:priority_id, pid)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def estimated_hours=(h)
|
||||||
|
write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h)
|
||||||
|
end
|
||||||
|
|
||||||
def validate
|
def validate
|
||||||
if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
|
if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
|
||||||
errors.add :due_date, :activerecord_error_not_a_date
|
errors.add :due_date, :activerecord_error_not_a_date
|
||||||
@@ -142,12 +148,17 @@ class Issue < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def after_save
|
def after_save
|
||||||
|
# Reload is needed in order to get the right status
|
||||||
|
reload
|
||||||
|
|
||||||
# Update start/due dates of following issues
|
# Update start/due dates of following issues
|
||||||
relations_from.each(&:set_issue_to_dates)
|
relations_from.each(&:set_issue_to_dates)
|
||||||
|
|
||||||
# Close duplicates if the issue was closed
|
# Close duplicates if the issue was closed
|
||||||
if @issue_before_change && !@issue_before_change.closed? && self.closed?
|
if @issue_before_change && !@issue_before_change.closed? && self.closed?
|
||||||
duplicates.each do |duplicate|
|
duplicates.each do |duplicate|
|
||||||
|
# Reload is need in case the duplicate was updated by a previous duplicate
|
||||||
|
duplicate.reload
|
||||||
# Don't re-close it if it's already closed
|
# Don't re-close it if it's already closed
|
||||||
next if duplicate.closed?
|
next if duplicate.closed?
|
||||||
# Same user and notes
|
# Same user and notes
|
||||||
@@ -165,6 +176,7 @@ class Issue < ActiveRecord::Base
|
|||||||
def init_journal(user, notes = "")
|
def init_journal(user, notes = "")
|
||||||
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
|
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
|
||||||
@issue_before_change = self.clone
|
@issue_before_change = self.clone
|
||||||
|
@issue_before_change.status = self.status
|
||||||
@custom_values_before_change = {}
|
@custom_values_before_change = {}
|
||||||
self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
|
self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
|
||||||
@current_journal
|
@current_journal
|
||||||
@@ -190,9 +202,9 @@ class Issue < ActiveRecord::Base
|
|||||||
# Returns the mail adresses of users that should be notified for the issue
|
# Returns the mail adresses of users that should be notified for the issue
|
||||||
def recipients
|
def recipients
|
||||||
recipients = project.recipients
|
recipients = project.recipients
|
||||||
# Author and assignee are always notified
|
# Author and assignee are always notified unless they have been locked
|
||||||
recipients << author.mail if author
|
recipients << author.mail if author && author.active?
|
||||||
recipients << assigned_to.mail if assigned_to
|
recipients << assigned_to.mail if assigned_to && assigned_to.active?
|
||||||
recipients.compact.uniq
|
recipients.compact.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -225,4 +237,14 @@ class Issue < ActiveRecord::Base
|
|||||||
def soonest_start
|
def soonest_start
|
||||||
@soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
|
@soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.visible_by(usr)
|
||||||
|
with_scope(:find => { :conditions => Project.visible_by(usr) }) do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{tracker} ##{id}: #{subject}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -25,18 +25,17 @@ class Journal < ActiveRecord::Base
|
|||||||
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
|
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
|
||||||
attr_accessor :indice
|
attr_accessor :indice
|
||||||
|
|
||||||
|
acts_as_searchable :columns => 'notes',
|
||||||
|
:include => :issue,
|
||||||
|
:project_key => "#{Issue.table_name}.project_id",
|
||||||
|
:date_column => "#{Issue.table_name}.created_on"
|
||||||
|
|
||||||
acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
|
acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
|
||||||
:description => :notes,
|
:description => :notes,
|
||||||
:author => :user,
|
:author => :user,
|
||||||
:type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
|
:type => Proc.new {|o| (s = o.new_status) && s.is_closed? ? 'issue-closed' : 'issue-edit' },
|
||||||
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
|
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
|
||||||
|
|
||||||
acts_as_activity_provider :type => 'issues',
|
|
||||||
:permission => :view_issues,
|
|
||||||
:find_options => {:include => [{:issue => :project}, :details, :user],
|
|
||||||
:conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
|
|
||||||
" (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
|
|
||||||
|
|
||||||
def save
|
def save
|
||||||
# Do not save an empty journal
|
# Do not save an empty journal
|
||||||
(details.empty? && notes.blank?) ? false : super
|
(details.empty? && notes.blank?) ? false : super
|
||||||
File renamed without changes.
File renamed without changes.
@@ -51,15 +51,6 @@ class Mailer < ActionMailer::Base
|
|||||||
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
|
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
|
||||||
end
|
end
|
||||||
|
|
||||||
def reminder(user, issues, days)
|
|
||||||
set_language_if_valid user.language
|
|
||||||
recipients user.mail
|
|
||||||
subject l(:mail_subject_reminder, issues.size)
|
|
||||||
body :issues => issues,
|
|
||||||
:days => days,
|
|
||||||
:issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'issues.due_date', :sort_order => 'asc')
|
|
||||||
end
|
|
||||||
|
|
||||||
def document_added(document)
|
def document_added(document)
|
||||||
redmine_headers 'Project' => document.project.identifier
|
redmine_headers 'Project' => document.project.identifier
|
||||||
recipients document.project.recipients
|
recipients document.project.recipients
|
||||||
@@ -153,30 +144,6 @@ class Mailer < ActionMailer::Base
|
|||||||
(bcc.nil? || bcc.empty?)
|
(bcc.nil? || bcc.empty?)
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends reminders to issue assignees
|
|
||||||
# Available options:
|
|
||||||
# * :days => how many days in the future to remind about (defaults to 7)
|
|
||||||
# * :tracker => id of tracker for filtering issues (defaults to all trackers)
|
|
||||||
# * :project => id or identifier of project to process (defaults to all projects)
|
|
||||||
def self.reminders(options={})
|
|
||||||
days = options[:days] || 7
|
|
||||||
project = options[:project] ? Project.find(options[:project]) : nil
|
|
||||||
tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
|
|
||||||
|
|
||||||
s = ARCondition.new ["#{IssueStatus.table_name}.is_closed = ? AND #{Issue.table_name}.due_date <= ?", false, days.day.from_now.to_date]
|
|
||||||
s << "#{Issue.table_name}.assigned_to_id IS NOT NULL"
|
|
||||||
s << "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}"
|
|
||||||
s << "#{Issue.table_name}.project_id = #{project.id}" if project
|
|
||||||
s << "#{Issue.table_name}.tracker_id = #{tracker.id}" if tracker
|
|
||||||
|
|
||||||
issues_by_assignee = Issue.find(:all, :include => [:status, :assigned_to, :project, :tracker],
|
|
||||||
:conditions => s.conditions
|
|
||||||
).group_by(&:assigned_to)
|
|
||||||
issues_by_assignee.each do |assignee, issues|
|
|
||||||
deliver_reminder(assignee, issues, days) unless assignee.nil?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def initialize_defaults(method_name)
|
def initialize_defaults(method_name)
|
||||||
File renamed without changes.
@@ -28,6 +28,7 @@ class Message < ActiveRecord::Base
|
|||||||
:date_column => 'created_on'
|
:date_column => 'created_on'
|
||||||
acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
|
acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
|
||||||
:description => :content,
|
:description => :content,
|
||||||
|
:type => Proc.new {|o| o.parent_id.nil? ? 'message' : 'reply'},
|
||||||
:url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id, :id => o.id}}
|
:url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id, :id => o.id}}
|
||||||
|
|
||||||
attr_protected :locked, :sticky
|
attr_protected :locked, :sticky
|
||||||
@@ -36,7 +37,7 @@ class Message < ActiveRecord::Base
|
|||||||
|
|
||||||
def validate_on_create
|
def validate_on_create
|
||||||
# Can not reply to a locked topic
|
# Can not reply to a locked topic
|
||||||
errors.add_to_base 'Topic is locked' if root.locked?
|
errors.add_to_base 'Topic is locked' if root.locked? && self != root
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_create
|
def after_create
|
||||||
File renamed without changes.
File renamed without changes.
@@ -22,6 +22,7 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
has_many :members, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
|
has_many :members, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
|
||||||
has_many :users, :through => :members
|
has_many :users, :through => :members
|
||||||
|
has_many :custom_values, :dependent => :delete_all, :as => :customized
|
||||||
has_many :enabled_modules, :dependent => :delete_all
|
has_many :enabled_modules, :dependent => :delete_all
|
||||||
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
|
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
|
||||||
has_many :issues, :dependent => :destroy, :order => "#{Issue.table_name}.created_on DESC", :include => [:status, :tracker]
|
has_many :issues, :dependent => :destroy, :order => "#{Issue.table_name}.created_on DESC", :include => [:status, :tracker]
|
||||||
@@ -37,7 +38,7 @@ class Project < ActiveRecord::Base
|
|||||||
has_many :changesets, :through => :repository
|
has_many :changesets, :through => :repository
|
||||||
has_one :wiki, :dependent => :destroy
|
has_one :wiki, :dependent => :destroy
|
||||||
# Custom field for the project issues
|
# Custom field for the project issues
|
||||||
has_and_belongs_to_many :issue_custom_fields,
|
has_and_belongs_to_many :custom_fields,
|
||||||
:class_name => 'IssueCustomField',
|
:class_name => 'IssueCustomField',
|
||||||
:order => "#{CustomField.table_name}.position",
|
:order => "#{CustomField.table_name}.position",
|
||||||
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
|
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
|
||||||
@@ -45,19 +46,18 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
acts_as_tree :order => "name", :counter_cache => true
|
acts_as_tree :order => "name", :counter_cache => true
|
||||||
|
|
||||||
acts_as_customizable
|
acts_as_searchable :columns => ['name', 'description'], :project_key => 'id'
|
||||||
acts_as_searchable :columns => ['name', 'description'], :project_key => 'id', :permission => nil
|
|
||||||
acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"},
|
acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"},
|
||||||
:url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o.id}},
|
:url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o.id}}
|
||||||
:author => nil
|
|
||||||
|
|
||||||
attr_protected :status, :enabled_module_names
|
attr_protected :status, :enabled_module_names
|
||||||
|
|
||||||
validates_presence_of :name, :identifier
|
validates_presence_of :name, :identifier
|
||||||
validates_uniqueness_of :name, :identifier
|
validates_uniqueness_of :name, :identifier
|
||||||
|
validates_associated :custom_values, :on => :update
|
||||||
validates_associated :repository, :wiki
|
validates_associated :repository, :wiki
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
validates_length_of :homepage, :maximum => 255
|
validates_length_of :homepage, :maximum => 60
|
||||||
validates_length_of :identifier, :in => 3..20
|
validates_length_of :identifier, :in => 3..20
|
||||||
validates_format_of :identifier, :with => /^[a-z0-9\-]*$/
|
validates_format_of :identifier, :with => /^[a-z0-9\-]*$/
|
||||||
|
|
||||||
@@ -113,18 +113,16 @@ class Project < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
if user.admin?
|
if user.admin?
|
||||||
# no restriction
|
# no restriction
|
||||||
|
elsif user.logged?
|
||||||
|
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" if Role.non_member.allowed_to?(permission)
|
||||||
|
allowed_project_ids = user.memberships.select {|m| m.role.allowed_to?(permission)}.collect {|m| m.project_id}
|
||||||
|
statements << "#{Project.table_name}.id IN (#{allowed_project_ids.join(',')})" if allowed_project_ids.any?
|
||||||
|
elsif Role.anonymous.allowed_to?(permission)
|
||||||
|
# anonymous user allowed on public project
|
||||||
|
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}"
|
||||||
else
|
else
|
||||||
|
# anonymous user is not authorized
|
||||||
statements << "1=0"
|
statements << "1=0"
|
||||||
if user.logged?
|
|
||||||
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" if Role.non_member.allowed_to?(permission)
|
|
||||||
allowed_project_ids = user.memberships.select {|m| m.role.allowed_to?(permission)}.collect {|m| m.project_id}
|
|
||||||
statements << "#{Project.table_name}.id IN (#{allowed_project_ids.join(',')})" if allowed_project_ids.any?
|
|
||||||
elsif Role.anonymous.allowed_to?(permission)
|
|
||||||
# anonymous user allowed on public project
|
|
||||||
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}"
|
|
||||||
else
|
|
||||||
# anonymous user is not authorized
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))"
|
statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))"
|
||||||
end
|
end
|
||||||
@@ -197,12 +195,12 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
# Returns an array of all custom fields enabled for project issues
|
# Returns an array of all custom fields enabled for project issues
|
||||||
# (explictly associated custom fields and custom fields enabled for all projects)
|
# (explictly associated custom fields and custom fields enabled for all projects)
|
||||||
def all_issue_custom_fields
|
def custom_fields_for_issues(tracker)
|
||||||
@all_issue_custom_fields ||= (IssueCustomField.for_all + issue_custom_fields).uniq.sort
|
all_custom_fields.select {|c| tracker.custom_fields.include? c }
|
||||||
end
|
end
|
||||||
|
|
||||||
def project
|
def all_custom_fields
|
||||||
self
|
@all_custom_fields ||= (IssueCustomField.for_all + custom_fields).uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
def <=>(project)
|
def <=>(project)
|
||||||
File renamed without changes.
@@ -88,7 +88,7 @@ class Query < ActiveRecord::Base
|
|||||||
:date_past => [ ">t-", "<t-", "t-", "t", "w" ],
|
:date_past => [ ">t-", "<t-", "t-", "t", "w" ],
|
||||||
:string => [ "=", "~", "!", "!~" ],
|
:string => [ "=", "~", "!", "!~" ],
|
||||||
:text => [ "~", "!~" ],
|
:text => [ "~", "!~" ],
|
||||||
:integer => [ "=", ">=", "<=", "!*", "*" ] }
|
:integer => [ "=", ">=", "<=" ] }
|
||||||
|
|
||||||
cattr_reader :operators_by_filter_type
|
cattr_reader :operators_by_filter_type
|
||||||
|
|
||||||
@@ -152,8 +152,7 @@ class Query < ActiveRecord::Base
|
|||||||
"updated_on" => { :type => :date_past, :order => 10 },
|
"updated_on" => { :type => :date_past, :order => 10 },
|
||||||
"start_date" => { :type => :date, :order => 11 },
|
"start_date" => { :type => :date, :order => 11 },
|
||||||
"due_date" => { :type => :date, :order => 12 },
|
"due_date" => { :type => :date, :order => 12 },
|
||||||
"estimated_hours" => { :type => :integer, :order => 13 },
|
"done_ratio" => { :type => :integer, :order => 13 }}
|
||||||
"done_ratio" => { :type => :integer, :order => 14 }}
|
|
||||||
|
|
||||||
user_values = []
|
user_values = []
|
||||||
user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
|
user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
|
||||||
@@ -167,20 +166,29 @@ class Query < ActiveRecord::Base
|
|||||||
@available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
|
@available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
|
||||||
|
|
||||||
if project
|
if project
|
||||||
# project specific filters
|
# project specific filters
|
||||||
unless @project.issue_categories.empty?
|
@available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
|
||||||
@available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
|
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } }
|
||||||
end
|
|
||||||
unless @project.versions.empty?
|
|
||||||
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } }
|
|
||||||
end
|
|
||||||
unless @project.active_children.empty?
|
unless @project.active_children.empty?
|
||||||
@available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } }
|
@available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } }
|
||||||
end
|
end
|
||||||
add_custom_fields_filters(@project.all_issue_custom_fields)
|
@project.all_custom_fields.select(&:is_filter?).each do |field|
|
||||||
else
|
case field.field_format
|
||||||
# global filters for cross project issue list
|
when "text"
|
||||||
add_custom_fields_filters(IssueCustomField.find(:all, :conditions => {:is_filter => true, :is_for_all => true}))
|
options = { :type => :text, :order => 20 }
|
||||||
|
when "list"
|
||||||
|
options = { :type => :list_optional, :values => field.possible_values, :order => 20}
|
||||||
|
when "date"
|
||||||
|
options = { :type => :date, :order => 20 }
|
||||||
|
when "bool"
|
||||||
|
options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
|
||||||
|
else
|
||||||
|
options = { :type => :string, :order => 20 }
|
||||||
|
end
|
||||||
|
@available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
|
||||||
|
end
|
||||||
|
# remove category filter if no category defined
|
||||||
|
@available_filters.delete "category_id" if @available_filters["category_id"][:values].empty?
|
||||||
end
|
end
|
||||||
@available_filters
|
@available_filters
|
||||||
end
|
end
|
||||||
@@ -227,7 +235,7 @@ class Query < ActiveRecord::Base
|
|||||||
return @available_columns if @available_columns
|
return @available_columns if @available_columns
|
||||||
@available_columns = Query.available_columns
|
@available_columns = Query.available_columns
|
||||||
@available_columns += (project ?
|
@available_columns += (project ?
|
||||||
project.all_issue_custom_fields :
|
project.all_custom_fields :
|
||||||
IssueCustomField.find(:all, :conditions => {:is_for_all => true})
|
IssueCustomField.find(:all, :conditions => {:is_for_all => true})
|
||||||
).collect {|cf| QueryCustomFieldColumn.new(cf) }
|
).collect {|cf| QueryCustomFieldColumn.new(cf) }
|
||||||
end
|
end
|
||||||
@@ -358,26 +366,4 @@ class Query < ActiveRecord::Base
|
|||||||
|
|
||||||
(project_clauses + filters_clauses).join(' AND ')
|
(project_clauses + filters_clauses).join(' AND ')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def add_custom_fields_filters(custom_fields)
|
|
||||||
@available_filters ||= {}
|
|
||||||
|
|
||||||
custom_fields.select(&:is_filter?).each do |field|
|
|
||||||
case field.field_format
|
|
||||||
when "text"
|
|
||||||
options = { :type => :text, :order => 20 }
|
|
||||||
when "list"
|
|
||||||
options = { :type => :list_optional, :values => field.possible_values, :order => 20}
|
|
||||||
when "date"
|
|
||||||
options = { :type => :date, :order => 20 }
|
|
||||||
when "bool"
|
|
||||||
options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
|
|
||||||
else
|
|
||||||
options = { :type => :string, :order => 20 }
|
|
||||||
end
|
|
||||||
@available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
@@ -17,9 +17,19 @@
|
|||||||
|
|
||||||
class Repository < ActiveRecord::Base
|
class Repository < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
has_many :changesets, :dependent => :destroy, :order => "#{Changeset.table_name}.revision DESC"
|
has_many :changesets, :dependent => :destroy, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
|
||||||
has_many :changes, :through => :changesets
|
has_many :changes, :through => :changesets
|
||||||
|
|
||||||
|
# Removes leading and trailing whitespace
|
||||||
|
def url=(arg)
|
||||||
|
write_attribute(:url, arg ? arg.to_s.strip : nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes leading and trailing whitespace
|
||||||
|
def root_url=(arg)
|
||||||
|
write_attribute(:root_url, arg ? arg.to_s.strip : nil)
|
||||||
|
end
|
||||||
|
|
||||||
def scm
|
def scm
|
||||||
@scm ||= self.scm_adapter.new url, root_url, login, password
|
@scm ||= self.scm_adapter.new url, root_url, login, password
|
||||||
update_attribute(:root_url, @scm.root_url) if root_url.blank?
|
update_attribute(:root_url, @scm.root_url) if root_url.blank?
|
||||||
@@ -51,7 +61,12 @@ class Repository < ActiveRecord::Base
|
|||||||
path = "/#{path}" unless path.starts_with?('/')
|
path = "/#{path}" unless path.starts_with?('/')
|
||||||
Change.find(:all, :include => :changeset,
|
Change.find(:all, :include => :changeset,
|
||||||
:conditions => ["repository_id = ? AND path = ?", id, path],
|
:conditions => ["repository_id = ? AND path = ?", id, path],
|
||||||
:order => "committed_on DESC, #{Changeset.table_name}.revision DESC").collect(&:changeset)
|
:order => "committed_on DESC, #{Changeset.table_name}.id DESC").collect(&:changeset)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns a path relative to the url of the repository
|
||||||
|
def relative_path(path)
|
||||||
|
path
|
||||||
end
|
end
|
||||||
|
|
||||||
def latest_changeset
|
def latest_changeset
|
||||||
@@ -88,4 +103,13 @@ class Repository < ActiveRecord::Base
|
|||||||
rescue
|
rescue
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def before_save
|
||||||
|
# Strips url and root_url
|
||||||
|
url.strip!
|
||||||
|
root_url.strip!
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
+1
-1
@@ -51,7 +51,7 @@ class Repository::Bazaar < Repository
|
|||||||
scm_info = scm.info
|
scm_info = scm.info
|
||||||
if scm_info
|
if scm_info
|
||||||
# latest revision found in database
|
# latest revision found in database
|
||||||
db_revision = latest_changeset ? latest_changeset.revision : 0
|
db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
|
||||||
# latest revision in the repository
|
# latest revision in the repository
|
||||||
scm_revision = scm_info.lastrev.identifier.to_i
|
scm_revision = scm_info.lastrev.identifier.to_i
|
||||||
if db_revision < scm_revision
|
if db_revision < scm_revision
|
||||||
Loaded 100 of 4757 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user