doortts doortts 2017-09-15
subtask: Change subtask feature
- Change new issue button to new subtask button in issue view page
- Hide subtasks in all list
- Make parent issue status bar more distinguishable
@44f616080f9a9ea08a8f290333d651fbacae773a
app/assets/stylesheets/less/_common.less
--- app/assets/stylesheets/less/_common.less
+++ app/assets/stylesheets/less/_common.less
@@ -110,6 +110,12 @@
     background:#f0f0f0;
     filter:none;
 
+    &.done-outline {
+        border: 1px solid @light-green;
+    }
+    &.red-outline {
+        border: 1px solid @yona-red;
+    }
     .box-shadow(inset 0px 1px 1px rgba(0,0,0,0.25));
     .bar {
         height:100%;
@@ -117,6 +123,7 @@
         &.orange { background:@orange; .box-shadow(none); } // #f28149
         &.blue   { background:@blue;   .box-shadow(none); }
         &.grey   { background:@gray-9e;   .box-shadow(none); }
+        &.red    { background:@yona-red;   .box-shadow(none); }
         &.done   { background:@light-green;   .box-shadow(none); }
         &.open   { background:@state-open; .box-shadow(none); }
         &.closed { background:@state-closed; .box-shadow(none); }
app/assets/stylesheets/less/_page.less
--- app/assets/stylesheets/less/_page.less
+++ app/assets/stylesheets/less/_page.less
@@ -7020,3 +7020,17 @@
         }
     }
 }
+
+.subtask-mark {
+    border: 1px solid #e95e01;
+    border-radius: 3px;
+    padding: 2px 5px;
+    font-size: 14px;
+    color: #e95e01;
+    margin-right: 5px;
+}
+.subtask-number {
+    color: darkgrey;
+    font-size: 12px;
+    margin-right: 5px;
+}
app/assets/stylesheets/less/_variables.less
--- app/assets/stylesheets/less/_variables.less
+++ app/assets/stylesheets/less/_variables.less
@@ -63,6 +63,7 @@
 @yobi-orange : #FF7332;
 @yobi-orange-dark : #E95E01;
 @yobi-red : #C93426;
+@yona-red : #f44336;
 @yobi-red-dark : #B13427;
 @yobi-white :#FFF;
 @yobi-white-dark :#F2F2F2;
app/models/Issue.java
--- app/models/Issue.java
+++ app/models/Issue.java
@@ -196,9 +196,9 @@
 
     public static int countIssues(Long projectId, State state) {
         if (state == State.ALL) {
-            return finder.where().eq("project.id", projectId).findRowCount();
+            return finder.where().eq("project.id", projectId).isNull("parent.id").findRowCount();
         } else {
-            return finder.where().eq("project.id", projectId).eq("state", state).findRowCount();
+            return finder.where().eq("project.id", projectId).isNull("parent.id").eq("state", state).findRowCount();
         }
     }
 
app/models/support/SearchCondition.java
--- app/models/support/SearchCondition.java
+++ app/models/support/SearchCondition.java
@@ -443,6 +443,10 @@
             el.lt("dueDate", DateUtils.addDays(dueDate, 1));
         }
 
+        if (authorId == null && StringUtils.isBlank(filter) && assigneeId == null && mentionId == null) {
+            el.isNull("parent.id");
+        }
+
         return el;
     }
 
