doortts doortts 2018-01-31
my-issues: Show shared issue list
@b68f3fdbbb74de5de99322769895be2b2f5fc62a
app/controllers/IssueApp.java
--- app/controllers/IssueApp.java
+++ app/controllers/IssueApp.java
@@ -108,7 +108,7 @@
 
     private static boolean hasNotConditions(models.support.SearchCondition searchCondition) {
         return searchCondition.assigneeId == null && searchCondition.authorId == null && searchCondition.mentionId == null
-                && searchCondition.commenterId == null;
+                && searchCondition.commenterId == null && searchCondition.sharerId == null;
     }
 
     @Transactional
app/models/IssueSharer.java
--- app/models/IssueSharer.java
+++ app/models/IssueSharer.java
@@ -7,6 +7,7 @@
 
 package models;
 
+import models.enumeration.State;
 import play.db.ebean.Model;
 
 import javax.persistence.*;
@@ -49,4 +50,11 @@
         }
         return issueSharer;
     }
+
+    public static int getNumberOfIssuesSharedWithUser(Long userId){
+        return find.where()
+                .eq("user.id", userId)
+                .eq("issue.state", State.OPEN)
+                .findRowCount();
+    }
 }
app/models/support/SearchCondition.java
--- app/models/support/SearchCondition.java
+++ app/models/support/SearchCondition.java
@@ -1,23 +1,9 @@
 /**
- * Yobi, Project Hosting SW
- *
- * Copyright 2012 NAVER Corp.
- * http://yobi.io
- *
- * @author Tae
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+ * Yona, 21st Century Project Hosting SW
+ * <p>
+ * Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp.
+ * https://yona.io
+ **/
 package models.support;
 
 import com.avaje.ebean.ExpressionList;
@@ -50,6 +36,7 @@
     public Project project;
 
     public Long mentionId;
+    public Long sharerId;
     public Organization organization;
     public List<String> projectNames;
 
@@ -76,6 +63,7 @@
         one.assigneeId = this.assigneeId;
         one.commenterId = this.commenterId;
         one.mentionId = this.mentionId;
+        one.sharerId = this.sharerId;
         one.dueDate = this.dueDate;
         one.projectNames = this.projectNames;
         return one;
@@ -151,6 +139,11 @@
         return this;
     }
 
