[Notice] Announcing the End of Demo Server [Read me]
Changsung Kim 2014-04-09
Merge remote-tracking branch 'insanehong/issue-1148' into feature/organization-on-master
@74e953e40da4bf7deb570edfc04c3b3b5b5e6b22
app/assets/stylesheets/less/_yobiUI.less
--- app/assets/stylesheets/less/_yobiUI.less
+++ app/assets/stylesheets/less/_yobiUI.less
@@ -463,6 +463,65 @@
     }
 }
 
+.tab-box {
+    border:1px solid #ececec;
+    border-top:none;
+    .border-radius(0 0 4px 4px);
+}
+
+.tab-box-content {
+    display:none;
+
+    &.active {
+        display:block;
+    }
+}
+
+.tab-searchbox {
+    padding:5px 15px;
+}
+
+.subtab-wrap {
+    padding:5px 15px;
+}
+
+.nav-subtab {
+    li {
+        display: inline-block;
+        margin-left:10px;
+        
+        &:first-child {
+            margin-left:0;
+        }
+
+        a {
+            display: block;
+            padding:3px; 
+
+            &:hover {
+                text-decoration: none;
+                border-bottom:2px solid @primary;
+            }
+        }
+
+        &.active {
+            a {
+                border-bottom:2px solid @primary;
+                font-weight: bold;
+            }
+        }
+    }
+}
+
+.my-project-item {
+    li {
+        padding:5px 15px;
+        border-top : 1px solid #ececec;
+        font-size: 14px;
+    }
+}
+
+
 /** alert **/
 .yobiDialog {
     .border-radius(none);
app/models/Organization.java
--- app/models/Organization.java
+++ app/models/Organization.java
@@ -108,6 +108,18 @@
     }
 
     /**
+     * Find organizations which contains {@code userLoginId} as member.
+     *
+     * @param userLoginId
+     * @return
+     */
+    public static List<Organization> findOrganizationsByUserLoginId(String userLoginId) {
+        return find.where().eq("users.user.loginId", userLoginId)
+                .orderBy("created DESC")
+                .findList();
+    }
+
+    /**
      * As resource.
      *
      * @return the resource
app/views/index/index.scala.html
--- app/views/index/index.scala.html
+++ app/views/index/index.scala.html
@@ -47,26 +47,108 @@
             </ul>
             <div class="page on-fold-intro">
                 <div class="row-fluid content-container">
-                    <div class="span9 main-stream">
+                    <div class="span8 main-stream">
                         <ul class="activity-streams notification-wrap unstyled">
                             @partial_notifications(0, 20)
                         </ul>
         	        </div>
-
-        	       <div class="span3">
-                        <div class="projects-wrap">
-                            @myProjectList(currentUser)
-                        </div>
+                    <div class="span4">
+                        <ul class="nav nav-tabs nm">
+                            <li class="active">
+                                <a href="#myPorjectList" data-toggle="tab">
+                                    @Messages("title.project")
+                                </a>
+                            </li>
+                            <li>
+                                <a href="#myOrganizationList" data-toggle="tab">
+                                    @Messages("title.organization")
+                                </a>
+                            </li>
+                        </ul>
+                        <div class="tab-content tab-box">
+                            <div class="tab-searchbox">
+                                <div class="search-bar">
+                                    <input name="mylist-filter" id="mylist-filter" class="textbox full" type="text" value="">
+                                    <button type="button" class="search-btn"><i class="yobicon-search"></i></button>
+                                </div>
+                            </div>
+                            <div class="tab-content">
+                                <div class="tab-pane myproject-list-wrap active" id="myPorjectList">
+                                    <div class="subtab-wrap">
+                                        <ul class="nav-subtab unstyled">
+                                            <li class="active">
+                                                <a href="#recentlyVisited" data-toggle="tab">
+                                                    @Messages("title.recently.visited")
+                                                </a>
+                                            </li>
+                                            <li>
+                                                <a href="#createdByMe" data-toggle="tab">
+                                                    @Messages("title.createdByMe")
+                                                </a>
+                                            </li>
+                                            <li>
+                                                <a href="#watching" data-toggle="tab">
+                                                    @Messages("title.watching")
+                                                </a>
+                                            </li>
+                                            <li>
+                                                <a href="#joinmember" data-toggle="tab">
+                                                    @Messages("title.joinmember")
+                                                </a>
+                                            </li>
+                                        </ul>    
+                                    </div>
+                                    <div class="tab-content">
+                                        @myProjectList(currentUser)
+                                    </div>
+                                </div>
+                                <div class="tab-pane myorganization-list-wrap" id="myOrganizationList">
+                                    @myOrganizationList(currentUser)
+                                </div>
+                            </div>
+                        </div>     
         	       </div>
-
                 </div>
-
             </div>
         </div>
     </div>
     }
     <script type="text/javascript">
         $(document).ready(function(){
+            var oSearchTimer;
+
+            $('#mylist-filter')
+                .on('keyup.myList-search', function() {
+                    oSearchTimer = setTimeout(_searchWithFileter, 150, $(this).val(), $('.my-list-item'));
+                })
+                .on('keydown.myList-search-stop',function() {
+                    clearTimeout(oSearchTimer);
+                });
+
+            function _searchWithFileter(sFilter, oItems) {
+                if(_isEmptyString(sFilter)) {
+                    oItems.show();
+                    return ;
+                }
+
+                oItems.each(function(i, oItem) {
+                    if( _containsFilterString(sFilter, oItem)) {
+                        $(oItem).show();
+                    } else {
+                        $(oItem).hide();
+                    }
+                });
+            }
+
+            function _containsFilterString(sFilter, oItem) {
+                var sTarget= $(oItem).data('value');
+                return (sTarget.indexOf(sFilter) !== -1);
+            }
+
+            function _isEmptyString(sValue) {
+                return !($.trim(sValue));
+            }
+
             $("#toggleIntro").click(function(){
                 $(".site-guide-outer").toggleClass("hide");
                 localStorage.setItem("yobi-intro", !$(".site-guide-outer").hasClass("hide"));
 
app/views/index/myOrganizationList.scala.html (added)
+++ app/views/index/myOrganizationList.scala.html
@@ -0,0 +1,14 @@
+@(currentUser:models.User)
+@import utils.TemplateHelper._
+
+<ul class="unstyled my-project-item">
+@defining(Organization.findOrganizationsByUserLoginId(UserApp.currentUser.loginId)) { organizations =>
+    @for(organization <- organizations){
+        <li class="my-list-item" data-value="@organization.name">
+            <a href="@routes.OrganizationApp.organization(organization.name)">
+                <span class="bold">@organization.name</span>
+            </a>
+        </li>
+    }
+}
+</ul>
app/views/index/myProjectList.scala.html
--- app/views/index/myProjectList.scala.html
+++ app/views/index/myProjectList.scala.html
@@ -2,49 +2,35 @@
 @import utils.TemplateHelper._
 
 @displayProjects(title:String, projects:List[Project]) = {
-
-    <div class="my-projects">
-        <div class="title">@title (@projects.size())</div>
-        <ul class="unstyled">
-        @for(project <- projects){
-            <li class="my-project">
-                <div class="my-project-header">
-                    <div class="name-wrap">
-                        @if(project.owner != currentUser.loginId) {
-                        <a href="@routes.UserApp.userInfo(project.owner)">@project.owner</a> /
-                        }
-                        <a href="@routes.ProjectApp.project(project.owner, project.name)" class="project-name">
-                            <strong>@project.name @if(!project.isPublic){ <i class="yobicon-lock yobicon-small"></i> }</strong>
-                        </a>
-                    </div>
-                </div>
-            </li>
+<ul class="tab-pane unstyled my-project-item" id="@title">
+@for(project <- projects){
+    <li class="my-list-item" data-value="@if(project.owner != currentUser.loginId) {@project.owner / }@project.name">
+        @if(project.owner != currentUser.loginId) {
+        <a href="@routes.UserApp.userInfo(project.owner)">@project.owner</a> /
         }
-        </ul>
-    </div>
+        <a href="@routes.ProjectApp.project(project.owner, project.name)" class="project-name">
+            <strong>@project.name @if(!project.isPublic){ <i class="yobicon-lock yobicon-small"></i> }</strong>
+        </a>
+    </li>
+}
+</ul>
 }
 @defining(currentUser.getVisitedProjects(10)){ visitedProjects =>
-    <div class="my-projects">
-        <div class="title">@Messages("project.recently.visited") (@visitedProjects.size())</div>
-        <ul class="unstyled">
-        @for(pv <- visitedProjects){
-            <li class="my-project">
-                <div class="my-project-header">
-                    <div class="name-wrap">
-                        @if(pv.project.owner != currentUser.loginId) {
-                        <a href="@routes.UserApp.userInfo(pv.project.owner)">@pv.project.owner</a> /
-                        }
-                        <a href="@routes.ProjectApp.project(pv.project.owner, pv.project.name)" class="project-name">
-                            <strong>@pv.project.name @if(!pv.project.isPublic){ <i class="yobicon-lock yobicon-small"></i> }</strong>
-                        </a>
-                    </div>
-                </div>
-            </li>
+<ul class="tab-pane unstyled my-project-item active" id="recentlyVisited">
+@for(pv <- visitedProjects){
+    <li class="my-list-item" data-value="@if(pv.project.owner != currentUser.loginId) {@pv.project.owner / }@pv.project.name">
+        @if(pv.project.owner != currentUser.loginId) {
+        <a href="@routes.UserApp.userInfo(pv.project.owner)">@pv.project.owner</a> /
         }
-        </ul>
-    </div>
+        <a href="@routes.ProjectApp.project(pv.project.owner, pv.project.name)" class="project-name">
+            <strong>@pv.project.name @if(!pv.project.isPublic){ <i class="yobicon-lock yobicon-small"></i> }</strong>
+        </a>
+    </li>
 }
+</ul>    
+}
+
 @orderString = @{"createdDate DESC"}
-@displayProjects(Messages("project.default.group.watching"), currentUser.getWatchingProjects(orderString))
-@displayProjects(Messages("project.createdByMe"), Project.findProjectsCreatedByUser(currentUser.loginId, orderString))
-@displayProjects(Messages("project.default.group.member"), Project.findProjectsJustMemberAndNotOwner(currentUser, orderString))
+@displayProjects("watching", currentUser.getWatchingProjects(orderString))
+@displayProjects("createdByMe", Project.findProjectsCreatedByUser(currentUser.loginId, orderString))
+@displayProjects("joinmember", Project.findProjectsJustMemberAndNotOwner(currentUser, orderString))
conf/initial-data.yml
--- conf/initial-data.yml
+++ conf/initial-data.yml
@@ -23,18 +23,6 @@
         id:             2
         name:           member
         active:         true
-    - !!models.Role
-        id:             3
-        name:           sitemanager
-        active:         true
-    - !!models.Role
-        id:             4
-        name:           anonymous
-        active:         true
-    - !!models.Role
-        id:             5
-        name:           guest
-        active:         true
 
 # Labels
 labels:
conf/messages
--- conf/messages
+++ conf/messages
@@ -355,7 +355,7 @@
 organization.member.atLeastOneAdmin = A group have to have at least one admin
 organization.member.isNotAMember = The user is not a group member
 organization.member.needManagerRole = To delete member from group, you need group manager role
-organization.setting = Organization Setting
+organization.setting = Group Setting
 organization.settingFrom = Setting
 post.author = Author
 post.comment.empty = you have to write contents.
@@ -634,6 +634,8 @@
 title.codeManagement = Code Management
 title.codeReview = Code Review
 title.commitHistory = Commit History
+title.contentSearchResult = Content Search Result
+title.createdByMe = Create
 title.editIssue = Edit Issue
 title.editMilestone = Edit Milestone
 title.editPullRequest = Edit Pull Request
@@ -644,6 +646,7 @@
 title.issueDetail = Issue
 title.issueList = Issue List
 title.issueTracker = Issue Tracker
+title.joinmember = Member
 title.keymap = Keyboard shortcuts
 title.login = Log in
 title.loginFor = Log in for <span class="highlight">{0}</span>
@@ -661,12 +664,14 @@
 title.post.notExistingPage = Page not found
 title.privateProject = Private Repositories
 title.projectDashboard = Project Dashboard
+title.project = Project
 title.projectDelete = Delete Project
 title.projectHome = Project Home
 title.projectList = Project List
 title.projectMembers = Member List
 title.projectSetting = Project Settings
 title.projectTransfer = Project Transfer
+title.recently.visited =  Recently visited
 title.rememberMe = Remember Me
 title.resetPassword = Reset Password
 title.resetPasswordFor = Reset Password for <span class="highlight">{0}</span>
@@ -677,6 +682,7 @@
 title.siteSetting = Site Setting
 title.text = Title
 title.unlimitedProjects = Unlimited Project Creation
+title.watching = Watching
 title.workTeam = Team Play
 title.yobi.feedback = Feedback
 title.zenmode = zen mode
conf/messages.ko
--- conf/messages.ko
+++ conf/messages.ko
@@ -635,6 +635,8 @@
 title.codeManagement = 코드 관리
 title.codeReview = 코드 리뷰
 title.commitHistory = 커밋 히스토리
+title.contentSearchResult = 컨텐츠 검색 결과
+title.createdByMe = 내가 만든
 title.editIssue = 이슈 수정
 title.editMilestone = 마일스톤 수정
 title.editPullRequest = 코드 보내기 수정
@@ -645,6 +647,7 @@
 title.issueDetail = 이슈 상세보기
 title.issueList = 이슈 목록
 title.issueTracker = 이슈 트래커
+title.joinmember = 멤버로 참여중인
 title.keymap = 단축키 안내
 title.login = 로그인
 title.loginFor = <span class="highlight">{0}</span> 로그인
@@ -660,6 +663,7 @@
 title.organizationHome = 홈
 title.organization = 그룹
 title.post.notExistingPage = 페이지를 찾지 못했습니다.
+title.project = 프로젝트
 title.privateProject = 비공개 프로젝트
 title.projectDashboard = 프로젝트 대시보드
 title.projectDelete = 프로젝트 삭제
@@ -668,6 +672,7 @@
 title.projectMembers = 프로젝트 멤버
 title.projectSetting = 프로젝트 설정
 title.projectTransfer = 프로젝트 이관
+title.recently.visited =  최근 방문
 title.rememberMe = 로그인 유지하기
 title.resetPassword = 비밀번호 재설정
 title.resetPasswordFor = <span class="highlight">{0}</span> 비밀번호 재설정
@@ -678,6 +683,7 @@
 title.siteSetting = 사이트 설정
 title.text = 제목
 title.unlimitedProjects = 제한 없는 프로젝트 생성
+title.watching = 지켜보는
 title.workTeam = 팀 구성
 title.yobi.feedback = 개발팀에게 문의하기
 title.zenmode = 집중 모드
Add a comment
List