doortts doortts 2017-07-11
feature: Show group list of site
@21eb565124809661380ea123b558cc8b954f37b2
app/assets/stylesheets/less/_override.less
--- app/assets/stylesheets/less/_override.less
+++ app/assets/stylesheets/less/_override.less
@@ -376,3 +376,15 @@
         -webkit-box-shadow: 0 0 0 100px #fcfcfc inset;
     }
 }
+
+.title_area {
+    .nav {
+        margin-top: 10px;
+    }
+    ul {
+        li {
+            font-size: 16px;
+            font-weight: normal;
+        }
+    }
+}
app/assets/stylesheets/less/_page.less
--- app/assets/stylesheets/less/_page.less
+++ app/assets/stylesheets/less/_page.less
@@ -591,13 +591,9 @@
 }
 
 .site-breadcrumb-outer {
-    height: 59px;
-    border-bottom:1px solid #ddd;
-
     .site-breadcrumb-inner {
         width: 1170px;
         margin:0 auto;
-        height: 59px;
 
         h3 {
             padding:15px 0 14px;
@@ -1681,7 +1677,6 @@
                 width: 50px;
                 height: 50px;
                 margin-right: 10px;
-                border: 1px solid #DDD9D9;
                 border-radius: 3px !important;
                 position: relative;
                 img {
@@ -1694,6 +1689,7 @@
                 font-size: 20px;
                 font-weight: bold;
                 margin-bottom: 5px;
+                margin-left: 10px;
 
                 .yobicon-lock { color:#7F8C8D;}
                 .owner-name-small{ color:#999; font-size: 19px; }
app/controllers/OrganizationApp.java
--- app/controllers/OrganizationApp.java
+++ app/controllers/OrganizationApp.java
@@ -1,25 +1,12 @@
 /**
- * Yobi, Project Hosting SW
+ * Yona, Project Hosting SW
  *
- * Copyright 2013 NAVER Corp.
- * http://yobi.io
- *
- * @author Keesun Baik
- *
- * 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 2017 the original author or authors.
  */
 package controllers;
 
+import com.avaje.ebean.ExpressionList;
+import com.avaje.ebean.Page;
 import controllers.annotation.AnonymousCheck;
 import models.*;
 import models.enumeration.Operation;
@@ -27,6 +14,7 @@
 import models.enumeration.RoleType;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.commons.collections.CollectionUtils;
 import play.data.Form;
 import play.data.validation.Validation;
 import play.data.validation.ValidationError;
@@ -457,4 +445,17 @@
 
         return new ValidationResult(okWithLocation(routes.OrganizationApp.organization(organization.name).url()), false);
     }
+
+    public static Result orgList(String query, int pageNum){
+        if(Application.HIDE_PROJECT_LISTING){
+            return forbidden(ErrorViews.Forbidden.render("error.auth.unauthorized.waringMessage"));
+        }
+
+        if (pageNum < 1) {
+            return notFound(ErrorViews.NotFound.render("error.notfound"));
+        }
+        Page<Organization> orgs = Organization.findByNameLike(query).getPage(pageNum);
+
+        return ok(views.html.organization.list.render("title.projectList", orgs, query));
+    }
 }
app/models/Organization.java
--- app/models/Organization.java
+++ app/models/Organization.java
@@ -20,6 +20,8 @@
  */
 package models;
 
+import com.avaje.ebean.Page;
+import com.avaje.ebean.PagingList;
 import controllers.Application;
 import models.enumeration.RequestState;
 import models.enumeration.ResourceType;
@@ -76,6 +78,11 @@
         return find.where().ieq("name", name).findUnique();
     }
 
+    public static PagingList<Organization> findByNameLike(String name) {
+        return find.where().ilike("name", "%" + name + "%")
+                .findPagingList(30);
+    }
+
     public static boolean isNameExist(String name) {
         int findRowCount = find.where().ieq("name", name).findRowCount();
         return (findRowCount != 0);
app/utils/ReservedWordsValidator.java
--- app/utils/ReservedWordsValidator.java
+++ app/utils/ReservedWordsValidator.java
@@ -60,6 +60,9 @@
             }
         }
         RESERVED_WORDS.add("new");
+        RESERVED_WORDS.add("projects");
+        RESERVED_WORDS.add("orgs");
+        RESERVED_WORDS.add("organizations");
     }
 
     /**
app/views/common/navbar.scala.html
--- app/views/common/navbar.scala.html
+++ app/views/common/navbar.scala.html
@@ -56,7 +56,7 @@
             </li>
             @if(!Application.HIDE_PROJECT_LISTING){
                 <li class="@isActiveMenu(MenuType.PROJECTS)">
-                    <a href="@routes.ProjectApp.projects()" class="show-progress-bar">@Messages("title.projectList")</a>
+                    <a href="@routes.ProjectApp.projects()" class="show-progress-bar">@Messages("title.list")</a>
                 </li>
                 <li class="divider"></li>
             }
 
app/views/organization/list.scala.html (added)
+++ app/views/organization/list.scala.html
@@ -0,0 +1,104 @@
+@**
+* Yona, 21st Century Project Hosting SW
+*
+* Copyright Yona & Yobi Authors & NAVER Corp.
+* https://yona.io
+**@
+@import utils.Config
+@import utils.AccessControl
+@import models.enumeration.Operation;
+@(message: String, currentPage: com.avaje.ebean.Page[Organization], filter:String)
+@import utils.TemplateHelper._
+@import utils.JodaDateUtil
+
+@siteLayout(message, utils.MenuType.PROJECTS) {
+<div class="site-breadcrumb-outer">
+    <div class="site-breadcrumb-inner">
+        <div class="title_area">
+            <ul class="nav nav-tabs">
+                <li>
+                    <a href="@routes.ProjectApp.projects()">@Messages("project.public") @Messages("title" +
+                        ".projectList")</a>
+                </li>
+                <li class='active'>
+                    <a href="@routes.OrganizationApp.orgList()">@Messages("title.organization.list")</a>
+                </li>
+            </ul>
+        </div>
+    </div>
+</div>
+<div class="page-wrap-outer">
+    <div class="project-page-wrap">
+    	<div class="search-wrap">
+    		<div id="search" class="pull-left">
+    			<form action="@routes.ProjectApp.projects()" method="get">
+    				<div class="search-bar">
+                        <input name="filter" class="textbox" type="text" placeholder="@Messages("site.project.filter")" value="@filter">
+                        <button type="submit" class="search-btn"><i class="yobicon-search"></i></button>
+                    </div>
+    			</form>
+             </div>
+        </div>
+        @if(currentPage.getTotalRowCount == 0){
+            <div class="error-wrap">
+                <i class="ico ico-err1"></i>
+                <p>@Messages("organization.is.empty")</p>
+            </div>
+        } else {
+    	<ul class="all-projects">
+        @for(org <- currentPage.getList) {
+            @if(Config.displayPrivateRepositories() || AccessControl.isAllowed(UserApp.currentUser(), org.asResource(),
+                Operation.READ)){
+            <li class="project">
+                <div class="info-wrap">
+                    <div class="owner-avatar-wrap">
+                        <a href="@routes.OrganizationApp.organization(org.name)">
+                            @if(hasOrganizationLogo(org)){<img src="@urlToOrganizationLogo(org)" alt="@org.name"/>}
+                        </a>
+                    </div>
+                    <div style="float:left">
+                        <div class="header">
+                            <a href="@routes.OrganizationApp.organization(org.name)" class="black">@org.name</a>
+                        </div>
+                        <div class="desc">
+                        @org.descr
+                        </div>
+                        <p class="name-tag">
+                            created <strong title="@JodaDateUtil.getDateString(org.created)">@agoOrDateString(org.created)</strong>
+                        </p>
+                    </div>
+                </div>
+            </li>
+            } else {
+                <li class="project" style="background-color: #fcfcfc;">
+                    <div class="info-wrap" style="opacity: 0.3">
+                        <div class="owner-avatar-wrap">
+                            <img src="@routes.Assets.at("images/organization_default_logo.png")" alt="@org.name"/>
+                        </div>
+                        <div style="float:left; color: gray">
+                            You do not have permission to view this project's information
+                        </div>
+                    </div>
+                </li>
+            }
+        }
+    	</ul>
+
+    	<!-- pagination.js will fill here. -->
+    	<div id="pagination"></div>
+        }
+    </div>
+</div>
+<script type="text/javascript">
+$(document).ready(function(){
+    yobi.Pagination.update($("#pagination"), @currentPage.getTotalPageCount);
+
+    /*
+	$(".btn-advanced").click(function(){
+		$(".inner").toggleClass("advanced");
+	});
+	*/
+});
+</script>
+
+}
app/views/organization/view.scala.html
--- app/views/organization/view.scala.html
+++ app/views/organization/view.scala.html
@@ -80,7 +80,8 @@
                         <div class="info-wrap">
                             <div class="owner-avatar-wrap hide-in-mobile">
                                 <a href="@routes.ProjectApp.project(project.owner,project.name)">
