doortts doortts 2018-12-12
Merge branch 'feature/sidebar' into next
Reviewed-by: Hyunjae Park
@68e48e1b71ee4ddf21ea0867b398189f544c9814
app/assets/stylesheets/less/_mixins.less
--- app/assets/stylesheets/less/_mixins.less
+++ app/assets/stylesheets/less/_mixins.less
@@ -3,9 +3,9 @@
 
 // Border Radius
 .border-radius(@radius: 5px){
-    -webkit-border-radius: @radius !important;
-    -moz-border-radius: @radius !important;
-    border-radius: @radius !important;
+    -webkit-border-radius: @radius;
+    -moz-border-radius: @radius;
+    border-radius: @radius;
 }
 .border-radius-bottom(@radius: 5px){
     -webkit-border-bottom-left-radius:@radius;
app/assets/stylesheets/less/_page.less
--- app/assets/stylesheets/less/_page.less
+++ app/assets/stylesheets/less/_page.less
@@ -1,4 +1,71 @@
 //--- common
+
+.main {
+    width: 100%;
+    background-color: #fff;
+}
+
+.sidebar {
+    background-color: rgb(51, 51, 51);
+    position: sticky;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    min-height: 100vh;
+
+    .nav {
+        width: 270px;
+    }
+
+    .nav-tabs {
+        border-bottom: none;
+
+        li {
+            margin-bottom: -2px;
+
+            a {
+                padding: 8px 10px;
+                border: none;
+                color: lightgray;
+
+                &:hover {
+                    color: #f36c22;
+                    background-color: black;
+                    border: none;
+                }
+            }
+        }
+
+        .active {
+            a {
+                color: #f36c22;
+                background-color: black;
+                border: none;
+            }
+        }
+    }
+
+    .user-menu-wrap {
+        padding: 10px;
+        color: grey;
+        box-sizing: border-box;
+
+        a {
+            &:hover {
+                color: white;
+            }
+        }
+    }
+
+    .user-menu {
+        padding: 5px;
+    }
+}
+
+#mainFrame {
+    width: 100%;
+}
+
 .prj {
     color:#202020;
 }
@@ -19,7 +86,6 @@
     display:none;
 
     .unsupported-inner {
-        width: 1170px;
         margin:0 auto;
 
         p {
@@ -55,11 +121,29 @@
     }
 }
 
