--- app/controllers/IssueApp.java
+++ app/controllers/IssueApp.java
... | ... | @@ -108,7 +108,7 @@ |
108 | 108 |
|
109 | 109 |
private static boolean hasNotConditions(models.support.SearchCondition searchCondition) { |
110 | 110 |
return searchCondition.assigneeId == null && searchCondition.authorId == null && searchCondition.mentionId == null |
111 |
- && searchCondition.commenterId == null; |
|
111 |
+ && searchCondition.commenterId == null && searchCondition.sharerId == null; |
|
112 | 112 |
} |
113 | 113 |
|
114 | 114 |
@Transactional |
--- app/models/support/SearchCondition.java
+++ app/models/support/SearchCondition.java
... | ... | @@ -1,23 +1,9 @@ |
1 | 1 |
/** |
2 |
- * Yobi, Project Hosting SW |
|
3 |
- * |
|
4 |
- * Copyright 2012 NAVER Corp. |
|
5 |
- * http://yobi.io |
|
6 |
- * |
|
7 |
- * @author Tae |
|
8 |
- * |
|
9 |
- * Licensed under the Apache License, Version 2.0 (the "License"); |
|
10 |
- * you may not use this file except in compliance with the License. |
|
11 |
- * You may obtain a copy of the License at |
|
12 |
- * |
|
13 |
- * http://www.apache.org/licenses/LICENSE-2.0 |
|
14 |
- * |
|
15 |
- * Unless required by applicable law or agreed to in writing, software |
|
16 |
- * distributed under the License is distributed on an "AS IS" BASIS, |
|
17 |
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
18 |
- * See the License for the specific language governing permissions and |
|
19 |
- * limitations under the License. |
|
20 |
- */ |
|
2 |
+ * Yona, 21st Century Project Hosting SW |
|
3 |
+ * <p> |
|
4 |
+ * Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp. |
|
5 |
+ * https://yona.io |
|
6 |
+ **/ |
|
21 | 7 |
package models.support; |
22 | 8 |
|
23 | 9 |
import com.avaje.ebean.ExpressionList; |
... | ... | @@ -50,6 +36,7 @@ |
50 | 36 |
public Project project; |
51 | 37 |
|
52 | 38 |
public Long mentionId; |
39 |
+ public Long sharerId; |
|
53 | 40 |
public Organization organization; |
54 | 41 |
public List<String> projectNames; |
55 | 42 |
|
... | ... | @@ -76,6 +63,7 @@ |
76 | 63 |
one.assigneeId = this.assigneeId; |
77 | 64 |
one.commenterId = this.commenterId; |
78 | 65 |
one.mentionId = this.mentionId; |
66 |
+ one.sharerId = this.sharerId; |
|
79 | 67 |
one.dueDate = this.dueDate; |
80 | 68 |
one.projectNames = this.projectNames; |
81 | 69 |
return one; |
... | ... | @@ -151,6 +139,11 @@ |
151 | 139 |
return this; |
152 | 140 |
} |
153 | 141 |
|
142 |
+ public SearchCondition setSharerId(Long sharerId) { |
|
143 |
+ this.sharerId = sharerId; |
|
144 |
+ return this; |
|
145 |
+ } |
|
146 |
+ |
|
154 | 147 |
public ExpressionList<Issue> asExpressionList(@Nonnull Organization organization) { |
155 | 148 |
ExpressionList<Issue> el = Issue.finder.where(); |
156 | 149 |
|
... | ... | @@ -163,6 +156,8 @@ |
163 | 156 |
setAssigneeIfExists(el); |
164 | 157 |
setAuthorIfExist(el); |
165 | 158 |
setMentionedIssuesIfExist(el); |
159 |
+ setSharedIssuesIfExist(el); |
|
160 |
+ |
|
166 | 161 |
setFilteredStringIfExist(el); |
167 | 162 |
|
168 | 163 |
if (commentedCheck) { |
... | ... | @@ -279,6 +274,7 @@ |
279 | 274 |
setAuthorIfExist(el); |
280 | 275 |
setCommenterIfExist(el, null); |
281 | 276 |
setMentionedIssuesIfExist(el); |
277 |
+ setSharedIssuesIfExist(el); |
|
282 | 278 |
setFilteredStringIfExist(el); |
283 | 279 |
|
284 | 280 |
if (commentedCheck) { |
... | ... | @@ -309,6 +305,23 @@ |
309 | 305 |
User mentionUser = User.find.byId(mentionId); |
310 | 306 |
if(!mentionUser.isAnonymous()) { |
311 | 307 |
List<Long> ids = getMentioningIssueIds(mentionUser); |
308 |
+ |
|
309 |
+ if (ids.isEmpty()) { |
|
310 |
+ // No need to progress because the query matches nothing. |
|
311 |
+ el.idEq(-1); |
|
312 |
+ } else { |
|
313 |
+ el.idIn(ids); |
|
314 |
+ } |
|
315 |
+ } |
|
316 |
+ } |
|
317 |
+ } |
|
318 |
+ |
|
319 |
+ private void setSharedIssuesIfExist(ExpressionList<Issue> el) { |
|
320 |
+ |
|
321 |
+ if (sharerId != null) { |
|
322 |
+ User user = User.find.byId(sharerId); |
|
323 |
+ if(!user.isAnonymous()) { |
|
324 |
+ List<Long> ids = getSharedIssueIds(user); |
|
312 | 325 |
|
313 | 326 |
if (ids.isEmpty()) { |
314 | 327 |
// No need to progress because the query matches nothing. |
... | ... | @@ -373,6 +386,18 @@ |
373 | 386 |
return new ArrayList<>(ids); |
374 | 387 |
} |
375 | 388 |
|
389 |
+ private List<Long> getSharedIssueIds(User user) { |
|
390 |
+ Set<Long> ids = new HashSet<>(); |
|
391 |
+ List<IssueSharer> issueSharers = IssueSharer.find.where() |
|
392 |
+ .eq("user.id", user.id) |
|
393 |
+ .findList(); |
|
394 |
+ for (IssueSharer issueSharer : issueSharers) { |
|
395 |
+ ids.add(issueSharer.issue.id); |
|
396 |
+ } |
|
397 |
+ |
|
398 |
+ return new ArrayList<>(ids); |
|
399 |
+ } |
|
400 |
+ |
|
376 | 401 |
public ExpressionList<Issue> asExpressionList(Project project) { |
377 | 402 |
ExpressionList<Issue> el = Issue.finder.where(); |
378 | 403 |
if( project != null ){ |
... | ... | @@ -417,6 +442,7 @@ |
417 | 442 |
} |
418 | 443 |
|
419 | 444 |
setCommenterIfExist(el, project); |
445 |
+ setSharedIssuesIfExist(el); |
|
420 | 446 |
|
421 | 447 |
if (milestoneId != null) { |
422 | 448 |
if (milestoneId.equals(Milestone.NULL_MILESTONE_ID)) { |
... | ... | @@ -457,4 +483,23 @@ |
457 | 483 |
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
458 | 484 |
return sdf.format(this.dueDate); |
459 | 485 |
} |
486 |
+ |
|
487 |
+ @Override |
|
488 |
+ public String toString() { |
|
489 |
+ return "SearchCondition{" + |
|
490 |
+ "state='" + state + '\'' + |
|
491 |
+ ", commentedCheck=" + commentedCheck + |
|
492 |
+ ", milestoneId=" + milestoneId + |
|
493 |
+ ", labelIds=" + labelIds + |
|
494 |
+ ", authorId=" + authorId + |
|
495 |
+ ", assigneeId=" + assigneeId + |
|
496 |
+ ", project=" + project + |
|
497 |
+ ", mentionId=" + mentionId + |
|
498 |
+ ", sharerId=" + sharerId + |
|
499 |
+ ", organization=" + organization + |
|
500 |
+ ", projectNames=" + projectNames + |
|
501 |
+ ", commenterId=" + commenterId + |
|
502 |
+ ", dueDate=" + dueDate + |
|
503 |
+ '}'; |
|
504 |
+ } |
|
460 | 505 |
} |
--- app/views/issue/my_partial_list_quicksearch.scala.html
+++ app/views/issue/my_partial_list_quicksearch.scala.html
... | ... | @@ -1,66 +1,72 @@ |
1 | 1 |
@** |
2 |
-* Yobi, Project Hosting SW |
|
2 |
+* Yona, 21st Century Project Hosting SW |
|
3 | 3 |
* |
4 |
-* Copyright 2014 NAVER Corp. |
|
5 |
-* http://yobi.io |
|
6 |
-* |
|
7 |
-* @author Jihan Kim |
|
8 |
-* |
|
9 |
-* Licensed under the Apache License, Version 2.0 (the "License"); |
|
10 |
-* you may not use this file except in compliance with the License. |
|
11 |
-* You may obtain a copy of the License at |
|
12 |
-* |
|
13 |
-* http://www.apache.org/licenses/LICENSE-2.0 |
|
14 |
-* |
|
15 |
-* Unless required by applicable law or agreed to in writing, software |
|
16 |
-* distributed under the License is distributed on an "AS IS" BASIS, |
|
17 |
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
18 |
-* See the License for the specific language governing permissions and |
|
19 |
-* limitations under the License. |
|
4 |
+* Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp. |
|
5 |
+* https://yona.io |
|
20 | 6 |
**@ |
21 |
-@(param:models.support.SearchCondition) |
|
7 |
+@import models.support.SearchCondition |
|
8 |
+@(param:SearchCondition) |
|
9 |
+ |
|
10 |
+@currentUserId = @{ |
|
11 |
+ UserApp.currentUser().id |
|
12 |
+} |
|
22 | 13 |
|
23 | 14 |
<ul class="lst-stacked unstyled"> |
24 | 15 |
@if(!UserApp.currentUser().isAnonymous()){ |
25 |
- <li @if(param.assigneeId == UserApp.currentUser().id){ class="active"}> |
|
16 |
+ <li @if(param.assigneeId == currentUserId){ class="active"}> |
|
26 | 17 |
<a pjax-filter href="#" |
27 | 18 |
data-author-id="" |
28 |
- data-assignee-id="@UserApp.currentUser.id" |
|
19 |
+ data-assignee-id="@currentUserId" |
|
29 | 20 |
data-commenter-id="" |
30 | 21 |
data-milestone-id="@param.milestoneId" |
31 |
- data-mention-id=""> |
|
22 |
+ data-mention-id="" |
|
23 |
+ data-sharer-id=""> |
|
32 | 24 |
@Messages("issue.list.assignedToMe") |
33 | 25 |
</a> |
34 | 26 |
</li> |
35 |
- <li @if(param.authorId == UserApp.currentUser().id){ class="active"}> |
|
27 |
+ <li @if(param.authorId == currentUserId){ class="active"}> |
|
36 | 28 |
<a pjax-filter href="#" |
37 |
- data-author-id="@UserApp.currentUser.id" |
|
29 |
+ data-author-id="@currentUserId" |
|
38 | 30 |
data-assignee-id="" |
39 | 31 |
data-commenter-id="" |
40 | 32 |
data-milestone-id="@param.milestoneId" |
41 |
- data-mention-id=""> |
|
33 |
+ data-mention-id="" |
|
34 |
+ data-sharer-id=""> |
|
42 | 35 |
@Messages("issue.list.authoredByMe") |
43 | 36 |
</a> |
44 | 37 |
</li> |
45 |
- <li @if(param.commenterId == UserApp.currentUser().id){ class="active"}> |
|
38 |
+ <li @if(param.commenterId == currentUserId){ class="active"}> |
|
46 | 39 |
<a pjax-filter href="#" |
47 | 40 |
data-author-id="" |
48 | 41 |
data-assignee-id="" |
49 |
- data-commenter-id="@UserApp.currentUser.id" |
|
42 |
+ data-commenter-id="@currentUserId" |
|
50 | 43 |
data-milestone-id="@param.milestoneId" |
51 |
- data-mention-id=""> |
|
44 |
+ data-mention-id="" |
|
45 |
+ data-sharer-id=""> |
|
52 | 46 |
@Messages("issue.list.commentedByMe") |
53 | 47 |
</a> |
54 | 48 |
</li> |
55 |
- <li @if(param.mentionId == UserApp.currentUser().id){ class="active"}> |
|
49 |
+ <li @if(param.mentionId == currentUserId){ class="active"}> |
|
56 | 50 |
<a pjax-filter href="#" |
57 | 51 |
data-author-id="" |
58 | 52 |
data-assignee-id="" |
59 | 53 |
data-commenter-id="" |
60 | 54 |
data-milestone-id="@param.milestoneId" |
61 |
- data-mention-id="@UserApp.currentUser.id"> |
|
55 |
+ data-mention-id="@currentUserId" |
|
56 |
+ data-sharer-id=""> |
|
62 | 57 |
@Messages("issue.list.mentionedOfMe") |
63 | 58 |
</a> |
64 | 59 |
</li> |
60 |
+ <li @if(param.sharerId == currentUserId){ class="active"}> |
|
61 |
+ <a pjax-filter href="#" |
|
62 |
+ data-author-id="" |
|
63 |
+ data-assignee-id="" |
|
64 |
+ data-commenter-id="" |
|
65 |
+ data-milestone-id="@param.milestoneId" |
|
66 |
+ data-mention-id="" |
|
67 |
+ data-sharer-id="@currentUserId"> |
|
68 |
+ @Messages("issue.list.sharedWithMe") (@IssueSharer.getNumberOfIssuesSharedWithUser(currentUserId)) |
|
69 |
+ </a> |
|
70 |
+ </li> |
|
65 | 71 |
} |
66 | 72 |
</ul> |
--- app/views/issue/my_partial_search.scala.html
+++ app/views/issue/my_partial_search.scala.html
... | ... | @@ -1,11 +1,13 @@ |
1 | 1 |
@** |
2 | 2 |
* Yona, 21st Century Project Hosting SW |
3 | 3 |
* |
4 |
-* Copyright Yona & Yobi Authors & NAVER Corp. |
|
4 |
+* Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp. |
|
5 | 5 |
* https://yona.io |
6 | 6 |
**@ |
7 | 7 |
@import java.util |
8 |
-@(title: String, currentPage: com.avaje.ebean.Page[Issue], param:models.support.SearchCondition, project:Project) |
|
8 |
+@import com.avaje.ebean.Page |
|
9 |
+@import models.support.SearchCondition |
|
10 |
+@(title: String, currentPage: Page[Issue], param:SearchCondition, project:Project) |
|
9 | 11 |
|
10 | 12 |
@import helper._ |
11 | 13 |
@import models.enumeration._ |
... | ... | @@ -33,6 +35,7 @@ |
33 | 35 |
<input type="hidden" name="commenterId" value="@param.commenterId" data-search="commenterId"> |
34 | 36 |
<input type="hidden" name="assigneeId" value="@param.assigneeId" data-search="assigneeId"> |
35 | 37 |
<input type="hidden" name="mentionId" value="@param.mentionId" data-search="mentionId"> |
38 |
+ <input type="hidden" name="sharerId" value="@param.sharerId" data-search="sharerId"> |
|
36 | 39 |
<div class="search myissues-search-input"> |
37 | 40 |
<div class="search-bar"> |
38 | 41 |
<input name="filter" class="textbox full" type="text" value="@param.filter" placeholder="@Messages("issue.search")"> |
--- conf/messages
+++ conf/messages
... | ... | @@ -298,6 +298,7 @@ |
298 | 298 |
issue.list.authoredByMe = Created |
299 | 299 |
issue.list.commentedByMe = Commented |
300 | 300 |
issue.list.mentionedOfMe = Mentioned |
301 |
+issue.list.sharedWithMe = Shared |
|
301 | 302 |
issue.menu.new = New issue |
302 | 303 |
issue.menu.new.mine = New issue - personal inbox |
303 | 304 |
issue.myIssue = My issues |
--- conf/messages.ko-KR
+++ conf/messages.ko-KR
... | ... | @@ -298,6 +298,7 @@ |
298 | 298 |
issue.list.authoredByMe = 작성한 이슈 |
299 | 299 |
issue.list.commentedByMe = 댓글 남긴 이슈 |
300 | 300 |
issue.list.mentionedOfMe = 나를 언급한 이슈 |
301 |
+issue.list.sharedWithMe = 공유된 이슈 |
|
301 | 302 |
issue.menu.new = 새 이슈 |
302 | 303 |
issue.menu.new.mine = 새 이슈 - 개인 inbox |
303 | 304 |
issue.myIssue = 내 이슈 |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?