[Notice] Announcing the End of Demo Server [Read me]
Keesun Baik 2013-04-30
HIVE-190 adding posts and issues view page for site admin
@e1c87ce2a79897fcbd7ec93c193f206dae525da5
app/controllers/SiteApp.java
--- app/controllers/SiteApp.java
+++ app/controllers/SiteApp.java
@@ -1,37 +1,23 @@
 package controllers;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.HashSet;
-
-import models.ProjectUser;
-import org.apache.commons.mail.*;
-
-import models.Project;
-import models.User;
+import com.avaje.ebean.Page;
+import info.schleichardt.play2.mailplugin.Mailer;
+import models.*;
+import org.apache.commons.mail.EmailException;
 import org.apache.commons.mail.SimpleEmail;
-import org.codehaus.jackson.JsonNode;
 import play.Configuration;
 import play.Logger;
+import play.i18n.Messages;
 import play.mvc.Controller;
 import play.mvc.Http;
 import play.mvc.Result;
 import utils.Constants;
+import views.html.site.*;
 
-import views.html.site.setting;
-import views.html.site.mail;
-import views.html.site.massMail;
-import views.html.site.userList;
-import views.html.site.projectList;
+import java.util.*;
 
-import com.avaje.ebean.Page;
 import static play.data.Form.form;
 import static play.libs.Json.toJson;