+.pin {
+    position: absolute;
+    display: inline-block;
+    left: -2px;
+    top: 6px;
+    border: 1px solid #666;
+    margin-right: 5px;
+
+    .yobicon-arrow-right {
+        padding: 6px 2px;
+    }
+
+    &:hover {
+        cursor: pointer;
+        color: white;
+    }
+}
+
 .gnb-inner {
-    width: 1170px;
     margin:0 auto;
     color:#788ba7;
     height:40px;
+    width: 98%;
 }
 
 .gnb-inner {
@@ -350,8 +434,8 @@
 
         .project-header-wrap {
             height:inherit;
-            width:1170px;
             margin:0 auto;
+            width: 99%;
             position: relative;
 
             .project-header-avatar {
@@ -479,7 +563,6 @@
 
 .page-wrap {
     background-color: @white;
-    width: 1170px;
     margin: 0 auto;
 }
 
@@ -490,7 +573,6 @@
 
     .project-menu-inner {
         height:39px;
-        width: 1170px;
         margin:0 auto;
 
         .project-menu-nav {
@@ -585,7 +667,6 @@
 }
 
 .project-page-wrap {
-    width: 1170px;
     margin:20px auto 0;
 
     label {
@@ -603,7 +684,6 @@
 
 .site-breadcrumb-outer {
     .site-breadcrumb-inner {
-        width: 1170px;
         margin:0 auto;
 
         h3 {
@@ -622,7 +702,6 @@
         margin: 0 auto;
         text-align:center;
         line-height: 34px;
-        width:1170px;
     }
 
     .provider {
@@ -905,7 +984,6 @@
     background-color:#f9f9f9;
     padding:80px 20px;
     .sample-wrap {
-        width:980px;
         margin:0 auto;
         text-align:center;
         overflow:auto;
@@ -5063,7 +5141,6 @@
 
 // -- site admin
 .site-setting-wrap {
-    width: 1170px;
     margin:20px auto 0;
 
     .site-setting-nav {
app/assets/stylesheets/less/_responsive.less
--- app/assets/stylesheets/less/_responsive.less
+++ app/assets/stylesheets/less/_responsive.less
@@ -1,6 +1,10 @@
 @media all and (max-width: 720px){
     body {
         overflow-y: auto;
+        flex-direction: column;
+    }
+    .sidebar {
+        position: relative;
     }
     .sidemenu-width {
       width: 100vw !important;
@@ -454,7 +458,7 @@
     }
 }
 
-@media all and (max-width:1199px){
+@media all {
     .attachment-files {
         font-size: 12px;
         .attachment-files-header {
@@ -491,20 +495,12 @@
 
         .unsupported-inner {
             width:95%;
-            max-width: 980px;
         }
     }
 
     .gnb-outer {
-        max-width: 1199px;
-        width: 100%;
         padding:0 10px;
         box-sizing: border-box;
-
-        .gnb-inner {
-            max-width:980px;
-            width: 100%;
-        }
     }
 
     .search-box {
@@ -514,26 +510,14 @@
     }
 
     .page-wrap-outer {
-        max-width: 1199px;
         padding:0 10px;
         width: 100%;
         box-sizing: border-box;
     }
 
-    .page-wrap {
-        width: 95%;
-        max-width:980px;
-    }
-
-    .project-menu-inner {
-        width: 95%;
-        max-width:980px;
-    }
-
     .project-page-wrap {
         width: 100%;
         margin-top: 5px !important;
-        max-width:980px;
         .project-breadcrumb {
             font-size: 1.5em;
             font-weight: bold;
@@ -542,33 +526,8 @@
 
     .site-breadcrumb-outer {
         width: 100%;
-        max-width: 1199px;
         padding:0 10px;
         box-sizing: border-box;
-
-        .site-breadcrumb-inner {
-            width: 95%;
-            max-width:980px;
-        }
-    }
-    .project-header-outer {
-        max-width: 1199px;
-
-        .project-header-inner {
-            .project-header-wrap {
-                width: 95%;
-                max-width: 980px;
-            }
-        }
-    }
-
-    .project-menu-outer {
-        max-width: 1199px;
-
-        .project-menu-inner {
-            width: 95%;
-            max-width: 980px;
-        }
     }
 
     .project-home-header {
@@ -617,13 +576,7 @@
         }
     }
 
-    .site-setting-wrap {
-        width: 95%;
-        max-width:980px;
-    }
-
     .page-footer-outer {
-        max-width: 1199px;
         padding:10px;
 
         .page-footer {
app/assets/stylesheets/less/_usermenu.less
--- app/assets/stylesheets/less/_usermenu.less
+++ app/assets/stylesheets/less/_usermenu.less
@@ -49,6 +49,7 @@
   &:hover {
     background-color: @violet;
   }
+
   a:hover {
     text-decoration: none;
   }
@@ -57,10 +58,10 @@
 .user-project-list {
   ul.nav-subtab > li {
     border: none;
+    margin-left: 0;
   }
 
   li {
-    border-bottom: 1px solid transparent;
     margin-left: 0;
   }
 
@@ -82,26 +83,30 @@
     list-style-type: none;
 
     .favored {
-      border-bottom: 1px dashed #7b1fa2;
+      border-bottom: 1px dashed gray;
     }
   }
 
   .user-li {
-    color: #000;
-    border-left: 1px solid #fff;
-    border-top: 1px solid #fff;
-    border-right: 1px solid #fff;
     cursor: pointer;
 
-    &:hover {
-      color: #3592B5;
-      border: 1px solid #3592B5 !important;
+    .popover {
+      word-wrap: break-word;
+      min-width: 200px;
+      background-color: rgb(3, 169, 244);
+      color: white;
+
+      .arrow {
+        &::after {
+          border-right-color: rgb(3, 169, 244);
+        }
+      }
     }
 
   }
 
   .etc-favorites {
-    border-top: 1px dashed #7b1fa2;
+    border-top: 1px dashed gray;
   }
 
   .user-search-form{
@@ -162,16 +167,18 @@
 
   .group {
     position:relative;
-    margin-top: 5px;
   }
 
   .search-input {
-    font-size:14px;
-    padding:10px 10px 10px 20px;
+    font-size:13px;
+    padding: 8px 10px;
     display:block;
     border:none;
-    width: 90%;
+    width: 99%;
     margin-bottom: 0;
+    background-color: black;
+    color: white;
+    border-radius: unset;
   }
 
   .search-input:focus {
@@ -200,7 +207,7 @@
     width:0;
     bottom:1px;
     position:absolute;
-    background: @orange;
+    background: white;
     transition:0.2s ease all;
   }
   .bar:before {
@@ -224,7 +231,6 @@
   ::-webkit-scrollbar-thumb {
     background: #1fb0ff;
   }
-
 
   li:focus {
     outline:solid 0 #DCDCDC;
@@ -309,16 +315,18 @@
   .star {
     vertical-align: bottom;
     height: 15px;
+    font-size: 16px;
   }
+
   .starred {
-    color: #e91e63;
+    color: rgba(255, 255, 255, 0.85);
   }
 
   .star-project, .star-org {
     width: 29px;
-    min-height: 35px;
+    min-height: 24px;
     flex-shrink: 0;
-    color: #eee;
+
     &:hover {
       color: #e91e63;
     }
@@ -355,13 +363,7 @@
   }
 
   .selected {
-    border-radius: 5px;
-    background-color: #9C27B0;
-    color: #fafafa;
-    padding: 3px 7px;
-    margin-right: 5px;
-    line-height: 25px;
-    z-index: 999;
+    background-color: rgba(255, 255, 255, 0.15);
   }
 
   .additional-help{
@@ -390,18 +392,19 @@
   }
 
   .site-logo {
-    width: 45px;
+    width: 26px;
     text-align: center;
     margin-left: 2px;
-    margin-right: -2px;
     padding-top: 3px;
     overflow: hidden;
     flex-shrink: 0;
+
     img {
-      width: 24px;
+      width: 16px;
       border-radius: 3px;
-      margin-right: 3px;
+      margin-right: 0;
       height: auto;
+      vertical-align: text-top;
     }
   }
 
@@ -455,8 +458,10 @@
   }
 
   .project-item {
-    font-size: 14px;
+    font-size: 13px;
+    font-weight: 400;
     overflow: hidden;
+    color: rgba( 255, 255, 255, 0.85 );
 
     .slash {
       padding: 5px;
@@ -464,36 +469,36 @@
 
     .project-name{
       min-width: 50px;
-      max-width: 220px;
+      max-width: 150px;
       text-overflow: ellipsis;
       overflow: hidden;
       white-space: nowrap;
+      font-family: roboto, sans-serif;
+      -webkit-font-smoothing: antialiased;
 
       &.org-name {
-        max-width: 320px;
-        font-size: 1.1em;
+        max-width: 140px;
+        font-size: 13px;
+        color: #00bcd4;
       }
 
       a {
         &:hover {
           text-decoration: none;
-          color: #3592B5;
+          color: white;
         }
       }
     }
 
     .all-project-names {
-      padding-left: 30px;
+      padding-left: 22px;
     }
 
     .all-org-names {
-      font-weight: 600;
-      color: black;
-      border-bottom: 1px solid transparent;
-
-      &:hover {
-        border-bottom: 1px solid #3592B5;
-      }
+      font-weight: 700;
+      color: white;
+      font-family: Roboto, sans-serif;
+      -webkit-font-smoothing: antialiased;
     }
 
     .project-owner {
@@ -505,7 +510,7 @@
       text-overflow: ellipsis;
       overflow: hidden;
       white-space: nowrap;
-      max-width: 100px;
+      max-width: 50px;
       min-width: 40px;
       a {
         &:hover {
@@ -523,7 +528,7 @@
     align-items: center;
     flex-grow: 1;
     overflow: hidden;
-    padding: 5px 0;
+    padding: 1px 0;
   }
 
   .page-list-item {
@@ -585,12 +590,17 @@
   }
 
   .list-end{
-    border-bottom: 1px dashed #7b1fa2;
+    border-bottom: 1px dashed gray;
+  }
+
+  .org-li {
+    margin-top: 3px;
   }
 
   .project-list, .org-list {
     &:hover {
       cursor: pointer;
+      background-color: rgba(255, 255, 255, 0.15);
     }
   }
 
@@ -785,13 +795,14 @@
   color: black;
   background-color: #eee;
   display: inline-block;
+
   a:hover {
     color: black;
   }
 }
 
 .nav-subtab li a {
-  padding: 5px 16px;
+  padding: 5px 8px;
 }
 
 /* Position and style the close button (top right corner) */
app/assets/stylesheets/less/_yobiUI.less
--- app/assets/stylesheets/less/_yobiUI.less
+++ app/assets/stylesheets/less/_yobiUI.less
@@ -6,7 +6,11 @@
  * (bootstrap 2.3.1 : 14px,
  *  bootstrap 2.2.1 : 12px)
  */
-body { font-size:13px; }
+body {
+    font-size:13px;
+    display: flex;
+    min-height: 99vh;
+}
 label, input, button, select, textarea { font-size:12px; }
 select, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"],
 input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"],
@@ -528,7 +532,7 @@
 .nav-subtab {
     li {
         display: inline-block;
-        margin-left:10px;
+        margin-left: 5px;
         
         &:first-child {
             margin-left:0;
@@ -536,7 +540,7 @@
 
         a {
             display: block;
-            padding: 5px 10px;
+            padding: 5px 8px;
 
             &:hover {
                 text-decoration: none;
app/controllers/Application.java
--- app/controllers/Application.java
+++ app/controllers/Application.java
@@ -43,11 +43,6 @@
 
     @AnonymousCheck
     public static Result index() {
-        User user = UserApp.currentUser();
-        UserSetting userSetting = UserSetting.findByUser(user.id);
-        if(!user.isAnonymous() && StringUtils.isNotBlank(userSetting.loginDefaultPage)) {
-            return redirect(userSetting.loginDefaultPage);
-        }
         return ok(index.render(UserApp.currentUser()));
     }
 
app/models/Organization.java
--- app/models/Organization.java
+++ app/models/Organization.java
@@ -1,23 +1,10 @@
 /**
- * Yobi, Project Hosting SW
- *
- * Copyright 2013 NAVER Corp.
- * http://yobi.io
- *
- * @author Keesun Baik, Wansoon Park, ChangSung Kim
- *
- * 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.
- */
+ * Yona, 21st Century Project Hosting SW
+ * <p>
+ * Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp.
+ * https://yona.io
+ **/
+
 package models;
 
 import com.avaje.ebean.Expr;
@@ -178,6 +165,9 @@
 
     public static List<Organization> findAllOrganizations(String loginId) {
         User user = User.findByLoginId(loginId);
+        if (user.isAnonymous()) {
+            return new ArrayList<>();
+        }
 
         Set<String> owners = new TreeSet<>(new Comparator<String>() {
             @Override
app/views/common/navbar.scala.html
--- app/views/common/navbar.scala.html
+++ app/views/common/navbar.scala.html
@@ -36,9 +36,10 @@
 </div>
 <header class="gnb-outer @if(project != null || org != null) {project-header}">
     <div class="gnb-inner">
+        <div class="pin"><i class="yobicon-arrow-right"></i></div>
         <ul class="gnb-nav">
             <li>
-                <a href="@routes.Application.index()" class="logo logo-letter">Y</a>
+                <a href="@routes.Application.index()" target="_parent" class="logo logo-letter">Y</a>
             </li>
             @if(!Application.HIDE_PROJECT_LISTING && !UserApp.currentUser().isGuest){
                 <li class="@isActiveMenu(MenuType.PROJECTS)">
app/views/common/usermenu.scala.html
--- app/views/common/usermenu.scala.html
+++ app/views/common/usermenu.scala.html
@@ -37,43 +37,6 @@
     }
 }
 
-<div id="mySidenav" class="sidenav">
-    <div class="span5 right-menu span-hard-wrap">
-        <div class="row-fluid user-menu-wrap">
-            <span class="user-menu"><a href="@routes.UserApp.userInfo(currentUser.loginId)">@Messages("userinfo.profile")</a></span>
-            <span class="user-menu"><a href="@routes.UserApp.editUserInfoForm()">@Messages("userinfo.accountSetting")</a></span>
-            @currentAuth() { auth =>
-                @if(auth != null) {
-                    <a href="@routes.Application.oAuthLogout"><span class="user-menu logout label">@Messages("title.logout")</span></a>
-                } else {
-                    <a href="@routes.UserApp.logout()"><span class="user-menu logout label">@Messages("title.logout")</span></a>
-                }
-            }
-        </div>
-        <ul class="nav nav-tabs nm">
-            <li class="myOrganizationList active">
-                <a href="#myOrganizationList" data-toggle="tab">
-                @Messages("title.favorite")
-                </a>
-            </li>
-            <li class="myProjectList">
-                <a href="#myProjectList" data-toggle="tab">
-                @Messages("title.project")
-                </a>
-            </li>
-            <li class="allProjectList">
-                <a href="#allProjectList" data-toggle="tab">
-                @Messages("common.order.all")
-                </a>
-            </li>
-        </ul>
-        <div class="tab-content tab-box">
-            <div id="usermenu-tab-content-list" class="tab-content">
-                Loading...
-            </div>
-        </div>
-    </div>
-</div>
 <ul class="gnb-usermenu">
     @if( !currentUser.isAnonymous()) {
         @if(!StringUtils.isBlank(Application.NAVBAR_CUSTOM_LINK_NAME)) {
@@ -81,9 +44,6 @@
             <a href="@Application.NAVBAR_CUSTOM_LINK_URL" class="user-item-btn loggged-in">@Application.NAVBAR_CUSTOM_LINK_NAME</a>
         </li>
         }
-       <li class="gnb-usermenu-item hide-in-mobile">
-          <a href="@routes.Application.notifications()" class="user-item-btn loggged-in">@Messages("notification")</a>
-       </li>
        <li class="gnb-usermenu-item" data-toggle="tooltip" data-placement="bottom" title="@Messages("title.shortcut") (A)">
            <a href="@routes.IssueApp.userIssues()" class="user-item-btn loggged-in">@Messages("issue.myIssue")@myOpenIssueCount</a>
         </li>
@@ -96,15 +56,6 @@
         </li>
         <li class="divider"></li>
         }
-        <li class="gnb-usermenu-dropdown sidebar-open-btn" id="sidebar-open-btn">
-            <a href="javascript:void(0);" class="gnb-dropdown-toggle" data-toggle="tooltip" data-placement="bottom" title="@Messages("user.menu"), @Messages("title.shortcut") (F)">
-                <span class="avatar-wrap smaller">
-                    <img src="@currentUser.avatarUrl(32)" />
-                </span>
-                <span class="caret-text hide-in-mobile">@currentUser.getPureNameOnly</span>
-                <span class="caret"></span>
-            </a>
-        </li>
       <li class="gnb-usermenu-dropdown">
           <a href="javascript:void(0);" class="gnb-dropdown-toggle dropdwon-box-btn" data-toggle="dropdown">
               <i class="yobicon-plus"></i>
app/views/common/usermenu_tab_content_list.scala.html
--- app/views/common/usermenu_tab_content_list.scala.html
+++ app/views/common/usermenu_tab_content_list.scala.html
@@ -10,7 +10,9 @@
 <div class="tab-pane user-project-list" id="myProjectList">
 @views.html.index.myProjectList(UserApp.currentUser())
 </div>
-<div class="tab-pane user-project-list" id="allProjectList">
+@if(!Application.HIDE_PROJECT_LISTING && !UserApp.currentUser().isGuest){
+    <div class="tab-pane user-project-list" id="allProjectList">
 @views.html.index.allProjectList(UserApp.currentUser())
-</div>
+    </div>
+}
 
app/views/error/notfound_default.scala.html
--- app/views/error/notfound_default.scala.html
+++ app/views/error/notfound_default.scala.html
@@ -35,7 +35,6 @@
                     <a href="https://github.com/nforge/yobi/issues?state=open" target="_blank">@Messages("title.yobi.feedback")</a>
                 </li>
             </ul>
-            @common.usermenu()
         </div>
     </header>
     <div class="page-wrap-outer">
app/views/index/allOrganizationList_partial.scala.html
--- app/views/index/allOrganizationList_partial.scala.html
+++ app/views/index/allOrganizationList_partial.scala.html
@@ -12,10 +12,10 @@
     <div class="org-list project-flex-container all-orgs">
         <div class="project-item project-item-container">
             <div class="flex-item site-logo">
-                <i class="project-avatar">@if(hasOrganizationLogo(organization)){<img class="logo" src="@urlToOrganizationLogo(organization)">}else{<span class="dummy-25px"> </span>}</i>
+                <i class="yobicon-angle-right"></i>
             </div>
             <div class="projectName-owner all-org-names flex-item">
-                <div class="project-name org-name flex-item"><a href="@routes.OrganizationApp.organization(organization.name)" target="_blank">@organization.name</a></div>
+                <div class="project-name org-name flex-item">@organization.name</div>
                 <div class="project-owner flex-item sub-project-counter"></div>
             </div>
         </div>
app/views/index/allProjectList_partial.scala.html
--- app/views/index/allProjectList_partial.scala.html
+++ app/views/index/allProjectList_partial.scala.html
@@ -12,7 +12,7 @@
 
 @if(AccessControl.isAllowed(UserApp.currentUser(), project.asResource(), Operation.READ)){
 <li class="user-li @if(isLast){favored} @if(favored){ show-always } else { hide }" data-location="@routes.ProjectApp.goConventionMenu(project.owner, project.name)">
-    <div class="project-list project-flex-container">
+    <div class="project-list project-flex-container" data-toggle='popover' data-trigger="hover" data-placement="right" data-content="@project.overview">
         <div class="project-item project-item-container">
             <div class="flex-item site-logo all-project-names">
                 <i class="project-avatar">@if(hasProjectLogo(project)){<img class="logo" src="@urlToProjectLogo(project)">}else{<span class="dummy-25px"> </span>}</i>
app/views/index/index.scala.html
--- app/views/index/index.scala.html
+++ app/views/index/index.scala.html
@@ -10,4 +10,6 @@
 @import utils.JodaDateUtil
 @import utils.MenuType._
 
-@views.html.index.notifications(currentUser)
+@siteLayout_framed(utils.Config.getSiteName, utils.MenuType.SITE_HOME) {
+
+}
app/views/index/myOrganizationList.scala.html
--- app/views/index/myOrganizationList.scala.html
+++ app/views/index/myOrganizationList.scala.html
@@ -17,7 +17,7 @@
                     <div class="org-list project-flex-container all-orgs">
                         <div class="project-item project-item-container">
                             <div class="flex-item site-logo">
-                                <i class="project-avatar"></i>
+                                <i class="yobicon-angle-right"></i>
                             </div>
                             <div class="projectName-owner all-org-names flex-item">
                                 <div class="project-name org-name flex-item">@currentUser.loginId</div>
app/views/index/myOrganizationList_partial.scala.html
--- app/views/index/myOrganizationList_partial.scala.html
+++ app/views/index/myOrganizationList_partial.scala.html
@@ -16,10 +16,10 @@
     <div class="org-list project-flex-container all-orgs">
         <div class="project-item project-item-container">
             <div class="flex-item site-logo">
-                <i class="project-avatar">@if(hasOrganizationLogo(organization)){<img class="logo" src="@urlToOrganizationLogo(organization)">}else{<span class="dummy-25px"> </span>}</i>
+                <i class="yobicon-angle-right"></i>
             </div>
             <div class="projectName-owner all-org-names flex-item">
-                <div class="project-name org-name flex-item"><a href="@routes.OrganizationApp.organization(organization.name)" target="_blank">@organization.name</a></div>
+                <div class="project-name org-name flex-item">@organization.name</div>
                 <div class="project-owner flex-item">@if(isAllowShowCount){@organization.projects.size()}</div>
             </div>
         </div>
app/views/layout.scala.html
--- app/views/layout.scala.html
+++ app/views/layout.scala.html
@@ -6,6 +6,10 @@
 **@
 @(title: String)(theme:String)(content: Html)
 @titleArray = @{title.split(" \\|:\\| ")}
+@currentUser = @{
+    UserApp.currentUser()
+}
+
 <!DOCTYPE html>
 <html lang="@UserApp.currentUser().getPreferredLanguage">
 <head>
@@ -36,7 +40,7 @@
 </head>
 
 <body class="@theme" id="html-body">
-    <div id="main">
+    <div id="main" class="main">
     @if(UserApp.isSiteAdminLoggedInSession){
         <div class="admin-logged-in-affix" data-spy="affix" data-offset-top="30">@Messages("user.siteAdminLoggedInAffix") <span class="small-font">@Messages("user.siteAdminLoggedInAffix.maxim")</span></div>
     }
@@ -87,7 +91,22 @@
                     }
                 });
             });
+
+            window.parent.document.title = window.document.title;
+            window.parent.history.pushState('', window.document.title, window.location.href);
+
+            $(".pin").on("click", function () {
+                if (window.parent === window) {
+                    window.location.href = "@routes.Application.index?path=" + window.location.pathname;
+                } else {
+                    window.parent.$(".sidebar").toggle();
+                    if(window.parent.$(".sidebar").text().trim().length < 1) {
+                        window.parent.location.reload();
+                    }
+                }
+            });
         })
+
     </script>
 
     @if(Application.SEND_YONA_USAGE){
 
app/views/layout_framed.scala.html (added)
+++ app/views/layout_framed.scala.html
@@ -0,0 +1,101 @@
+@**
+* Yona, 21st Century Project Hosting SW
+*
+* Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp.
+* https://yona.io
+**@
+@(title: String)(theme:String)(content: Html)(implicit request: RequestHeader)
+@titleArray = @{title.split(" \\|:\\| ")}
+@currentUser = @{
+    UserApp.currentUser()
+}
+
+@defaultPage = @{
+    if(UserSetting.findByUser(currentUser.id).loginDefaultPage == null) {
+        routes.Application.notifications().toString
+    } else {
+        UserSetting.findByUser(currentUser.id).loginDefaultPage
+    }
+}
+
+@iframePath = @{
+    request.getQueryString("path").getOrElse(defaultPage)
+}
+
+<!DOCTYPE html>
+<html lang="@UserApp.currentUser().getPreferredLanguage">
+<head>
+<meta charset="utf-8">
+<title>@titleArray(0)</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta property="og:title" content="@titleArray(0)" />
+<meta property="og:url" content="@play.mvc.Http.Context.current().request().path()" />
+<meta property="og:type" content="website" />
+<meta property="og:description" content="@{titleArray(titleArray.length-1)}" />
+<meta name="twitter:card" content="summary" />
+<meta name="twitter:title" content="@titleArray(0)" />
+<meta name="twitter:url" content="@play.mvc.Http.Context.current().request().path()" />
+<meta name="twitter:description" content="@{titleArray(titleArray.length-1)}" />
+<link rel="shortcut icon" type="image/x-icon" href="@routes.Assets.at("images/favicon.ico")">
+<link rel="stylesheet" type="text/css" media="all" href="@routes.Assets.at("bootstrap/css/bootstrap.css")">
+<link rel="stylesheet" type="text/css" media="all" href="@routes.Assets.at("stylesheets/yobicon/style.css")">
+<link rel="stylesheet" type="text/css" media="all" href="@routes.Assets.at("javascripts/lib/select2/select2.css")"/>
+<link rel="stylesheet" type="text/css" media="all" href="@routes.Assets.at("javascripts/lib/pikaday/pikaday.css")" />
+<link rel="stylesheet" type="text/css" media="all" href="@routes.Assets.at("stylesheets/usermenu.css")">
+<link rel="stylesheet" type="text/css" media="all" href="@routes.Assets.at("stylesheets/yobi.css")">
+<link rel='stylesheet' href="@routes.Assets.at("javascripts/lib/nprogress/nprogress.css")"/>
+<link rel="stylesheet" href="@routes.Assets.at("javascripts/lib/magnific-popup/magnific-popup.css")" />
+<script type="text/javascript" src="@routes.Assets.at("javascripts/yona-layout.js")"></script>
+
+</head>
+
+<body class="@theme" id="html-body">
+    <div id="sidebar" class="sidebar">
+        @if(!currentUser.isAnonymous){
+            @sidebar()
+        }
+    </div>
+    <div id="mainFrame">
+        <iframe name="mainFrame" frameborder="0" scrolling="no" height="100%" width="100%" src="@iframePath"  scrolling="no" onload="resizeIframe(this)"></iframe>
+        @common.scripts()
+    </div>
+
+    <script type="text/javascript">
+        $(function() {
+            NProgress.configure({minimum: 0.7});
+
+            $('[data-toggle="popover"]').popover();
+        });
+
+        function resizeIframe(obj) {
+            obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
+            window.scrollTo(0, 0);
+        }
+
+        //Following three values are used for common/yona.Usermenu.js
+        var UsermenuToggleFavoriteProjectUrl = "@api.routes.UserApi.toggleFoveriteProject("")";
+        var UsermenuToggleFoveriteOrganizationUrl = "@api.routes.UserApi.toggleFoveriteOrganization("")";
+        var UsermenuGetFoveriteProjectsUrl = "@api.routes.UserApi.getFoveriteProjects()";
+        var UsermenuToggleFavoriteIssueUrl = "@api.routes.UserApi.toggleFoveriteIssue("")";
+        var UsermenuGetFoveriteIssuesUrl = "@api.routes.UserApi.getFoveriteIssues()";
+        var UsermenuUrl = "@routes.UserApp.usermenuTabContentList()";
+
+    </script>
+    <script type="text/javascript" src="@routes.Assets.at("javascripts/common/yona.Usermenu.js")"></script>
+
+    @if(Application.SEND_YONA_USAGE){
+    <script>
+        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+                    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+                m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+        })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+
+        ga('create', 'UA-102735758-1', 'auto');
+        ga('send', 'pageview');
+    </script>
+    }
+
+</body>
+</html>
 
app/views/sidebar.scala.html (added)
+++ app/views/sidebar.scala.html
@@ -0,0 +1,75 @@
+@import org.apache.commons.lang3.StringUtils
+@import utils.TemplateHelper._
+@import com.feth.play.module.pa.PlayAuthenticate._
+@import com.feth.play.module.pa.views.html._
+@import play.mvc.Http._;
+
+@currentUser = @{
+    UserApp.currentUser()
+}
+
+@if(currentUser.isAnonymous){
+    @currentAuth() { auth => @{
+        if(auth == null) {
+            val redirect = Context.current().request().getQueryString("redirectUrl")
+            if(StringUtils.isNotEmpty(redirect)) {
+                val url = Context.current().session().put("pa.url.orig", redirect)
+            } else {
+                val url = storeOriginalUrl(Context.current())
+            }
+        }
+    }
+    }
+}
+
+
+<div class="row-fluid user-menu-wrap">
+    <span class="user-menu"><a href="@routes.UserApp.userInfo(currentUser.loginId)" target="mainFrame">
+        <span class="avatar-wrap smaller">
+            <img src="@currentUser.avatarUrl(32)" />
+        </span>
+        <span class="caret-text hide-in-mobile">@currentUser.getPureNameOnly</span>
+    </a></span>
+    <span class="user-menu"><a href="@routes.UserApp.editUserInfoForm()" target="mainFrame">@Messages("userinfo.accountSetting")</a></span>
+    @currentAuth() { auth =>
+        @if(auth != null) {
+            <a href="@routes.Application.oAuthLogout"><span class="user-menu logout label">@Messages("title.logout")</span></a>
+        } else {
+            <a href="@routes.UserApp.logout()"><span class="user-menu logout label">@Messages("title.logout")</span></a>
+        }
+    }
+</div>
+<ul class="nav nav-tabs nm">
+    <li class="myOrganizationList active">
+        <a href="#myOrganizationList" data-toggle="tab">
+        @Messages("title.favorite")
+        </a>
+    </li>
+    <li class="myProjectList">
+        <a href="#myProjectList" data-toggle="tab">
+        @Messages("title.project")
+        </a>
+    </li>
+    @if(!Application.HIDE_PROJECT_LISTING && !UserApp.currentUser().isGuest){
+    <li class="allProjectList">
+        <a href="#allProjectList" data-toggle="tab">
+        @Messages("common.order.all")
+        </a>
+    </li>
+    }
+</ul>
+<div class="tab-content tab-box">
+    <div id="usermenu-tab-content-list" class="tab-content">
+        <div class="tab-pane user-project-list active" id="myOrganizationList">
+        @views.html.index.myOrganizationList(UserApp.currentUser())
+        </div>
+        <div class="tab-pane user-project-list" id="myProjectList">
+        @views.html.index.myProjectList(UserApp.currentUser())
+        </div>
+        @if(!Application.HIDE_PROJECT_LISTING && !UserApp.currentUser().isGuest){
+            <div class="tab-pane user-project-list" id="allProjectList">
+            @views.html.index.allProjectList(UserApp.currentUser())
+            </div>
+        }
+    </div>
+</div>
 
app/views/siteLayout_framed.scala.html (added)
+++ app/views/siteLayout_framed.scala.html
@@ -0,0 +1,17 @@
+@**
+* Yona, 21st Century Project Hosting SW
+*
+* Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp.
+* https://yona.io
+**@
+@(title: String, menuType:utils.MenuType)(content: Html)
+
+@import utils._
+
+@layout_framed(Messages(title))(""){
+    @common.navbar(menuType, null, null)
+
+    @content
+
+    @common.footer()
+}
conf/messages.ko-KR
--- conf/messages.ko-KR
+++ conf/messages.ko-KR
@@ -936,7 +936,7 @@
 title.issueDetail = 이슈 상세보기
 title.issueList = 이슈 목록
 title.issueTracker = 이슈 트래커
-title.joinmember = 멤버로 참여중인
+title.joinmember = 참여 중인
 title.keymap = 단축키 안내
 title.list = 전체 목록
 title.login = 로그인
public/bootstrap/css/bootstrap-responsive.css
--- public/bootstrap/css/bootstrap-responsive.css
+++ public/bootstrap/css/bootstrap-responsive.css
@@ -1101,9 +1101,3 @@
   }
 }
 
-@media (min-width: 980px) {
-  .nav-collapse.collapse {
-    height: auto !important;
-    overflow: visible !important;
-  }
-}
public/javascripts/common/yona.Usermenu.js
--- public/javascripts/common/yona.Usermenu.js
+++ public/javascripts/common/yona.Usermenu.js
@@ -1,14 +1,5 @@
 $(function() {
-    if($(".gnb-usermenu-dropdown").length !== 0) {
-        $.get(UsermenuUrl)
-            .done(function (data) {
-                $("#usermenu-tab-content-list").html(data);
-                afterUsermenuLoaded();
-            })
-            .fail(function (data) {
-                console.log("Usermenu loading failed: " + data);
-            });
-    }
+    afterUsermenuLoaded();
 
     function afterUsermenuLoaded(){
         /* Set side navigation */
@@ -124,7 +115,6 @@
                         that.find('i').addClass("starred");
                     } else {
                         that.find('i').removeClass("starred");
-                        removeIfNotFavoriteProject(that);
                     }
                 })
                 .fail(function (data) {
@@ -141,7 +131,6 @@
                         that.find('i').addClass("starred");
                     } else {
                         that.find('i').removeClass("starred");
-                        removeIfNotFavoriteProject(that);
                     }
                     $yobi.notify(Messages(data.message), 3000);
                 })
@@ -151,25 +140,6 @@
 
         });
 
-
-        function removeIfNotFavoriteProject(that) {
-            var $recentlyVisited = $('.user-li');
-            var lastFavoriteItemIndex = $recentlyVisited.index($(".favored"));
-            var currentItemIndex = $recentlyVisited.index(that.parent(".project-list").parent());
-            if (lastFavoriteItemIndex < currentItemIndex) {
-                that.parent(".project-list").remove();
-            }
-        }
-
-        function removeIfNotFavoriteIssue(that) {
-            var $recentlyVisited = $('.user-li');
-            var lastFavoriteItemIndex = $recentlyVisited.index($(".favored"));
-            var currentItemIndex = $recentlyVisited.index(that.parent(".issue-list").parent());
-            if (lastFavoriteItemIndex < currentItemIndex) {
-                that.parent(".issue-list").remove();
-            }
-        }
-
         $(".user-ul > .user-li, .project-ul > .user-li").on("click", function (e) {
             e.preventDefault();
             e.stopPropagation();
@@ -177,8 +147,11 @@
             if(e.metaKey || e.ctrlKey || e.shiftKey) {
                 window.location = location;
             } else {
-                window.open(location, '_blank');
+                window.open(location, 'mainFrame');
             }
+
+            $(".user-ul > .user-li, .project-ul > .user-li").removeClass("selected");
+            $(this).addClass("selected");
         });
 
       $(".org-list > .star-org").on("click", function toggleOrgFavorite(e) {
Add a comment
List