app/views/issue/partial_list_subtask.scala.html
--- app/views/issue/partial_list_subtask.scala.html
+++ app/views/issue/partial_list_subtask.scala.html
@@ -14,8 +14,8 @@
     @defining(Issue.countByParentIssueIdAndState(issue.id, State.OPEN)) { openIssueCount =>
         @defining(Issue.countByParentIssueIdAndState(issue.id, State.CLOSED)) { closedIssueCount =>
             @defining(getPercent(closedIssueCount.toDouble, openIssueCount + closedIssueCount)) { percentage =>
-                <div class="upload-progress">
-                    <div class="bar @if(percentage == 100) {done} else {grey}" style="width: @percentage%;" title="Subtask"></div>
+                <div class="upload-progress @if(percentage == 100){done-outline} else {red-outline}">
+                    <div class="bar @if(percentage == 100) {done} else {red}" style="width: @percentage%;" title="Subtask"></div>
                 </div>
                 <span class="completion-ratio @if(percentage == 100){txt-green}">@if(percentage != 100){@closedIssueCount/}@(closedIssueCount + openIssueCount)</span>
             }
app/views/issue/partial_select_subtask.scala.html
--- app/views/issue/partial_select_subtask.scala.html
+++ app/views/issue/partial_select_subtask.scala.html
@@ -6,7 +6,7 @@
 **@
 @(project:Project, parentIssueId:Long, currentIssueId:Long)
 
-@showOption = @{Option(parentIssueId).isDefined && Option(currentIssueId).isDefined}
+@showOption = @{Option(parentIssueId).isDefined || Option(currentIssueId).isDefined}
 @hasChildIssue = @{Option(currentIssueId).isDefined && Issue.finder.byId(currentIssueId).hasChildIssue}
 @import utils.TemplateHelper._
 
app/views/issue/view.scala.html
--- app/views/issue/view.scala.html
+++ app/views/issue/view.scala.html
@@ -66,10 +66,10 @@
         @if(!openChildIssues.isEmpty || !closedChildIssues.isEmpty) {
             <div class="child-issues">
                 @defining(Issue.finder.byId(parentIssueId)) { parentIssue =>
-                    <div class="issue-item parent-issue"><a href="@routes.IssueApp.issue(parentIssue.project.owner, parentIssue.project.name, parentIssue.getNumber)" class="@if(parentIssue.id == issue.id){bold}">#@parentIssue.getNumber @parentIssue.title @if(parentIssue.assignee != null) {- @parentIssue.assignee.user.name}</a>
+                    <div class="issue-item parent-issue"><a href="@routes.IssueApp.issue(parentIssue.project.owner, parentIssue.project.name, parentIssue.getNumber)" class="@if(parentIssue.id == issue.id){bold}">#@parentIssue.getNumber @parentIssue.title @if(parentIssue.assignee != null) {- @parentIssue.assignee.user.getPureNameOnly}</a>
                         @defining(getPercent(closedChildIssues.size.toDouble, (openChildIssues.size + closedChildIssues.size).toDouble)) { percentage =>
-                        <div class="upload-progress">
-                            <div class="bar @if(percentage == 100){done} else {grey}" style="width: @percentage%;" title="Subtask"></div>
+                        <div class="upload-progress @if(percentage == 100){done-outline} else {red-outline}">
+                            <div class="bar @if(percentage == 100){done} else {red}" style="width: @percentage%;" title="Subtask"></div>
                         </div>
                         <span class="@if(percentage == 100){txt-green}">@if(percentage != 100){@closedChildIssues.size/}@(openChildIssues.size + closedChildIssues.size)</span>
                         <span class="parent-issue-state @parentIssue.state.state">@Messages("issue.state." + parentIssue.state.state)</span>
@@ -81,7 +81,7 @@
                     <div class="issue-item @if(childIssue.id == issue.id){bold}">
                         <span class="state-label open"></span>
                         <a href="@routes.IssueApp.issue(childIssue.project.owner, childIssue.project.name, childIssue.getNumber)">
-                            <span class="item-name">@childIssue.title @if(childIssue.assignee != null) {- @childIssue.assignee.user.name}</span>
+                            <span class="item-name"><span class="subtask-number">#@childIssue.getNumber</span> @childIssue.title @if(childIssue.assignee != null) {- @childIssue.assignee.user.getPureNameOnly}</span>
                         </a>
                     </div>
                 }
@@ -89,7 +89,7 @@
                     <div class="issue-item @if(childIssue.id == issue.id){bold}">
                         <span class="state-label closed"><i class=" yobicon-checkmark"></i></span>
                         <a href="@routes.IssueApp.issue(childIssue.project.owner, childIssue.project.name, childIssue.getNumber)">
-                            <span class="item-name">@childIssue.title @if(childIssue.assignee != null) {- @childIssue.assignee.user.name}</span>
+                            <span class="item-name"><span class="subtask-number">#@childIssue.getNumber</span> @childIssue.title @if(childIssue.assignee != null) {- @childIssue.assignee.user.getPureNameOnly}</span>
                         </a>
                     </div>
                 }
@@ -114,6 +114,9 @@
                 <span class="badge badge-issue-@issue.state.state.toLowerCase">@Messages("issue.state." + issue.state.state)</span>
             </div>
             <div class="title">
+                @if(issue.parent != null) {
+                    <span class="subtask-mark">subtask</span>
+                }
                 <strong class="board-id">#@issue.getNumber</strong> @issue.title
                 <div class="pull-right hide show-in-mobile" style="font-size: 0.7em">
                     <span class="date" title="@JodaDateUtil.getDateString(issue.createdDate)">
@@ -246,7 +249,7 @@
                         <dl>
                             @if(project.menuSetting.issue) {
                                 <dd class="project-btn-item">
-                                    <a href="@routes.IssueApp.newIssueForm(project.owner, project.name)?parentIssueId=@parentIssueId" class="ybtn ybtn-success">@Messages("button.newIssue")</a>
+                                    <a href="@routes.IssueApp.newIssueForm(project.owner, project.name)?parentIssueId=@parentIssueId" class="ybtn ybtn-success">@Messages("button.newSubtask")</a>
                                 </dd>
                             }
                             <dt>@Messages("issue.assignee")</dt>
conf/messages
--- conf/messages
+++ conf/messages
@@ -61,6 +61,7 @@
 button.new.enrollment = Send sign-up request
 button.newIssue = New issue
 button.newProject = Create new project
+button.newSubtask = New subtask
 button.nextPage = Next page
 button.nextState.closed = Close issue
 button.nextState.open = Reopen issue
conf/messages.ko-KR
--- conf/messages.ko-KR
+++ conf/messages.ko-KR
@@ -61,6 +61,7 @@
 button.new.enrollment = 멤버 등록 요청하기
 button.newIssue = 새 이슈 등록
 button.newProject = 새 프로젝트 만들기
+button.newSubtask = 새 서브 태스크
 button.nextPage = 다음 페이지
 button.nextState.closed = 이슈 닫기
 button.nextState.open = 이슈 다시 열기
Add a comment
List