[Notice] Announcing the End of Demo Server [Read me]
Jihan Kim 2013-05-07
make userinfo to dropdown menu on navbar(HIVE-101), apply HIVE UI to board(HIVE-188), fix filter on board(HIVE-134), remove deprecated file (postValidate.scala.html), change default image of project(HIVE-213)
@c676c084d90b3d62c909035032dbfb58f2844889
app/assets/stylesheets/less/_hiveUI.less
--- app/assets/stylesheets/less/_hiveUI.less
+++ app/assets/stylesheets/less/_hiveUI.less
@@ -71,7 +71,8 @@
     line-height: 18px;
     height: 18px;
     border:0; padding:0; 
-
+    margin-right:5px;
+    
     .border-radius(2px);
     .box-shadow(0 1px 2px rgba(0, 0, 0, .25));
     .inline-block;
@@ -83,6 +84,7 @@
         background-color: darken(#707070, 10%);
         text-decoration: none;
     }
+    &.last { margin-right:0; }
 
     &.blue {
         background-color: @blue; /*#56B5D9*/
@@ -103,7 +105,7 @@
         color: #222;
         background-color: @white;
         &:hover { background-color: darken(@white, 10%); }
-    }
+    }    
 }
 a.nbtn, div.nbtn, span.nbtn, p.nbtn {
     vertical-align:middle;
@@ -115,6 +117,9 @@
     &.small  { padding:1px 10px; height:24px; line-height:1; }
     &.medium { padding:4px 20px; height:30px; line-height:1; }
     &.large  { padding:8px 30px; height:36px; line-height:1; font-size:15px; }
+}
+.nbtn-group:last-child {
+    margin-right:0px;
 }
 
 /* fileUpload button **/
@@ -191,7 +196,7 @@
 
 /** 화면 상단의 전체 검색 폼 **/
 .form-searchbar {
-    width: 146px; height: 19px;
+    width: 146px; height: 29px;
     margin: 0; padding: 0 6px;
     background-color: @search-bar-bg-color;
     border:1px solid @search-bar-border-color;
@@ -200,12 +205,12 @@
     .box-shadow(inset 0px 2px 3px rgba(0,0,0,0.12));
     
     .text {
-        width: 128px; height: 13px;
+        width: 128px; /*height: 13px;*/
         margin: 0; margin-right:3px;
         padding:4px 0px; 
         border: 0 none;
         
-        font-size: 11px;
+        font-size: 14px; /* 11px */
         color: @search-input-color;
         background-color: transparent;
        
@@ -216,7 +221,8 @@
     .ico-search {
         border:0; padding:0;
         background-color:transparent;
-        margin-bottom:2px;
+        /*margin-bottom:2px;*/
+        margin-top:2px;
     }
 }
 
@@ -229,6 +235,8 @@
     border: 1px solid #ccc;
     .border-radius(3px) !important;
     
+    &.mini    { width:12px; height:12px;   }
+    &.smaller { width:20px; height:20px;   }
     &.small   { width:24px; height:24px;   }
     &.medium  { width:32px; height:32px;   }
     &.large   { width:64px; height:64px;   }
app/assets/stylesheets/less/_page.less
--- app/assets/stylesheets/less/_page.less
+++ app/assets/stylesheets/less/_page.less
@@ -38,7 +38,7 @@
             
             .gnb-menus {
                 float: left;
-                overflow: hidden;
+                /*overflow: hidden;*/
                 margin: 23px 10px 22px 34px;
                 
                 .menu {
@@ -57,45 +57,54 @@
                         a { color: @gnb-link-highlight-color; }
                     }
                 }
+
                 &.right {
-                    float: right;
-                    position:absolute; right:0; top:0;
+                    float: right; position:absolute; 
+                    right:0; top:0;
+                    margin-top:19px;
                     
-                    > li {
-                        float: left;
-                        padding: 0 8px;
-                        height: 24px;
-                        line-height: 24px;
-                        color: @gnb-action-color;
-                        font-size: 11px;
-                    }
-                    .uname {
-                        color: @gnb-action-color;
-                    }
-                    .user-thumb {
-                        vertical-align: top;
-                        margin-right: 5px;
-                    }
-                    .signout {
-                        color: @gnb-action-signout-color;
-                    }
-                    .sp-line {
-                        padding: 0; padding-top:3px;
-                        font-size: 18px;
-                        font-family:Dotum;
-                        color: @gnb-action-separate-border-color;
-                    }
-                    .d-link-wrap { 
-                        padding-top:2px; 
-                        padding-right:1px;
-                        
-                        &.d-link-l { padding-right:6px !important; }
-                        &.d-link-r { padding-left:6px !important; }                        
-                    }
-                    
+                    /** 사이트 검색폼 **/
                     .search-bar {
+                        display:inline-block;                        
                         padding:3px 0 0 5px;
-                    } /*.search-bar */
+                    }
+                   
+                    /** 로그인 하지 않은 경우 메뉴 **/
+                    .lnk-group {
+                        a {
+                            padding-right:5px; margin-right:8px;
+                            border-right:1px solid @gnb-action-separate-border-color;
+                            
+                            &:last-of-type {
+                                padding-right:0; margin-right:0;
+                                border-right:none; 
+                            }
+                        }
+                        margin-right:10px;
+                        
+                        .avatar-wrap {
+                            border:1px solid #868686;
+                            margin-right:5px;
+                            img { vertical-align:top; }
+                        }
+                    }
+                    
+                    /** 로그인한 사용자의 dropdown 메뉴 **/
+                    .usermenu {
+                        margin:0; display:inline-block; vertical-align:middle;
+                        
+                        .dropdown-toggle {
+                            background:transparent;
+                            
+                            .d-label { 
+                                width:70px;
+                                span.text { margin-left:5px; }
+                            }
+                            .d-caret {
+                                padding:5px 9px;
+                            } 
+                        }
+                    }                   
                 } // .right
             }// gnb-menu
         }//gnb-menu-wrap