-import play.i18n.Messages;
-
-import info.schleichardt.play2.mailplugin.Mailer;
 
 public class SiteApp extends Controller {
     public static Result sendMail() throws EmailException{
@@ -86,16 +72,26 @@
     public static Result setting() {
         return ok(setting.render("title.siteSetting"));
     }
-    
+
     public static Result userList(int pageNum, String loginId) {
         return ok(userList.render("title.siteSetting", User.findUsers(pageNum, loginId)));
     }
-    
+
+    public static Result postList(int pageNum) {
+        Page<Posting> page = Posting.finder.order("createdDate DESC").findPagingList(30).getPage(pageNum - 1);
+        return ok(postList.render("title.siteSetting", page));
+    }
+
+    public static Result issueList(int pageNum) {
+        Page<Issue> page = Issue.finder.order("createdDate DESC").findPagingList(30).getPage(pageNum - 1);
+        return ok(issueList.render("title.siteSetting", page));
+    }
+
     public static Result searchUser() {
         String loginId = form(User.class).bindFromRequest().get().loginId;
         return redirect(routes.SiteApp.userList(0, loginId));
     }
-    
+
     public static Result deleteUser(Long userId) {
         if( User.findByLoginId(session().get("loginId")).isSiteManager() ){
             if(Project.isOnlyManager(userId).size() == 0)
@@ -108,12 +104,12 @@
 
         return redirect(routes.SiteApp.userList(0, null));
     }
-        
+
     public static Result projectList(String filter) {
         Page<Project> projects = Project.findByName(filter, 25, 0);
         return ok(projectList.render("title.projectList", projects, filter));
     }
-    
+
     public static Result deleteProject(Long projectId){
         if( User.findByLoginId(session().get("loginId")).isSiteManager() ){
             Project.find.byId(projectId).delete();
@@ -122,7 +118,7 @@
         }
         return redirect(routes.SiteApp.projectList(""));
     }
-    
+
     public static Result softwareMap() {
         return TODO;
     }
app/models/Attachment.java
--- app/models/Attachment.java
+++ app/models/Attachment.java
@@ -88,6 +88,12 @@
                 .eq("containerId", containerId).findList();
     }
 
+    public static int countByContainer(ResourceType containerType, Long containerId) {
+        return find.where()
+                .eq("containerType", containerType)
+                .eq("containerId", containerId).findRowCount();
+    }
+
     public static List<Attachment> findByContainer(Resource resource) {
         return findByContainer(resource.getType(), resource.getId());
     }
 
app/views/site/issueList.scala.html (added)
+++ app/views/site/issueList.scala.html
@@ -0,0 +1,40 @@
+@(message: String, currentPage: com.avaje.ebean.Page[Issue])
+
+@siteMngMain(message) {
+    <h2>@Messages("site.sidebar.issueList")</h2>
+
+    <div class="row-fluid">
+        <table class="table table-striped table-condensed">
+            <thead>
+                <tr>
+                    <th>@Messages("project.name")</th>
+                    <th>@Messages("issue.author")</th>
+                    <th>@Messages("issue.title")</th>
+                    <th>@Messages("issue.createdDate")</th>
+                    <th>@Messages("issue.attachment")</th>
+                    <th>@Messages("issue.numOfComments")</th>
+                </tr>
+            </thead>
+            <tbody>
+                @for(issue <- currentPage.getList()) {
+                    @issuelisting(issue)
+                }
+            </tbody>
+        </table>
+    </div>
+
+    <div class="row-fluid">
+        <center>@pagination(currentPage, 5, "pagination", "/sites/issueList")</center>
+    </div>
+}
+
+@issuelisting(issue: models.Issue) = {
+    <tr>
+        <td>@issue.project.name</td>
+        <td>@issue.authorName</td>
+        <td><a href="@routes.BoardApp.post(issue.project.owner, issue.project.name, issue.id)">@issue.title</a></td>
+        <td>@utils.TemplateHelper.agoString(issue.ago())</td>
+        <td>@models.Attachment.countByContainer(models.enumeration.ResourceType.ISSUE_POST, issue.id)</td>
+        <td>@issue.numOfComments</td>
+    </tr>
+}(파일 끝에 줄바꿈 문자 없음)
 
app/views/site/pagination.scala.html (added)
+++ app/views/site/pagination.scala.html
@@ -0,0 +1,46 @@
+@(page:com.avaje.ebean.Page[_ <: play.db.ebean.Model], pageNum:Int, divId:String, listUrl:String)
+
+@{
+    var currentPageNum = page.getPageIndex + 1
+    var lastPageNum = page.getTotalPageCount()
+    var str = ""
+
+    if(currentPageNum <= pageNum/2) {
+        currentPageNum = pageNum/2 +1
+    } else if(currentPageNum > lastPageNum - pageNum/2) {
+        currentPageNum = lastPageNum - pageNum/2 - 1
+    }
+    makeList(currentPageNum)
+}
+@makeList(currentPageNum:Int) = {
+    <div class='pagination' id="@divId"><ul>
+    @if(page.hasPrev){
+        @makeLink("Prev", page.getPageIndex)
+    } else {
+        <li class="disabled"><a>Prev</a></li>
+    }
+
+    @if(page.getTotalPageCount() < pageNum) {
+        @for(x <- (1 to page.getTotalPageCount())){
+            @makeLink(x + "", x)
+        }
+    } else {
+        @for( x <- (currentPageNum - pageNum/2 to currentPageNum + pageNum/2)){
+            @makeLink(x + "", x)
+        }
+    }
+
+
+    @if(page.hasNext) {
+        @makeLink("Next",page.getPageIndex + 2)
+    } else {
+        <li class="disabled"><a>Next</a></li>
+    }
+
+    </ul></div>
+}
+@makeLink(title:String, index:Int) = {
+    <li class="@if((page.getPageIndex + 1).equals(index)){active}">
+      <a href="@(listUrl + "?pageNum=" + index)" pageNum="@index">@title</a>
+    </li>
+}(파일 끝에 줄바꿈 문자 없음)
 
app/views/site/postList.scala.html (added)
+++ app/views/site/postList.scala.html
@@ -0,0 +1,40 @@
+@(message: String, currentPage: com.avaje.ebean.Page[Posting])
+
+@siteMngMain(message) {
+    <h2>@Messages("site.sidebar.postList")</h2>
+
+    <div class="row-fluid">
+        <table class="table table-striped table-condensed">
+            <thead>
+                <tr>
+                    <th>@Messages("project.name")</th>
+                    <th>@Messages("post.author")</th>
+                    <th>@Messages("post.title")</th>
+                    <th>@Messages("post.createdDate")</th>
+                    <th>@Messages("post.attachment")</th>
+                    <th>@Messages("post.numOfComments")</th>
+                </tr>
+            </thead>
+            <tbody>
+                @for(post <- currentPage.getList()) {
+                    @postlisting(post)
+                }
+            </tbody>
+        </table>
+    </div>
+
+    <div class="row-fluid">
+        <center>@pagination(currentPage, 5, "pagination", "/sites/postList")</center>
+    </div>
+}
+
+@postlisting(post: models.Posting) = {
+    <tr>
+        <td>@post.project.name</td>
+        <td>@post.authorName</td>
+        <td><a href="@routes.BoardApp.post(post.project.owner, post.project.name, post.id)">@post.title</a></td>
+        <td>@utils.TemplateHelper.agoString(post.ago())</td>
+        <td>@models.Attachment.countByContainer(models.enumeration.ResourceType.BOARD_POST, post.id)</td>
+        <td>@post.numOfComments</td>
+    </tr>
+}(파일 끝에 줄바꿈 문자 없음)
app/views/site/projectList.scala.html
--- app/views/site/projectList.scala.html
+++ app/views/site/projectList.scala.html
@@ -7,7 +7,7 @@
       <button type="submit" class="btn">검색</button>
     </form>
   </div>
-  
+
   <div class="row-fluid">
     <table class="table table-striped table-condensed">
       <thead>
@@ -24,9 +24,9 @@
             <td>@project.owner</td>
             <td>
               <a class="btn btn-danger" data-toggle="modal" href="#alertDeletion@project.id">@Messages("button.delete")</a>
-            </td> 
+            </td>
           </tr>
-          
+
           <div class="modal hide" id="alertDeletion@project.id">
               <div class="modal-header">
                   <button type="button" class="close" data-dismiss="modal">×</button>
@@ -44,7 +44,7 @@
       </tbody>
     </table>
   </div>
-  
+
   <div class="row-fluid">
     <center>@paginationForUserList(currentPage, 5, "pagination")</center>
   </div>
app/views/site/sidebar.scala.html
--- app/views/site/sidebar.scala.html
+++ app/views/site/sidebar.scala.html
@@ -17,6 +17,12 @@
         <li class="@isActiveMenu(routes.SiteApp.userList())">
             <a href="@routes.SiteApp.userList()"><i class="icon-user"></i>@Messages("site.sidebar.userList")</a>
         </li>
+        <li class="@isActiveMenu(routes.SiteApp.postList())">
+            <a href="@routes.SiteApp.postList()"><i class="icon-pencil"></i>@Messages("site.sidebar.postList")</a>
+        </li>
+        <li class="@isActiveMenu(routes.SiteApp.issueList())">
+            <a href="@routes.SiteApp.issueList()"><i class="icon-check"></i>@Messages("site.sidebar.issueList")</a>
+        </li>
         <li class="@isActiveMenu(routes.SiteApp.projectList())">
             <a href="@routes.SiteApp.projectList()"><i class="icon-folder-open"></i>@Messages("site.sidebar.projectList")</a>
         </li>
conf/messages.en
--- conf/messages.en
+++ conf/messages.en
@@ -62,7 +62,7 @@
 label.confirm.delete = Are you Sure?
 label.select = Select Label
 label.error.duplicated = Failed to create new label. It might be same label exists already.
-label.error.creationFailed = Failed to create new label. It might be server error or your request is invalid. 
+label.error.creationFailed = Failed to create new label. It might be server error or your request is invalid.
 
 order.all = All
 order.date = Date
@@ -116,7 +116,7 @@
 milestone.form.dueDate = Choose due date
 milestone.error.title = Title is required
 milestone.error.content = Description is required
-milestone.error.duedateFormat = Invalid format of due date (YYYY-MM-DD) 
+milestone.error.duedateFormat = Invalid format of due date (YYYY-MM-DD)
 
 #Issue
 issue.state.unit = issues
@@ -192,7 +192,11 @@
 issue.downloadAsExcel = Download as Excel
 issue.search = SEARCH
 issue.error.emptyTitle = Title of this issue is required
-issue.error.emptyBody = Description about this issue is required 
+issue.error.emptyBody = Description about this issue is required
+issue.title = Title
+issue.createdDate = Created Date
+issue.attachment = Attachment
+issue.numOfComments = Comment Count
 
 #Post
 post.new = New
@@ -210,6 +214,10 @@
 post.popup.fileAttach.contents = Please, select file to attach
 post.edit.rejectNotAuthor = You don't have permisstion to access.
 post.update.error = Errors on Input Value
+post.title = Title
+post.createdDate = Created Date
+post.attachment = Attachment
+post.numOfComments = Comment Count
 
 #Project
 project.myproject = MY PROJECTS
@@ -278,6 +286,8 @@
 site.sidebar = Site Management
 site.sidebar.setting = Site Setting
 site.sidebar.userList = Users
+site.sidebar.postList = Posts
+site.sidebar.issueList = Issues
 site.sidebar.projectList = Projects
 site.sidebar.softwareMap = Software Map
 site.sidebar.mailSend = Send a Email
@@ -398,7 +408,7 @@
 none = None
 comment = Comment
 noAssignee = No Assignee
-noMilestone = No Milestone 
+noMilestone = No Milestone
 
 #validation
 validation.tooShortPassword = The password field must be at least 4 characters in length.
conf/messages.ko
--- conf/messages.ko
+++ conf/messages.ko
@@ -64,7 +64,7 @@
 label.confirm.delete = 라벨을 삭제하면 이슈에 지정한 라벨도 함께 제거됩니다. 정말 삭제하시겠습니까?
 label.select = 라벨 선택
 label.error.duplicated = 라벨 생성에 실패했습니다.\n이미 동일한 라벨이 존재할지도 모릅니다.
-label.error.creationFailed = 라벨 생성에 실패했습니다.\n서버에 문제가 있거나 올바른 요청이 아닐 수 있습니다. 
+label.error.creationFailed = 라벨 생성에 실패했습니다.\n서버에 문제가 있거나 올바른 요청이 아닐 수 있습니다.
 
 order.all = 전체
 order.date = 날짜순
@@ -121,7 +121,7 @@
 milestone.form.dueDate = 완료일을 선택하세요
 milestone.error.title = 마일스톤 제목을 입력해주세요
 milestone.error.content = 마일스톤 내용을 입력해주세요
-milestone.error.duedateFormat = 완료일 형식이 잘못되었습니다. YYYY-MM-DD 형식으로 입력해주세요. 
+milestone.error.duedateFormat = 완료일 형식이 잘못되었습니다. YYYY-MM-DD 형식으로 입력해주세요.
 
 #Issue
 issue.state.unit = 이슈
@@ -198,7 +198,11 @@
 issue.downloadAsExcel = 엑셀파일로 다운받기
 issue.search = 검색
 issue.error.emptyTitle = 이슈 제목을 입력해주세요
-issue.error.emptyBody = 이슈 내용을 입력해주세요  
+issue.error.emptyBody = 이슈 내용을 입력해주세요
+issue.title = 제목
+issue.createdDate = 작성일
+issue.attachment = 첨부파일
+issue.numOfComments = 댓글개수
 
 #Post
 post.new = 새글
@@ -216,6 +220,10 @@
 post.popup.fileAttach.contents = 첨부할 파일을 선택해주세요.
 post.edit.rejectNotAuthor = 글쓴이가 아닙니다.
 post.update.error = 입력값 오류
+post.title = 제목
+post.createdDate = 작성일
+post.attachment = 첨부파일
+post.numOfComments = 댓글개수
 
 #Project
 project.myproject = 내 프로젝트
@@ -284,7 +292,9 @@
 #Site
 site.sidebar = 사이트 관리
 site.sidebar.setting = 설정
-site.sidebar.userList = 유저 관리
+site.sidebar.userList = 유저
+site.sidebar.postList = 게시물
+site.sidebar.issueList = 이슈
 site.sidebar.projectList = 프로젝트 설정
 site.sidebar.softwareMap = 소프트웨어 맵
 site.sidebar.mailSend = 메일 발송
@@ -406,7 +416,7 @@
 none = 없음
 comment = 댓글
 noAssignee = 담당자 없음
-noMilestone = 마일스톤 없음 
+noMilestone = 마일스톤 없음
 
 #validation
 validation.tooShortPassword = 비밀번호를 4자 이상으로 만들어 주세요!
conf/routes
--- conf/routes
+++ conf/routes
@@ -47,6 +47,9 @@
 POST    /lostPassword                                   controllers.PasswordResetApp.requestResetPasswordEmail()
 GET     /resetPassword                                  controllers.PasswordResetApp.resetPasswordForm(s:String)
 POST    /resetPassword                                  controllers.PasswordResetApp.resetPassword()
+GET     /sites/postList                                 controllers.SiteApp.postList(pageNum: Int ?= 1)
+GET     /sites/issueList                                controllers.SiteApp.issueList(pageNum: Int ?= 1)
+
 
 # Attachments
 GET     /files                                          controllers.AttachmentApp.getFileList()
Add a comment
List