+    public SearchCondition setSharerId(Long sharerId) {
+        this.sharerId = sharerId;
+        return this;
+    }
+
     public ExpressionList<Issue> asExpressionList(@Nonnull Organization organization) {
         ExpressionList<Issue> el = Issue.finder.where();
 
@@ -163,6 +156,8 @@
         setAssigneeIfExists(el);
         setAuthorIfExist(el);
         setMentionedIssuesIfExist(el);
+        setSharedIssuesIfExist(el);
+
         setFilteredStringIfExist(el);
 
         if (commentedCheck) {
@@ -279,6 +274,7 @@
         setAuthorIfExist(el);
         setCommenterIfExist(el, null);
         setMentionedIssuesIfExist(el);
+        setSharedIssuesIfExist(el);
         setFilteredStringIfExist(el);
 
         if (commentedCheck) {
@@ -309,6 +305,23 @@
             User mentionUser = User.find.byId(mentionId);
             if(!mentionUser.isAnonymous()) {
                 List<Long> ids = getMentioningIssueIds(mentionUser);
+
+                if (ids.isEmpty()) {
+                    // No need to progress because the query matches nothing.
+                    el.idEq(-1);
+                } else {
+                    el.idIn(ids);
+                }
+            }
+        }
+    }
+
+    private void setSharedIssuesIfExist(ExpressionList<Issue> el) {
+
+        if (sharerId != null) {
+            User user = User.find.byId(sharerId);
+            if(!user.isAnonymous()) {
+                List<Long> ids = getSharedIssueIds(user);
 
                 if (ids.isEmpty()) {
                     // No need to progress because the query matches nothing.
@@ -373,6 +386,18 @@
         return new ArrayList<>(ids);
     }
 
+    private List<Long> getSharedIssueIds(User user) {
+        Set<Long> ids = new HashSet<>();
+        List<IssueSharer> issueSharers = IssueSharer.find.where()
+                .eq("user.id", user.id)
+                .findList();
+        for (IssueSharer issueSharer : issueSharers) {
+            ids.add(issueSharer.issue.id);
+        }
+
+        return new ArrayList<>(ids);
+    }
+
     public ExpressionList<Issue> asExpressionList(Project project) {
         ExpressionList<Issue> el = Issue.finder.where();
         if( project != null ){
@@ -417,6 +442,7 @@
         }
 
         setCommenterIfExist(el, project);
+        setSharedIssuesIfExist(el);
 
         if (milestoneId != null) {
             if (milestoneId.equals(Milestone.NULL_MILESTONE_ID)) {
@@ -457,4 +483,23 @@
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
         return sdf.format(this.dueDate);
     }
+
+    @Override
+    public String toString() {
+        return "SearchCondition{" +
+                "state='" + state + '\'' +
+                ", commentedCheck=" + commentedCheck +
+                ", milestoneId=" + milestoneId +
+                ", labelIds=" + labelIds +
+                ", authorId=" + authorId +
+                ", assigneeId=" + assigneeId +
+                ", project=" + project +
+                ", mentionId=" + mentionId +
+                ", sharerId=" + sharerId +
+                ", organization=" + organization +
+                ", projectNames=" + projectNames +
+                ", commenterId=" + commenterId +
+                ", dueDate=" + dueDate +
+                '}';
+    }
 }
app/views/issue/my_partial_list_quicksearch.scala.html
--- app/views/issue/my_partial_list_quicksearch.scala.html
+++ app/views/issue/my_partial_list_quicksearch.scala.html
@@ -1,66 +1,72 @@
 @**
-* Yobi, Project Hosting SW
+* Yona, 21st Century Project Hosting SW
 *
-* Copyright 2014 NAVER Corp.
-* http://yobi.io
-*
-* @author Jihan Kim
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*   http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
+* Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp.
+* https://yona.io
 **@
-@(param:models.support.SearchCondition)
+@import models.support.SearchCondition
+@(param:SearchCondition)
+
+@currentUserId = @{
+    UserApp.currentUser().id
+}
 
 <ul class="lst-stacked unstyled">
     @if(!UserApp.currentUser().isAnonymous()){
-    <li @if(param.assigneeId == UserApp.currentUser().id){ class="active"}>
+    <li @if(param.assigneeId == currentUserId){ class="active"}>
         <a pjax-filter href="#"
             data-author-id=""
-            data-assignee-id="@UserApp.currentUser.id"
+            data-assignee-id="@currentUserId"
             data-commenter-id=""
             data-milestone-id="@param.milestoneId"
-            data-mention-id="">
+            data-mention-id=""
+            data-sharer-id="">
             @Messages("issue.list.assignedToMe")
         </a>
     </li>
-    <li @if(param.authorId == UserApp.currentUser().id){ class="active"}>
+    <li @if(param.authorId == currentUserId){ class="active"}>
         <a pjax-filter href="#"
-            data-author-id="@UserApp.currentUser.id"
+            data-author-id="@currentUserId"
             data-assignee-id=""
             data-commenter-id=""
             data-milestone-id="@param.milestoneId"
-            data-mention-id="">
+            data-mention-id=""
+            data-sharer-id="">
             @Messages("issue.list.authoredByMe")
         </a>
     </li>
-    <li @if(param.commenterId == UserApp.currentUser().id){ class="active"}>
+    <li @if(param.commenterId == currentUserId){ class="active"}>
         <a pjax-filter href="#"
         data-author-id=""
         data-assignee-id=""
-        data-commenter-id="@UserApp.currentUser.id"
+        data-commenter-id="@currentUserId"
         data-milestone-id="@param.milestoneId"
-        data-mention-id="">
+        data-mention-id=""
+        data-sharer-id="">
         @Messages("issue.list.commentedByMe")
         </a>
     </li>
-    <li @if(param.mentionId == UserApp.currentUser().id){ class="active"}>
+    <li @if(param.mentionId == currentUserId){ class="active"}>
         <a pjax-filter href="#"
             data-author-id=""
             data-assignee-id=""
             data-commenter-id=""
             data-milestone-id="@param.milestoneId"
-            data-mention-id="@UserApp.currentUser.id">
+            data-mention-id="@currentUserId"
+            data-sharer-id="">
             @Messages("issue.list.mentionedOfMe")
         </a>
     </li>
+    <li @if(param.sharerId == currentUserId){ class="active"}>
+        <a pjax-filter href="#"
+        data-author-id=""
+        data-assignee-id=""
+        data-commenter-id=""
+        data-milestone-id="@param.milestoneId"
+        data-mention-id=""
+        data-sharer-id="@currentUserId">
+        @Messages("issue.list.sharedWithMe") (@IssueSharer.getNumberOfIssuesSharedWithUser(currentUserId))
+        </a>
+    </li>
     }
 </ul>
app/views/issue/my_partial_search.scala.html
--- app/views/issue/my_partial_search.scala.html
+++ app/views/issue/my_partial_search.scala.html
@@ -1,11 +1,13 @@
 @**
 * Yona, 21st Century Project Hosting SW
 *
-* Copyright Yona & Yobi Authors & NAVER Corp.
+* Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp.
 * https://yona.io
 **@
 @import java.util
-@(title: String, currentPage: com.avaje.ebean.Page[Issue], param:models.support.SearchCondition, project:Project)
+@import com.avaje.ebean.Page
+@import models.support.SearchCondition
+@(title: String, currentPage: Page[Issue], param:SearchCondition, project:Project)
 
 @import helper._
 @import models.enumeration._
@@ -33,6 +35,7 @@
                 <input type="hidden" name="commenterId" value="@param.commenterId" data-search="commenterId">
                 <input type="hidden" name="assigneeId" value="@param.assigneeId" data-search="assigneeId">
                 <input type="hidden" name="mentionId" value="@param.mentionId" data-search="mentionId">
+                <input type="hidden" name="sharerId" value="@param.sharerId" data-search="sharerId">
                 <div class="search myissues-search-input">
                     <div class="search-bar">
                         <input name="filter" class="textbox full" type="text" value="@param.filter" placeholder="@Messages("issue.search")">
conf/messages
--- conf/messages
+++ conf/messages
@@ -298,6 +298,7 @@
 issue.list.authoredByMe = Created
 issue.list.commentedByMe = Commented
 issue.list.mentionedOfMe = Mentioned
+issue.list.sharedWithMe = Shared
 issue.menu.new = New issue
 issue.menu.new.mine = New issue - personal inbox
 issue.myIssue = My issues
conf/messages.ko-KR
--- conf/messages.ko-KR
+++ conf/messages.ko-KR
@@ -298,6 +298,7 @@
 issue.list.authoredByMe = 작성한 이슈
 issue.list.commentedByMe = 댓글 남긴 이슈
 issue.list.mentionedOfMe = 나를 언급한 이슈
+issue.list.sharedWithMe = 공유된 이슈
 issue.menu.new = 새 이슈
 issue.menu.new.mine = 새 이슈 - 개인 inbox
 issue.myIssue = 내 이슈
Add a comment
List