@@ -2009,7 +2018,7 @@
 }
 
 .notice-wrap {
-    margin-top:20px;
+    margin:20px 0 0 0;
     border:1px solid #eee;
     
     .board-list .board:last-of-type { border-bottom:none; }
@@ -2030,7 +2039,7 @@
         margin-right: 5px;
     }
 }
-/*
+
 .board-header{
     padding: 15px 20px;
     border-top: 1px solid @gray-d4;
@@ -2066,7 +2075,7 @@
         }
     }
 }
-*/
+
 .board-body {
     padding: 20px;
     .author-info {
app/views/board/editPost.scala.html
--- app/views/board/editPost.scala.html
+++ app/views/board/editPost.scala.html
@@ -6,92 +6,81 @@
 
 @main(title, project, utils.MenuType.BOARD) {
 <div class="page">
-  @views.html.prjmenu(project, utils.MenuType.BOARD, "main-menu-only")
+	@prjmenu(project, utils.MenuType.BOARD, "main-menu-only")
 
-  <div class="content-wrap frm-wrap">
+	<form action="@routes.BoardApp.editPost(project.owner, project.name, postId)" method="post" enctype="multipart/form-data" class="nm">
+	<div class="content-wrap frm-wrap">
+		<dl>
+			<dt>
+				<label for="title">@Messages("post.new.title")</label>
+ 			</dt>
+			<dd>
+				@helper.inputText(form("title"), 'class->"text title", 'maxlength -> "250", 'tabindex -> 1)
+			</dd>
+			
+			<dd>
+				@helper.textarea(form("body"), 'markdown -> true, 'class->"text content", 'tabindex -> 2)
+			</dd>
+			
+			@if(isAllowedToNotice){
+			@helper.input(form("notice")){(id, name, value, args) =>
+			<dd class="right-txt">
+				<input type="checkbox" id="notice" name="notice" class="checkbox" @toHtmlArgs(args) @(if(value.equals(Some("true"))) "checked" else "")/><!-- 
+			 --><label for="notice" class="label-public">@Messages("post.notice.label")</label>
+			</dd>
+			}
+			}
+		</dl>
 
-    @helper.form(action=routes.BoardApp.editPost(project.owner, project.name, postId), 'enctype -> "multipart/form-data", 'class->"nm"){
-
-    <dl>
-    	<dt>
-	      <div id="warning" class="n-alert hide">
-	        <div class="n-inner">
-	          <span class="msg">제목과 본문에 빈칸이 있습니다.</span>
-	          <a href="#" class="ico btn-delete"></a>
-	        </div>
-	      </div>
-	      <label for="title">@Messages("post.new.title")</label>
-    	</dt>
-    	<dd>
-    		@helper.inputText(form("title"), 'class->"text title", 'maxlength -> "250", 'tabindex -> 1)
-    	</dd>
-    </dl>
-
-	@helper.textarea(form("body"), 'markdown -> true, 'class->"text content", 'tabindex -> 2)
-
-    @if(isAllowedToNotice) {
-    <div>
-        <label for="notice">@Messages("post.notice")</label>
-            @helper.input(form("notice")) { (id, name, value, args) =>
-                <input type="checkbox" name="@name" id="@id" @toHtmlArgs(args) @(if(value.equals(Some("true"))) "checked" else "") />
-            }
-    </div>
-    }
-
-	@** fileUploader **@
-    @if(UserApp.currentUser() != UserApp.anonymous) {
-
-	<div class="content-footer">
-		<div class="attach-wrap">
-			<div class="avatar-wrap">
-				<img src="@User.findByLoginId(session.get("loginId")).avatarUrl" class="img-rounded" width="32" height="32" alt="avatar">
-			</div>
-			<div id="upload" class="attach-info-wrap" resourceType="@ResourceType.BOARD_POST" resourceId="@postId">
-				<div>
-					<span class="progress-num">0%</span> <span class="sp-line">&nbsp;</span>
-					<strong>total</strong> <span class="total-num">0MB</span>
+		@** fileUploader **@
+	    @if(UserApp.currentUser() != UserApp.anonymous) {
+		<div class="content-footer">
+			<div class="attach-wrap">
+				<div class="avatar-wrap">
+					<img src="@User.findByLoginId(session.get("loginId")).avatarUrl" class="img-rounded" width="32" height="32" alt="avatar">
 				</div>
-				<div class="progress-wrap">
-					<div class="progress n4">
-						<div class="bar orange" style="width: 0%;"></div>
+				<div id="upload" class="attach-info-wrap" resourceType="@ResourceType.BOARD_POST" resourceId="@postId">
+					<div>
+						<span class="progress-num">0%</span> <span class="sp-line">&nbsp;</span>
+						<strong>total</strong> <span class="total-num">0MB</span>
+					</div>
+					<div class="progress-wrap">
+						<div class="progress n4">
+							<div class="bar orange" style="width: 0%;"></div>
+						</div>
 					</div>
 				</div>
-				<!-- <a href="#!/cancel"><i class="ico btn-cancel"></i></a> -->
-			</div>
-
-			<div class="btn-wrap">
-				<div class="fake-file-wrap">
-					<input type="file" class="file" name="filePath" size="1">
-					<div class="ns-btn">
-						<i class="ico ico-plus-blue"></i>@Messages("button.upload")
+	
+				<div class="btn-wrap">
+					<div class="nbtn medium white fake-file-wrap">
+						<i class="ico ico-plus-blue"></i>@Messages("button.upload")<!-- 
+					--> <input type="file" class="file" name="filePath">
 					</div>
 				</div>
 			</div>
+			<script type="text/template" id="tplAttachedFile"><!--
+				--><li class="attached-file" data-name="${fileName}" data-href="${fileHref}" data-mime="${mimeType}" data-size="${fileSize}">
+				<strong>${fileName}(${fileSizeReadable})</strong><!--
+				--><a class="attached-delete"><i class="ico btn-delete"></i></a></li>
+			</script>
+	
+			<div class="attached-files-wrap">
+				<ul class="attached-files"></ul>
+			</div>
+		</div>
+		}
+		@** end of fileUploader **@
+
+		<div class="actions">
+			<button class="nbtn medium orange" tabindex="3">@Messages("button.save")</button><!-- 
+	 	 --><a href="javascript:history.back();" class="nbtn medium last" tabindex="4">@Messages("button.cancel")</a>
+		</div>
+		
 	</div>
-	<script type="text/template" id="tplAttachedFile"><!--
-	--><li class="attached-file" data-name="${fileName}" data-href="${fileHref}" data-mime="${mimeType}" data-size="${fileSize}">
-		<strong>${fileName}(${fileSizeReadable})</strong><!--
-		--><a class="attached-delete"><i class="ico btn-delete"></i></a>
-	</li>
-	</script>
-
-	<div class="attached-files-wrap">
-		<ul class="attached-files"></ul>
-	</div>
-	}
-	@** end of fileUploader **@
-
-  </div>
-
-  <div class="actions">
-      <button class="btn-transparent n-btn orange med">@Messages("button.save")</button>
-      <a href="javascript:history.back();" class="n-btn gray med cancel">@Messages("button.cancel")</a>
-  </div>
-
-  } @** end of form **@
+	</form>
 </div>
 
-@views.html.markdown()
+@markdown()
 
 <script type="text/javascript">
 $(document).ready(function(){
app/views/board/newPost.scala.html
--- app/views/board/newPost.scala.html
+++ app/views/board/newPost.scala.html
@@ -6,92 +6,79 @@
 
 @main(title, project, utils.MenuType.BOARD) {
 <div class="page">
-  @views.html.prjmenu(project, utils.MenuType.BOARD, "main-menu-only")
+	@prjmenu(project, utils.MenuType.BOARD, "main-menu-only")
 
-  <div class="content-wrap frm-wrap">
+	<form action="@routes.BoardApp.newPost(project.owner, project.name)" method="post" enctype="multipart/form-data" class="nm">
+	<div class="content-wrap frm-wrap">
+		<dl>
+			<dt>
+				<label for="title">@Messages("post.new.title")</label>
+ 			</dt>
+			<dd>
+				<input type="text" id="title" name="title" class="text title" maxlength="250" tabindex="1" />
+			</dd>
+			
+			<dd>
+				<textarea id="body" name="body" class="text content" markdown="true" tabindex="2"></textarea>
+			</dd>
+			
+			@if(isAllowedToNotice){
+			<dd class="right-txt">
+				<input type="checkbox" id="notice" name="notice" class="checkbox" /><!-- 
+			 --><label for="notice" class="label-public">@Messages("post.notice.label")</label>
+			</dd>
+			}
+		</dl>
 
-    @helper.form(action=routes.BoardApp.newPost(project.owner, project.name), 'enctype -> "multipart/form-data", 'class->"nm"){
-
-    <dl>
-    	<dt>
-	      <div id="warning" class="n-alert hide">
-	        <div class="n-inner">
-	          <span class="msg">제목과 본문에 빈칸이 있습니다.</span>
-	          <a href="#" class="ico btn-delete"></a>
-	        </div>
-	      </div>
-	      <label for="title">@Messages("post.new.title")</label>
-    	</dt>
-    	<dd>
-    		@helper.inputText(form("title"), 'class->"text title", 'maxlength -> "250", 'tabindex -> 1)
-    	</dd>
-    </dl>
-
-	@helper.textarea(form("body"), 'markdown -> true, 'class->"text content", 'tabindex -> 2)
-
-    @if(isAllowedToNotice) {
-    <div>
-        <label for="notice">@Messages("post.notice")</label>
-        @helper.input(form("notice")) { (id, name, value, args) =>
-            <input type="checkbox" name="@name" id="@id" @toHtmlArgs(args) />
-        }
-    </div>
-    }
-
-      @** fileUploader **@
-    @if(UserApp.currentUser() != UserApp.anonymous) {
-
-	<div class="content-footer">
-		<div class="attach-wrap">
-			<div class="avatar-wrap">
-				<img src="@User.findByLoginId(session.get("loginId")).avatarUrl" class="img-rounded" width="32" height="32" alt="avatar">
-			</div>
-			<div id="upload" class="attach-info-wrap" resourceType="@ResourceType.BOARD_POST">
-				<div>
-					<span class="progress-num">0%</span> <span class="sp-line">&nbsp;</span>
-					<strong>total</strong> <span class="total-num">0MB</span>
+		@** fileUploader **@
+	    @if(UserApp.currentUser() != UserApp.anonymous) {
+		<div class="content-footer">
+			<div class="attach-wrap">
+				<div class="avatar-wrap">
+					<img src="@User.findByLoginId(session.get("loginId")).avatarUrl" class="img-rounded" width="32" height="32" alt="avatar">
 				</div>
-				<div class="progress-wrap">
-					<div class="progress n4">
-						<div class="bar orange" style="width: 0%;"></div>
+				<div id="upload" class="attach-info-wrap" resourceType="@ResourceType.BOARD_POST">
+					<div>
+						<span class="progress-num">0%</span> <span class="sp-line">&nbsp;</span>
+						<strong>total</strong> <span class="total-num">0MB</span>
+					</div>
+					<div class="progress-wrap">
+						<div class="progress n4">
+							<div class="bar orange" style="width: 0%;"></div>
+						</div>
 					</div>
 				</div>
-				<!-- <a href="#!/cancel"><i class="ico btn-cancel"></i></a> -->
-			</div>
-
-			<div class="btn-wrap">
-				<div class="fake-file-wrap">
-					<input type="file" class="file" name="filePath" size="1">
-					<div class="ns-btn">
-						<i class="ico ico-plus-blue"></i>@Messages("button.upload")
+	
+				<div class="btn-wrap">
+					<div class="nbtn medium white fake-file-wrap">
+						<i class="ico ico-plus-blue"></i>@Messages("button.upload")<!-- 
+					--> <input type="file" class="file" name="filePath">
 					</div>
 				</div>
 			</div>
+			<script type="text/template" id="tplAttachedFile"><!--
+				--><li class="attached-file" data-name="${fileName}" data-href="${fileHref}" data-mime="${mimeType}" data-size="${fileSize}">
+				<strong>${fileName}(${fileSizeReadable})</strong><!--
+				--><a class="attached-delete"><i class="ico btn-delete"></i></a></li>
+			</script>
+	
+			<div class="attached-files-wrap">
+				<ul class="attached-files"></ul>
+			</div>
+		</div>
+		}
+		@** end of fileUploader **@
+
+		<div class="actions">
+			<button class="nbtn medium orange" tabindex="3">@Messages("button.save")</button><!-- 
+	 	 --><a href="javascript:history.back();" class="nbtn medium last" tabindex="4">@Messages("button.cancel")</a>
+		</div>
+		
 	</div>
-	<script type="text/template" id="tplAttachedFile"><!--
-	--><li class="attached-file" data-name="${fileName}" data-href="${fileHref}" data-mime="${mimeType}" data-size="${fileSize}">
-		<strong>${fileName}(${fileSizeReadable})</strong><!--
-		--><a class="attached-delete"><i class="ico btn-delete"></i></a>
-	</li>
-	</script>
-
-	<div class="attached-files-wrap">
-		<ul class="attached-files"></ul>
-	</div>
-	}
-	@** end of fileUploader **@
-
-  </div>
-
-  <div class="actions">
-      <button class="btn-transparent n-btn orange med">@Messages("button.save")</button>
-      <a href="javascript:history.back();" class="n-btn gray med cancel">@Messages("button.cancel")</a>
-  </div>
-
-  } @** end of form **@
+	</form>
 </div>
 
-@views.html.markdown()
+@markdown()
 
 <script type="text/javascript">
 $(document).ready(function(){
app/views/board/post.scala.html
--- app/views/board/post.scala.html
+++ app/views/board/post.scala.html
@@ -8,156 +8,140 @@
 @main(post.title, project, utils.MenuType.BOARD){
 
 <div class="page board-view">
-  @prjmenu(project, utils.MenuType.BOARD, "main-menu-only")
+	@prjmenu(project, utils.MenuType.BOARD, "main-menu-only")
   
-  @** Post Info **@
-  <div class="board-header">
-	<div class="board-id div">@post.getNumber</div>
-    <h1 class="title div">@post.title</h1>
-    <div class="date div">@utils.TemplateHelper.agoString(post.ago())</div>
-  </div>
+	@** Post Info **@
+	<div class="board-header">
+		<div class="board-id div">@post.getNumber</div>
+		<h1 class="title div">@post.title</h1>
+		<div class="date div">@utils.TemplateHelper.agoString(post.ago())</div>
+	</div>
   
-  @** Content body **@
-  <div class="board-body">
-    <div class="author-info">
-      <a href="@routes.UserApp.userInfo(post.authorLoginId)" class="avatar-wrap pull-left img-rounded">
-      	<img class="user-picture" src="@User.findByLoginId(post.authorLoginId).avatarUrl" width="32" height="32" alt="@post.authorName">
-      </a>
-      <div class="media-body">
-        <p>
-          <a href="@routes.UserApp.userInfo(post.authorLoginId)"><strong>@post.authorLoginId</strong></a> <!--<span class="name">(Loren Brichter)</span>-->
-        </p>
-        <p class="status">
-          <!--Hit <strong class="num">777</strong> 
-          -->Comment <strong class="num">@post.numOfComments</strong><!-- 
-          Like <i class="ico ico-like-small"></i> <strong class="num">522</strong>-->
-        </p>
-      </div>
-    </div>
-    <div class="content" markdown="true">@post.body</div>
-    <div class="attachments" resourceType="@ResourceType.BOARD_POST" resourceId="@post.id"></div>
-    <!--
-      <ul class="attaches wm">
-        <li class="attach"><i class="ico ico-clip"></i>K23.png (11KB)</li>
-        <li class="attach"><i class="ico ico-clip"></i>K23.png (11KB)</li>
-        <li class="attach"><i class="ico ico-clip"></i>K23.png (11KB)</li>
-      </ul>-->
-  </div>
-  <div class="board-footer board-actrow">
-  @if(isAllowed(UserApp.currentUser(), post.asResource(), Operation.UPDATE)){
-	<a href="@routes.BoardApp.editPostForm(project.owner, project.name, post.id)" class="n-btn orange med">@Messages("button.edit")</a>
-  }
-  @if(isAllowed(UserApp.currentUser(), post.asResource(), Operation.DELETE)){
-   	<a href="#deleteConfirm" data-toggle="modal" class="n-btn light-gray med">@Messages("button.delete")</a>
-  }
-    <a href="@routes.BoardApp.posts(project.owner, project.name)" class="n-btn gray med">@Messages("button.list")</a>
-  </div>
-
-@** Comment **@
-<div class="board-comment-wrap">
-    <div class="comment-header"><strong>Comment</strong> <strong class="num">@post.comments.size()</strong></div>
-    
-    <ul class="comments">
-    @for(comment <-post.comments){
-		<li class="comment">
-			<a href="@routes.UserApp.userInfo(comment.authorLoginId)" class="pull-left img-rounded avatar-wrap">
-				<img class="user-picture" src="@User.findByLoginId(comment.authorLoginId).avatarUrl" width="32" height="32" alt="@comment.authorLoginId">
+	@** Content body **@
+	<div class="board-body">
+		<div class="author-info">
+			<a href="@routes.UserApp.userInfo(post.authorLoginId)" class="avatar-wrap pull-left">
+				<img src="@User.findByLoginId(post.authorLoginId).avatarUrl" width="32" height="32" alt="@post.authorName">
 			</a>
 			<div class="media-body">
-				@if(isAllowed(UserApp.currentUser(), comment.asResource(), Operation.DELETE)){
-				<a class="pull-right close" href="@routes.BoardApp.deleteComment(project.owner, project.name, post.id, comment.id)">&times;</a>
-				}
-				<p class="commenter">
-					<a href="@routes.UserApp.userInfo(comment.authorLoginId)"><strong>@comment.authorLoginId</strong></a>
-					<span class="date"> @utils.TemplateHelper.agoString(comment.ago())</span>
+				<p>
+					<a href="@routes.UserApp.userInfo(post.authorLoginId)"><strong>@post.authorLoginId</strong></a>
 				</p>
-	            <div class="comment-body" markdown="true">@comment.contents</div>
-	            <div class="attachments" resourceType="@ResourceType.NONISSUE_COMMENT" resourceId="@comment.id"></div>
-	        </div>
-      	</li>
-    }
-    </ul>
-    
-@if(isCreatable(User.findByLoginId(session.get("loginId")), project, models.enumeration.ResourceType.BOARD_POST)){
-    <div class="write-comment-box">
-        @helper.form(routes.BoardApp.newComment(project.owner, project.name, post.id), 'class->"nm", 'enctype -> "multipart/form-data"){
-		<div class="write-comment-wrap">
-			<textarea name="contents" id="contents" class="text comment" markdown="true"></textarea>
-			<button class="comment-btn">@Messages("button.comment.new")</button>
+				<p class="status">
+					<!--Hit <strong class="num">777</strong> 
+	          	 -->Comment <strong class="num">@post.numOfComments</strong> 
+				</p>
+			</div>
 		</div>
-        
-		<div class="attach-wrap">
-			<div class="pull-left img-rounded avatar-wrap">
-			@if(UserApp.currentUser() != UserApp.anonymous) {
-				<img src="@User.findByLoginId(session.get("loginId")).avatarUrl" class="img-rounded" width="32" height="32" alt="avatar">
-			} else {
-				<img src="@routes.Assets.at("images/default-avatar-34.png")" class="img-rounded" width="32" height="32" alt="avatar">
-			}
-			</div>
-			
-			@** fileUploader **@
-            @if(UserApp.currentUser() != UserApp.anonymous) {
+		<div class="content" markdown="true">@post.body</div>
+		<div class="attachments" resourceType="@ResourceType.BOARD_POST" resourceId="@post.id">
+		    @**<!--
+		      <ul class="attaches wm">
+		        <li class="attach"><i class="ico ico-clip"></i>K23.png (11KB)</li>
+		      </ul>-->
+			**@
+		</div>
+	</div>
+	<div class="board-footer board-actrow nbtn-group">
+		@if(isAllowed(UserApp.currentUser(), post.asResource(), Operation.DELETE)){
+		<a href="#deleteConfirm" class="nbtn medium black" data-toggle="modal">@Messages("button.delete")</a>
+		}
 
-			<div id="upload" class="attach-info-wrap" resourceType="@ResourceType.NONISSUE_COMMENT">
-				<div>
-					<span class="progress-num">0%</span> <span class="sp-line">&nbsp;</span>
-					<strong>total</strong> <span class="total-num">0Mb</span>
+		@if(isAllowed(UserApp.currentUser(), post.asResource(), Operation.UPDATE)){
+		<a href="@routes.BoardApp.editPostForm(project.owner, project.name, post.id)" class="nbtn medium orange">@Messages("button.edit")</a>
+		}
+
+		<a href="@routes.BoardApp.posts(project.owner, project.name)" class="nbtn medium">@Messages("button.list")</a>
+	</div>
+
+	@** Comment **@
+	<div class="board-comment-wrap">
+		<div class="comment-header"><strong>@Messages("comment")</strong> <strong class="num">@post.comments.size()</strong></div>
+    	<hr class="nm" />
+    	
+    	<ul class="comments">
+    	@for(comment <-post.comments){
+			<li class="comment">
+				<a href="@routes.UserApp.userInfo(comment.authorLoginId)" class="avatar-wrap pull-left">
+					<img src="@User.findByLoginId(comment.authorLoginId).avatarUrl" width="32" height="32" alt="@comment.authorLoginId">
+				</a>
+				<div class="media-body">
+					@if(isAllowed(UserApp.currentUser(), comment.asResource(), Operation.DELETE)){
+						<a href="@routes.BoardApp.deleteComment(project.owner, project.name, post.id, comment.id)" class="pull-right close">&times;</a>
+					}
+					<p class="commenter">
+						<a href="@routes.UserApp.userInfo(comment.authorLoginId)"><strong>@comment.authorLoginId</strong></a>
+						<span class="date"> @utils.TemplateHelper.agoString(comment.ago())</span>
+					</p>
+					<div class="comment-body" markdown="true">@comment.contents</div>
+					<div class="attachments" resourceType="@ResourceType.NONISSUE_COMMENT" resourceId="@comment.id"></div>
 				</div>
-				<div class="progress-wrap">
-					<div class="progress n4">
-						<div class="bar orange" style="width: 0%;"></div>
-					</div>
-				</div>
-				<!-- <a href="#!/cancel"><i class="ico btn-cancel"></i></a> -->
+			</li>
+    	}
+		</ul>
+    
+		@if(isCreatable(User.findByLoginId(session.get("loginId")), project, models.enumeration.ResourceType.BOARD_POST)){
+		<hr class="nm" />
+        @helper.form(routes.BoardApp.newComment(project.owner, project.name, post.id), 'class->"nm", 'enctype -> "multipart/form-data"){
+		<div class="write-comment-box">
+			<div class="write-comment-wrap">
+				<textarea name="contents" id="contents" class="text comment" markdown="true"></textarea><!-- 
+			 --><button class="comment-btn">@Messages("button.comment.new")</button>
 			</div>
+        
+			@** fileUploader **@
+			@if(UserApp.currentUser() != UserApp.anonymous) {
+			<div class="attach-wrap">
+				<div class="avatar-wrap pull-left">
+					<img src="@User.findByLoginId(session.get("loginId")).avatarUrl" width="32" height="32">
+				</div>
 			
-			<div class="btn-wrap">
-				<div class="fake-file-wrap">
-					<input type="file" class="file" name="filePath" size="1">
-					<div class="ns-btn">
-						<i class="ico ico-plus-blue"></i>@Messages("button.upload")
+				<div id="upload" class="attach-info-wrap" resourceType="@ResourceType.NONISSUE_COMMENT">
+					<div>
+						<span class="progress-num">0%</span> <span class="sp-line">&nbsp;</span>
+						<strong>total</strong> <span class="total-num">0Mb</span>
+					</div>
+					<div class="progress-wrap">
+						<div class="progress n4">
+							<div class="bar orange" style="width: 0%;"></div>
+						</div>
 					</div>
 				</div>
+			
+				<div class="btn-wrap">
+					<div class="nbtn medium white fake-file-wrap">
+						<i class="ico ico-plus-blue"></i>@Messages("button.upload")<!-- 
+					--> <input type="file" class="file" name="filePath">
+					</div>
+				</div>
+			</div>
+			<div class="attached-files-wrap">
+				<ul class="attached-files"></ul>
 			</div>
 			}
 			@** end of fileUploader **@
-        
+			
 		</div>
 		} @** end of comment form **@
-		<div class="attached-files-wrap">
-           <ul class="attached-files"></ul>
+		
+		@** end of write-comment-box **@
+		
+		} else {
+		<div class="write-comment-box">
+			<div class="write-comment-wrap">
+				<textarea class="text comment disabled" disabled="disabled">@Messages("auth.unauthorized.comment")</textarea>
+				<button class="comment-btn disabled">@Messages("button.comment.new")</button>
+			</div>
 		</div>
-  </div>
-  <script type="text/template" id="tplAttachedFile"><!--
-	--><li class="attached-file" data-name="${fileName}" data-href="${fileHref}" data-mime="${mimeType}" data-size="${fileSize}">
-		<strong>${fileName}(${fileSizeReadable})</strong><!--
-		--><a class="attached-delete"><i class="ico btn-delete"></i></a>
-	</li>
-  </script>
-@** end of write-comment-box **@
-} else {
-	<div class="write-comment-box">
-		<div class="write-comment-wrap">
-			<textarea class="text comment disabled" disabled="disabled">@Messages("auth.unauthorized.comment")</textarea>
-			<button class="comment-btn disabled">@Messages("button.comment.new")</button>
-		</div>
+		}
 	</div>
-}
 </div>
 
-@**
-<div class="board-footer">
-	@isAllowed(UserApp.currentUser(), post.asResource(), Operation.UPDATE)){
-	<a href="@routes.BoardApp.editPostForm(project.owner, project.name, post.id)" class="n-btn orange med">@Messages("button.edit")</a>
-	}
-
-	@isAllowed(UserApp.currentUser(), post.asResource(), Operation.DELETE)){
-   	<a href="#deleteConfirm" data-toggle="modal" class="n-btn light-gray med">@Messages("button.delete")</a>
-	}
-
-    <a href="@routes.BoardApp.posts(project.owner, project.name)" class="n-btn gray med">@Messages("button.list")</a>
-</div>
-**@
+<script type="text/template" id="tplAttachedFile"><!--
+	--><li class="attached-file" data-name="${fileName}" data-href="${fileHref}" data-mime="${mimeType}" data-size="${fileSize}">
+	<strong>${fileName}(${fileSizeReadable})</strong><!--
+	--><a class="attached-delete"><i class="ico btn-delete"></i></a></li>
+</script>
 
 @** Confirm to delete post **@
 <div id="deleteConfirm" class="modal hide fade">
@@ -169,8 +153,7 @@
 		<p>@Messages("post.delete.confirm")</p>
 	</div>
 	<div class="modal-footer">
-		<a class="btn btn-danger med"
-			href="@routes.BoardApp.deletePost(project.owner, project.name, post.id)">@Messages("button.yes")</a>
+		<a class="btn btn-danger med" href="@routes.BoardApp.deletePost(project.owner, project.name, post.id)">@Messages("button.yes")</a>
 		<a href="#" class="btn med" data-dismiss="modal">@Messages("button.no")</a>
 	</div>
 </div>
app/views/board/postList.scala.html
--- app/views/board/postList.scala.html
+++ app/views/board/postList.scala.html
@@ -8,9 +8,9 @@
 
 @makeFilterLink(fieldName:String, orderBy:String, orderDir:String, fieldText:String) = {
 	@if(orderBy.equals(fieldName)) {
-		<a href="@urlToList&orderBy=@fieldName&orderDir=@if(orderDir.equals("desc")){asc}else{desc}" class="filter active"><i class="ico btn-gray-arrow @if(orderDir.equals("desc")){ down }"></i>@fieldText</a>
+		<a href="@urlToList?orderBy=@fieldName&orderDir=@if(orderDir.equals("desc")){asc}else{desc}" class="filter active"><i class="ico btn-gray-arrow @if(orderDir.equals("desc")){ down }"></i>@fieldText</a>
 	} else {
-	    <a href="@urlToList&orderBy=@fieldName&orderDir=asc" class="filter"><i class="ico btn-gray-arrow"></i>@fieldText</a>
+	    <a href="@urlToList?orderBy=@fieldName&orderDir=asc" class="filter"><i class="ico btn-gray-arrow"></i>@fieldText</a>
 	}
 }
 
@@ -30,6 +30,24 @@
 	    </div>
 	  </div>
 	</div>
+
+	@if(page.getTotalRowCount == 0){
+
+	<div class="error-wrap">
+		<i class="ico ico-err1"></i>
+		<p>@Messages("post.is.empty")</p>
+	</div>
+
+	} else {
+
+	@if(page.getTotalRowCount > 1){
+	<div class="filter-wrap board">
+	    <div class="filters">
+			@makeFilterLink("createdDate", param.orderBy, param.orderDir, Messages("order.date"))
+			@makeFilterLink("numOfComments", param.orderBy, param.orderDir, Messages("order.comments"))
+	    </div>
+	</div>
+	}
 
   	@if(notices != null && notices.size > 0) {
     <div class="notice-wrap bubble-wrap gray">
@@ -67,24 +85,6 @@
 	</div>
 	}
 
-	@if(page.getTotalRowCount == 0){
-
-	<div class="error-wrap">
-		<i class="ico ico-err1"></i>
-		<p>@Messages("post.is.empty")</p>
-	</div>
-
-	} else {
-
-	@if(page.getTotalRowCount > 1){
-	<div class="filter-wrap board">
-	    <div id="order" class="filters">
-			@makeFilterLink("createdDate", param.orderBy, param.orderDir, Messages("order.date"))
-			@makeFilterLink("numOfComments", param.orderBy, param.orderDir, Messages("order.comments"))
-	    </div>
-	</div>
-	}
-
 	<ul class="board-list unstyled">
 	@for(post <- page.getList()){
 		<li class="board">
@@ -119,7 +119,7 @@
   }
 
 	<div class="write-btn-wrap">
-		<a href="@routes.BoardApp.newPostForm(project.owner, project.name)" class="n-btn orange med">@Messages("post.write")</a>
+		<a href="@routes.BoardApp.newPostForm(project.owner, project.name)" class="nbtn orange medium">@Messages("post.write")</a>
 	</div>
 
 	<div id="pagination">
 
app/views/board/postVaildate.scala.html (deleted)
--- app/views/board/postVaildate.scala.html
@@ -1,28 +0,0 @@
-<div class="modal hide fade" id="chk_vaildate">
-  <div class="modal-header">
-    <button type="button" class="close" data-dismiss="modal">×</button>
-    <h3>확인</h3>
-  </div>
-  <div class="modal-body alert alert-error">
-    <p>본문과 제목에 빈칸이 있습니다.</p>
-    <p>본문과 제목을 입력해 주세요</p>
-  </div>
-  <div class="modal-footer">
-    <a href="#" class="btn" data-dismiss="modal">확인</a>
-  </div>
-</div>
-<script>
-$(document).ready(function(){
-    $("form").submit(function(){
-        if($("input#title").val() == "" || $("textarea#contents").val() == "")
-        {
-            $('#chk_vaildate').modal()
-            return false;
-        }
-        else
-        {
-        	return true;
-        }
-    });
-});
-</script>(No newline at end of file)
app/views/milestone/list.scala.html
--- app/views/milestone/list.scala.html
+++ app/views/milestone/list.scala.html
@@ -42,9 +42,6 @@
     
     <div class="tab-wrap">
         <div class="pull-right btns">
-        	@**<!-- 
-            <a href="@routes.MilestoneApp.manageMilestones(projectInst.owner, projectInst.name)" class="nbtn medium">@Messages("milestone.menu.manage")</a>
-             -->**@
             <a href="@routes.MilestoneApp.newMilestoneForm(projectInst.owner, projectInst.name)" class="nbtn medium orange">@Messages("milestone.menu.new")</a>
         </div>
         
app/views/navbar.scala.html
--- app/views/navbar.scala.html
+++ app/views/navbar.scala.html
@@ -9,7 +9,7 @@
 <header class="gnb-outer">
     <div class="gnb-inner">
         <div class="gnb-menu-wrap">
-            <a href="@routes.Application.index()" class="logo"><span>HIVE</span></a>
+            <a href="@routes.Application.index()" class="logo"><span>@Messages("hive.name")</span></a>
             <ul class="gnb-menus unstyled">
                 <li class="menu">
                     <a href="@routes.ProjectApp.newProjectForm()" class="@isActiveMenu(MenuType.NEW_PROJECT)">@Messages("title.newProject")</a>
@@ -21,41 +21,49 @@
                     <a href="@routes.HelpApp.help()" class="@isActiveMenu(MenuType.HELP)">@Messages("title.help")</a>
                 </li>
             </ul>
-            <ul class="gnb-menus right unstyled">
-            	@if(session.contains("loginId")){
-                <li class="d-link-wrap d-link-l">
-                	<a href="@routes.UserApp.userInfo(session.get("loginId"))" class="d-link signin">
-                		<i><img src="@User.findByLoginId(session.get("loginId")).avatarUrl" width="22" height="22"></i>
-                		@session.get("loginId")
-                	</a>
-                </li>
-                <li class="sp-line">|</li>
-                <li class="d-link-wrap d-link-r">
-                	<a href="@routes.UserApp.logout()" class="d-link signup">@Messages("title.logout")</a>
-                </li>
-            	} else {
-                <li class="d-link-wrap d-link-l">
-                	<a href="@routes.UserApp.loginForm()" class="d-link signin">
-                		<i><img src="@routes.Assets.at("images/default-avatar-34.png")" width="22" height="22"></i>
+
+			<div class="gnb-menus right">
+				@if(session.contains("loginId")){
+                <div class="usermenu btn-group">
+					<button class="btn dropdown-toggle large" data-toggle="dropdown">
+						<div class="d-label">
+							<span class="avatar-wrap smaller">
+								<img src="@User.findByLoginId(session.get("loginId")).avatarUrl" width="20" height="20">
+							</span>
+							<span class="text">@session.get("loginId")</span>
+						</div>
+						<span class="d-caret"><span class="caret"></span></span>
+					</button>
+					<ul class="dropdown-menu">
+						<li><a href="@routes.UserApp.userInfo(session.get("loginId"))">@Messages("userinfo.profile")</a></li>
+						<li><a href="@routes.UserApp.editUserInfoForm()">@Messages("userinfo.accountSetting")</a></li>
+						<li class="divider"></li>
+						<li><a href="@routes.UserApp.logout()" class="d-link signup">@Messages("title.logout")</a></li>
+					</ul>
+				</div>
+				} else {
+				<div class="usermenu lnk-group">
+                	<a href="@routes.UserApp.loginForm()">
+                		<span class="avatar-wrap smaller">
+                			<img src="@routes.Assets.at("images/default-avatar-34.png")" width="20" height="20">
+                		</span>
                 		@Messages("title.login")
-                	</a>
-                </li>
-                <li class="sp-line">|</li>
-                <li class="d-link-wrap d-link-r">
-                	<a href="@routes.UserApp.signupForm()" class="d-link signup">@Messages("title.signup")</a>
-                </li>
-            	}
-            	<li class="search-bar">
-                	<form action="@routes.ProjectApp.projects()" class="form-searchbar">
+                	</a><!-- 
+                 --><a href="@routes.UserApp.signupForm()">@Messages("title.signup")</a>
+				</div>
+				}
+			
+				<div class="search-bar">
+	               	<form action="@routes.ProjectApp.projects()" class="form-searchbar">
 						<input type="text" class="text" name="filter" autocomplete="off" accesskey="S"><!-- 
-			 		 --><button type="submit" class="ico ico-search"></button>
+					 --><button type="submit" class="ico ico-search"></button>
 					</form>
-                </li>
-            </ul>
+				</div>
+			</div>
         </div>
     </div>
     
-    
+	@** for Site Administrator **@
     @if(session.contains("userId") && session.get("userId").equals("1")){
     <div class="side-menu-wrap">
         <ul class="side-menus unstyled bg">
@@ -64,4 +72,5 @@
         </ul>
     </div>
     }
+    @** // **@
 </header>
(No newline at end of file)
conf/messages.en
--- conf/messages.en
+++ conf/messages.en
@@ -208,6 +208,7 @@
 post.new.filePath = File Path
 post.author = Author
 post.notice = Notice
+post.notice.label = Set this post to notice
 post.age = Age
 post.menu.search = Search
 post.delete.confirm = If this is deleted, then it cannot be recovered. Is it okay and go through?
@@ -220,6 +221,8 @@
 post.createdDate = Created Date
 post.attachment = Attachment
 post.numOfComments = Comment Count
+post.error.emptyTitle = Title is required
+post.error.emptyBody = Post with empty body cannot be created
 
 #Project
 project.myproject = MY PROJECTS
@@ -427,6 +430,8 @@
 auth.unauthorized.comment = You need authorization to comment
 
 #userinfo
+userinfo.profile = My Profile
+userinfo.accountSetting = Account Setting
 userinfo.myProjects = My Projects
 userinfo.starredProjects = Starred
 
conf/messages.ko
--- conf/messages.ko
+++ conf/messages.ko
@@ -211,7 +211,8 @@
 post.new.contents = 내용
 post.new.filePath = 파일 경로
 post.author = 글쓴이
-post.notice = 공지
+post.notice = 공지사항
+post.notice.label = 이 글을 공지사항으로 설정합니다
 post.age = 나이
 post.menu.search = 검색
 post.delete.confirm = 해당 게시물이 삭제되면 영원히 복구할 수 없습니다. 그래도 삭제하시겠습니까?
@@ -224,6 +225,8 @@
 post.createdDate = 작성일
 post.attachment = 첨부파일
 post.numOfComments = 댓글개수
+post.error.emptyTitle = 글 제목을 입력해주세요
+post.error.emptyBody = 글 내용을 입력해주세요
 
 #Project
 project.myproject = 내 프로젝트
@@ -433,6 +436,8 @@
 auth.unauthorized.comment = 로그인 후 댓글 입력이 가능합니다.
 
 #userinfo
+userinfo.profile = 프로필
+userinfo.accountSetting = 설정
 userinfo.myProjects = 내 프로젝트
 userinfo.starredProjects = 관심 프로젝트
 
public/images/bg-default-project.jpg (Binary)
--- public/images/bg-default-project.jpg
+++ public/images/bg-default-project.jpg
Binary file is not shown
public/javascripts/service/hive.board.List.js
--- public/javascripts/service/hive.board.List.js
+++ public/javascripts/service/hive.board.List.js
@@ -35,7 +35,6 @@
 			htElement.welInputOrderDir = htElement.welForm.find("input[name=orderDir]");
 			htElement.welInputPageNum = htElement.welForm.find("input[name=pageNum]");
 
-			htElement.welFilter = $(htOptions.sQueryFilter || "#order a");
 			htElement.welPages = $(htOptions.sQueryPages || "#pagination a");
 			htElement.welPagination = $(htOptions.elPagination || '#pagination');
 		}
@@ -44,22 +43,7 @@
 		 * attach event handlers
 		 */
         function _attachEvent() {
-            htElement.welFilter.click(_onClickFilter);
             htElement.welPages.click(_onClickPage);
-        }
-
-        /**
-         * onClick filter
-         */
-        function _onClickFilter(){
-            var orderBy = $(this).attr("data-orderBy");
-            var orderDir = $(this).attr("data-orderDir");
-
-            htElement.welInputOrderBy.val(orderBy);
-            htElement.welInputOrderDir.val(orderDir);
-
-            htElement.welForm.submit();
-            return false;
         }
 
         /**
public/javascripts/service/hive.board.Write.js
--- public/javascripts/service/hive.board.Write.js
+++ public/javascripts/service/hive.board.Write.js
@@ -47,9 +47,7 @@
 			// Validate
 			htElement.welForm = $("form");
 			htElement.welInputTitle = $("input#title");
-			htElement.welInputBody = $("textarea#contents");
-			htElement.welWarning = $("#warning");
-			htElement.welWarningBtn = htElement.welWarning.find("button"); 			
+			htElement.welInputBody = $("textarea#body");
 		}
 		
 		/**
@@ -63,11 +61,13 @@
 		 * Validate form on submit
 		 */
 		function _onSubmitForm(){
-			if(htElement.welInputTitle.val() == "" || htElement.welInputBody.val() == ""){
-				htElement.welWarningBtn.click(function(){
-					htElement.welWarning.hide();
-				});
-				htElement.welWarning.show();
+			if(htElement.welInputTitle.val() == ""){
+				$hive.showAlert(Messages("post.error.emptyTitle"));
+				return false;
+			}
+
+			if(htElement.welInputBody.val() == ""){
+				$hive.showAlert(Messages("post.error.emptyBody"));
 				return false;
 			}
 			
Add a comment
List