-                                    <img src="@urlToProjectLogo(project)" alt="@project.name"/>
+                                    @if(hasProjectLogo(project)){<img src="@urlToProjectLogo(project)" alt="@project" +
+                                            ".name"/>}
                                 </a>
                             </div>
                             <div style="float:left">
app/views/project/list.scala.html
--- app/views/project/list.scala.html
+++ app/views/project/list.scala.html
@@ -14,13 +14,19 @@
 @siteLayout(message, utils.MenuType.PROJECTS) {
 <div class="site-breadcrumb-outer">
     <div class="site-breadcrumb-inner">
-        <h3>@Messages("project.public") @Messages("title.projectList")</h3>
+        <div class="title_area">
+            <ul class="nav nav-tabs">
+                <li class='active'><a href="@routes.ProjectApp.projects()">@Messages("project.public") @Messages("title" +
+                        ".projectList")</a></li>
+                <li><a href="@routes.OrganizationApp.orgList()">@Messages("title.organization.list")</a></li>
+            </ul>
+        </div>
     </div>
 </div>
 <div class="page-wrap-outer">
     <div class="project-page-wrap">
     	<div class="search-wrap">
-    		<div id="search" class="pull-right">
+    		<div id="search" class="pull-left">
     			<form action="@routes.ProjectApp.projects()" method="get">
     				<div class="search-bar">
                         <input name="filter" class="textbox" type="text" placeholder="@Messages("site.project.filter")" value="@filter">
@@ -42,7 +48,7 @@
                 <div class="info-wrap">
                     <div class="owner-avatar-wrap">
                         <a href="@routes.ProjectApp.project(project.owner,project.name)">
-                            <img src="@urlToProjectLogo(project)" alt="@project.name"/>
+                            @if(hasProjectLogo(project)){<img src="@urlToProjectLogo(project)" alt="@project.name"/>}
                         </a>
                     </div>
                     <div style="float:left">
app/views/site/projectList.scala.html
--- app/views/site/projectList.scala.html
+++ app/views/site/projectList.scala.html
@@ -10,7 +10,6 @@
 @import utils.JodaDateUtil._
 
 @siteMngLayout(message) {
-    <div class="title_area">
         <h2 class="pull-left">@Messages("site.sidebar.projectList")</h2>
         <form class="form-search pull-right" action="@routes.SiteApp.projectList()">
             <div class="search-bar">
conf/messages
--- conf/messages
+++ conf/messages
@@ -890,6 +890,7 @@
 title.issueTracker = Issue tracker
 title.joinmember = Member
 title.keymap = Keyboard shortcuts
+title.list = All List
 title.login = Log in
 title.loginFor = Log in to <span class="highlight">{0}</span>
 title.logout = Log out
@@ -903,6 +904,7 @@
 title.newPullRequest = Send pull request
 title.no.results = No results
 title.organization = Groups
+title.organization = Group List
 title.organizationHome = Group Home
 title.post.notExistingPage = Page not found
 title.privateProject = Private repositories
conf/messages.ko-KR
--- conf/messages.ko-KR
+++ conf/messages.ko-KR
@@ -884,6 +884,7 @@
 title.issueTracker = 이슈 트래커
 title.joinmember = 멤버로 참여중인
 title.keymap = 단축키 안내
+title.list = 전체 목록
 title.login = 로그인
 title.loginFor = <span class="highlight">{0}</span> 로그인
 title.logout = 로그아웃
@@ -897,6 +898,7 @@
 title.newPullRequest = 코드 보내기
 title.no.results = 결과 없음
 title.organization = 그룹
+title.organization.list = 그룹 목록
 title.organizationHome = 홈
 title.post.notExistingPage = 페이지를 찾지 못했습니다.
 title.privateProject = 비공개 프로젝트
conf/routes
--- conf/routes
+++ conf/routes
@@ -177,6 +177,7 @@
 GET            /projectform                                                           controllers.ProjectApp.newProjectForm()
 POST           /projects                                                              controllers.ProjectApp.newProject()
 GET            /projects                                                              controllers.ProjectApp.projects(filter:String ?= "", pageNum: Int ?= 1)
+GET            /orgs                                                                  controllers.OrganizationApp.orgList(filter:String ?= "", pageNum: Int ?= 1)
 GET            /:user/:project                                                        controllers.ProjectApp.project(user, project)
 PUT            /:user/:project                                                        controllers.ProjectApp.projectOverviewUpdate(user, project)
 GET            /:user/:project/settingform                                            controllers.ProjectApp.settingForm(user, project)
Add a comment
List