Commit f5dd22eb authored by Jason Song's avatar Jason Song Committed by GitHub

Merge pull request #426 from lepdou/index_page_refactor

refactor index page. add favorites function module
parents 3fc0afd9 4805b4d6
package com.ctrip.framework.apollo.portal.controller; package com.ctrip.framework.apollo.portal.controller;
import com.google.common.collect.Sets;
import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.App;
import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.http.MultiResponseEntity; import com.ctrip.framework.apollo.common.http.MultiResponseEntity;
...@@ -17,12 +19,15 @@ import com.ctrip.framework.apollo.portal.service.UserService; ...@@ -17,12 +19,15 @@ import com.ctrip.framework.apollo.portal.service.UserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpClientErrorException;
...@@ -46,8 +51,19 @@ public class AppController { ...@@ -46,8 +51,19 @@ public class AppController {
private UserService userService; private UserService userService;
@RequestMapping("") @RequestMapping("")
public List<App> findAllApp() { public List<App> findApps(@RequestParam(value = "appIds", required = false) String appIds) {
return appService.findAll(); if (StringUtils.isEmpty(appIds)){
return appService.findAll();
}else {
return appService.findByAppIds(Sets.newHashSet(appIds.split(",")));
}
}
@RequestMapping("/by-owner")
public List<App> findAppsByOwner(@RequestParam("owner") String owner, Pageable page){
return appService.findByOwnerName(owner, page);
} }
@RequestMapping("/{appId}/navtree") @RequestMapping("/{appId}/navtree")
......
package com.ctrip.framework.apollo.portal.controller;
import com.ctrip.framework.apollo.portal.entity.po.Favorite;
import com.ctrip.framework.apollo.portal.service.FavoriteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class FavoriteController {
@Autowired
private FavoriteService favoriteService;
@RequestMapping(value = "/favorites", method = RequestMethod.POST)
public Favorite addFavorite(@RequestBody Favorite favorite) {
return favoriteService.addFavorite(favorite);
}
@RequestMapping("/favorites")
public List<Favorite> findFavorites(@RequestParam(value = "userId", required = false) String userId,
@RequestParam(value = "appId", required = false) String appId,
Pageable page) {
return favoriteService.search(userId, appId, page);
}
@RequestMapping(value = "/favorites/{favoriteId}", method = RequestMethod.DELETE)
public void deleteFavorite(@PathVariable long favoriteId) {
favoriteService.deleteFavorite(favoriteId);
}
@RequestMapping(value = "/favorites/{favoriteId}", method = RequestMethod.PUT)
public void toTop(@PathVariable long favoriteId) {
favoriteService.adjustFavoriteToFirst(favoriteId);
}
}
package com.ctrip.framework.apollo.portal.entity.po;
import com.ctrip.framework.apollo.common.entity.BaseEntity;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "Favorite")
@SQLDelete(sql = "Update Favorite set isDeleted = 1 where id = ?")
@Where(clause = "isDeleted = 0")
public class Favorite extends BaseEntity {
@Column(name = "AppId", nullable = false)
private String appId;
@Column(name = "UserId", nullable = false)
private String userId;
@Column(name = "Position")
private long position;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public long getPosition() {
return position;
}
public void setPosition(long position) {
this.position = position;
}
}
package com.ctrip.framework.apollo.portal.entity.po; package com.ctrip.framework.apollo.portal.entity.po;
public class UserInfo { public class UserInfo {
private String userId; private String userId;
private String name; private String name;
private String email; private String email;
...@@ -28,4 +29,20 @@ public class UserInfo { ...@@ -28,4 +29,20 @@ public class UserInfo {
public void setEmail(String email) { public void setEmail(String email) {
this.email = email; this.email = email;
} }
@Override
public boolean equals(Object o) {
if (o instanceof UserInfo) {
if (o == this){
return true;
}
UserInfo anotherUser = (UserInfo) o;
return userId.equals(anotherUser.userId);
} else {
return false;
}
}
} }
...@@ -2,11 +2,19 @@ package com.ctrip.framework.apollo.portal.repository; ...@@ -2,11 +2,19 @@ package com.ctrip.framework.apollo.portal.repository;
import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.entity.App;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
import java.util.Set;
public interface AppRepository extends PagingAndSortingRepository<App, Long> { public interface AppRepository extends PagingAndSortingRepository<App, Long> {
App findByAppId(String appId); App findByAppId(String appId);
List<App> findByOwnerName(String ownerName, Pageable page);
List<App> findByAppIdIn(Set<String> appIds);
} }
package com.ctrip.framework.apollo.portal.repository;
import com.ctrip.framework.apollo.portal.entity.po.Favorite;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
public interface FavoriteRepository extends PagingAndSortingRepository<Favorite, Long> {
List<Favorite> findByUserIdOrderByPositionAscDataChangeCreatedTimeAsc(String userId, Pageable page);
List<Favorite> findByAppIdOrderByPositionAscDataChangeCreatedTimeAsc(String appId, Pageable page);
Favorite findFirst1ByUserIdOrderByPositionAscDataChangeCreatedTimeAsc(String userId);
Favorite findByUserIdAndAppId(String userId, String appId);
}
...@@ -18,12 +18,14 @@ import com.dianping.cat.Cat; ...@@ -18,12 +18,14 @@ import com.dianping.cat.Cat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.HttpStatusCodeException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
@Service @Service
public class AppService { public class AppService {
...@@ -54,6 +56,14 @@ public class AppService { ...@@ -54,6 +56,14 @@ public class AppService {
return Lists.newArrayList((apps)); return Lists.newArrayList((apps));
} }
public List<App> findByAppIds(Set<String> appIds){
return appRepository.findByAppIdIn(appIds);
}
public List<App> findByOwnerName(String ownerName, Pageable page){
return appRepository.findByOwnerName(ownerName, page);
}
public App load(String appId) { public App load(String appId) {
App app = appRepository.findByAppId(appId); App app = appRepository.findByAppId(appId);
if (app == null) { if (app == null) {
......
package com.ctrip.framework.apollo.portal.service;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
import com.ctrip.framework.apollo.portal.entity.po.Favorite;
import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
import com.ctrip.framework.apollo.portal.repository.FavoriteRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@Service
public class FavoriteService {
public static final long POSITION_DEFAULT = 10000;
@Autowired
private UserInfoHolder userInfoHolder;
@Autowired
private FavoriteRepository favoriteRepository;
@Autowired
private UserService userService;
public Favorite addFavorite(Favorite favorite) {
UserInfo user = userService.findByUserId(favorite.getUserId());
if (user == null) {
throw new BadRequestException("user not exist");
}
UserInfo loginUser = userInfoHolder.getUser();
//user can only add himself favorite app
if (!loginUser.equals(user)) {
throw new BadRequestException("add favorite fail. "
+ "because favorite's user is not current login user.");
}
Favorite checkedFavorite = favoriteRepository.findByUserIdAndAppId(loginUser.getUserId(), favorite.getAppId());
if (checkedFavorite != null) {
return checkedFavorite;
}
favorite.setPosition(POSITION_DEFAULT);
favorite.setDataChangeCreatedBy(user.getUserId());
favorite.setDataChangeLastModifiedBy(user.getUserId());
return favoriteRepository.save(favorite);
}
public List<Favorite> search(String userId, String appId, Pageable page) {
boolean isUserIdEmpty = StringUtils.isEmpty(userId);
boolean isAppIdEmpty = StringUtils.isEmpty(appId);
if (isAppIdEmpty && isUserIdEmpty) {
throw new BadRequestException("user id and app id can't be empty at the same time");
}
//search by userId
if (isAppIdEmpty && !isUserIdEmpty) {
return favoriteRepository.findByUserIdOrderByPositionAscDataChangeCreatedTimeAsc(userId, page);
}
//search by appId
if (!isAppIdEmpty && isUserIdEmpty) {
return favoriteRepository.findByAppIdOrderByPositionAscDataChangeCreatedTimeAsc(appId, page);
}
//search by userId and appId
return Arrays.asList(favoriteRepository.findByUserIdAndAppId(userId, appId));
}
public void deleteFavorite(long favoriteId) {
Favorite favorite = favoriteRepository.findOne(favoriteId);
checkUserOperatePermission(favorite);
favoriteRepository.delete(favorite);
}
public void adjustFavoriteToFirst(long favoriteId) {
Favorite favorite = favoriteRepository.findOne(favoriteId);
checkUserOperatePermission(favorite);
String userId = favorite.getUserId();
Favorite firstFavorite = favoriteRepository.findFirst1ByUserIdOrderByPositionAscDataChangeCreatedTimeAsc(userId);
long minPosition = firstFavorite.getPosition();
favorite.setPosition(minPosition - 1);
favoriteRepository.save(favorite);
}
private void checkUserOperatePermission(Favorite favorite) {
if (favorite == null) {
throw new BadRequestException("favorite not exist");
}
if (!Objects.equals(userInfoHolder.getUser().getUserId(), favorite.getUserId())) {
throw new BadRequestException("can not operate other person's favorite");
}
}
}
...@@ -86,7 +86,6 @@ ...@@ -86,7 +86,6 @@
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular/angular-route.min.js"></script>
<script src="vendor/angular/angular-resource.min.js"></script> <script src="vendor/angular/angular-resource.min.js"></script>
<script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script> <script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="vendor/angular/loading-bar.min.js"></script> <script src="vendor/angular/loading-bar.min.js"></script>
......
...@@ -106,7 +106,6 @@ ...@@ -106,7 +106,6 @@
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular/angular-route.min.js"></script>
<script src="vendor/angular/angular-resource.min.js"></script> <script src="vendor/angular/angular-resource.min.js"></script>
<script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script> <script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="vendor/angular/loading-bar.min.js"></script> <script src="vendor/angular/loading-bar.min.js"></script>
......
...@@ -31,13 +31,31 @@ ...@@ -31,13 +31,31 @@
</div> </div>
<div class="J_appFound hidden col-md-3 col-xs-3 col-sm-3" ng-show="!notFoundApp"> <div class="J_appFound hidden col-md-3 col-xs-3 col-sm-3" ng-show="!notFoundApp">
<div id="treeview"></div> <section class="panel">
<header class="panel-heading">
<img src="img/env.png" class="i-20">&nbsp;环境列表
<span class="pull-right"
data-tooltip="tooltip" data-placement="bottom" title="通过切换环境、集群来管理不同环境、集群的配置">
<img src="img/question.png" class="i-20"/>
</span>
</header>
<div id="treeview" class="no-radius"></div>
</section>
<!--app info--> <!--app info-->
<section class="panel"> <section class="panel">
<header class="panel-heading"> <header class="panel-heading">
<img src="img/info.png" class="i-25-20"/> 应用信息 <img src="img/info.png" class="i-25-20"/> 项目信息
<span class="tools pull-right"> <span class="pull-right cursor-pointer">
<a href="javascript:;" class="icon-chevron-down"></a> <a ng-if="!favoriteId" ng-click="addFavorite()"
data-tooltip="tooltip" data-placement="bottom" title="收藏">
<img src="img/unlike.png" class="i-20"/>
</a>
<a ng-if="favoriteId" ng-click="deleteFavorite()"
data-tooltip="tooltip" data-placement="bottom" title="取消收藏">
<img src="img/like.png" class="i-20"/>
</a>
</span> </span>
</header> </header>
<div class="panel-body"> <div class="panel-body">
...@@ -525,7 +543,6 @@ ...@@ -525,7 +543,6 @@
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular/angular-ui-router.min.js"></script>
<script src="vendor/angular/angular-resource.min.js"></script> <script src="vendor/angular/angular-resource.min.js"></script>
<script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script> <script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="vendor/angular/loading-bar.min.js"></script> <script src="vendor/angular/loading-bar.min.js"></script>
...@@ -556,6 +573,7 @@ ...@@ -556,6 +573,7 @@
<script type="application/javascript" src="scripts/services/CommitService.js"></script> <script type="application/javascript" src="scripts/services/CommitService.js"></script>
<script type="application/javascript" src="scripts/services/NamespaceLockService.js"></script> <script type="application/javascript" src="scripts/services/NamespaceLockService.js"></script>
<script type="application/javascript" src="scripts/services/InstanceService.js"></script> <script type="application/javascript" src="scripts/services/InstanceService.js"></script>
<script type="application/javascript" src="scripts/services/FavoriteService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script> <script type="application/javascript" src="scripts/AppUtils.js"></script>
......
...@@ -97,7 +97,6 @@ ...@@ -97,7 +97,6 @@
<!--angular--> <!--angular-->
<script src="../vendor/angular/angular.min.js"></script> <script src="../vendor/angular/angular.min.js"></script>
<script src="../vendor/angular/angular-route.min.js"></script>
<script src="../vendor/angular/angular-resource.min.js"></script> <script src="../vendor/angular/angular-resource.min.js"></script>
<script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script> <script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="../vendor/angular/loading-bar.min.js"></script> <script src="../vendor/angular/loading-bar.min.js"></script>
......
...@@ -233,7 +233,6 @@ ...@@ -233,7 +233,6 @@
<!--angular--> <!--angular-->
<script src="../vendor/angular/angular.min.js"></script> <script src="../vendor/angular/angular.min.js"></script>
<script src="../vendor/angular/angular-route.min.js"></script>
<script src="../vendor/angular/angular-resource.min.js"></script> <script src="../vendor/angular/angular-resource.min.js"></script>
<script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script> <script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="../vendor/angular/loading-bar.min.js"></script> <script src="../vendor/angular/loading-bar.min.js"></script>
......
...@@ -13,55 +13,97 @@ ...@@ -13,55 +13,97 @@
<title>apollo</title> <title>apollo</title>
</head> </head>
<body ng-controller="IndexController"> <body>
<div class="site-notice"><label>当前站点支持</label><label ng-repeat="env in envs" ng-bind="env" style="margin-left: 5px;"></label> <apollonav></apollonav>
环境
</div>
<header class="site-header jumbotron">
<div class="container">
<div class="row">
<div class="col-xs-12"><h1>Apollo</h1>
<p>携程统一配置中心<br>
<span class="package-amount">共收录了 <strong ng-bind="appsCount"></strong> 个项目</span>
<a class="btn btn-success" href="app.html">创建项目</a>
</p>
<form class="" role="search">
<div class="form-group"><input type="text" class="form-control search clearable"
placeholder="搜索App, 例如:apollo" ng-model="searchKey"
ng-change="search()"></div>
</form>
</div>
</div>
</div>
</header> <div id="app-list" ng-controller="IndexController">
<div class="container-fluid apollo-container"> <section class="media create-app-list">
<div class="list-group apps"> <aside class="media-left text-center">
<a class="package list-group-item" href="config.html?#/appid={{app.appId}}" <h5>我的项目</h5>
ng-repeat="app in apps "> </aside>
<div class="row"> <aside class="media-body">
<div class="col-md-3"><h4 class="apps-name" ng-bind="app.appId"></h4></div> <div class="col-md-2 text-center" ng-click="goToCreateAppPage()">
<div class="col-md-7 hidden-xs"> <div href="#" class="thumbnail create-btn hover cursor-pointer">
<p class="apps-description" ng-bind="app.name"></p> <img src="img/plus-white.png"/>
<h5>创建项目</h5>
</div>
</div>
<div class="col-md-2 text-center" ng-repeat="app in createdApps" ng-click="goToAppHomePage(app.appId)">
<div href="#" class="thumbnail hover cursor-pointer">
<h4 ng-bind="app.appId"></h4>
<h5 ng-bind="app.name"></h5>
</div>
</div>
<div class="col-md-2 text-center" ng-show="hasMoreCreatedApps"
ng-click="getUserCreatedApps()">
<div href="#" class="thumbnail hover cursor-pointer">
<img class="more-img" src="img/more.png"/>
<h5>加载更多</h5>
</div> </div>
<div class="col-md-2"> </div>
<p class="apps-description"> </aside>
<span ng-bind="app.ownerName"></span> </section>
<br>
<span ng-bind="app.ownerEmail"></span> <section class="media favorites-app-list">
<aside class="media-left text-center">
<h5>收藏的项目</h5>
</aside>
<aside class="media-body">
<div class="app-panel col-md-2 text-center"
ng-repeat="app in favorites"
ng-click="goToAppHomePage(app.appId)"
ng-mouseover="toggleOperationBtn(app)"
ng-mouseout="toggleOperationBtn(app)">
<div class="thumbnail hover">
<h4 ng-bind="app.appId"></h4>
<h5 ng-bind="app.name"></h5>
<p class="operate-panel" ng-show="app.showOperationBtn">
<button class="btn btn-default btn-xs" title="置顶"
ng-click="toTop(app.favoriteId);$event.stopPropagation();">
<img src="img/top.png" class="i-15">
</button>
<button class="btn btn-default btn-xs" title="取消收藏"
ng-click="deleteFavorite(app.favoriteId);$event.stopPropagation();">
<img src="img/like.png" class="i-15">
</button>
</p> </p>
</div>
</div>
<div class="col-md-2 text-center" ng-show="hasMoreFavorites"
ng-click="getUserFavorites()">
<div href="#" class="thumbnail hover cursor-pointer">
<img class="more-img" src="img/more.png"/>
<h5>加载更多</h5>
</div>
</div>
<div class="no-favorites text-center" ng-show="!favorites || favorites.length == 0">
<h4>您还没有收藏过任何项目,在项目主页可以收藏项目哟~</h4>
</div>
</aside>
</section>
<section class="media visit-app-list" ng-show="visitedApps && visitedApps.length">
<aside class="media-left text-center">
<h5>最近浏览的项目</h5>
</aside>
<aside class="media-body">
<div class="app-panel col-md-2 text-center"
ng-repeat="app in visitedApps"
ng-click="goToAppHomePage(app.appId)">
<div class="thumbnail hover">
<h4 ng-bind="app.appId"></h4>
<h5 ng-bind="app.name"></h5>
</div> </div>
</div> </div>
</a> </aside>
</div> </section>
</div> </div>
<div ng-include="'views/common/footer.html'"></div> <div ng-include="'views/common/footer.html'"></div>
<!--angular--> <!--angular-->
...@@ -82,7 +124,11 @@ ...@@ -82,7 +124,11 @@
<script type="application/javascript" src="scripts/app.js"></script> <script type="application/javascript" src="scripts/app.js"></script>
<script type="application/javascript" src="scripts/services/AppService.js"></script> <script type="application/javascript" src="scripts/services/AppService.js"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script> <script type="application/javascript" src="scripts/services/EnvService.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/services/FavoriteService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script> <script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/directive/directive.js"></script>
<script type="application/javascript" src="scripts/controller/IndexController.js"></script> <script type="application/javascript" src="scripts/controller/IndexController.js"></script>
</body> </body>
......
...@@ -107,7 +107,6 @@ ...@@ -107,7 +107,6 @@
<!--angular--> <!--angular-->
<script src="../vendor/angular/angular.min.js"></script> <script src="../vendor/angular/angular.min.js"></script>
<script src="../vendor/angular/angular-route.min.js"></script>
<script src="../vendor/angular/angular-resource.min.js"></script> <script src="../vendor/angular/angular-resource.min.js"></script>
<script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script> <script src="../vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="../vendor/angular/loading-bar.min.js"></script> <script src="../vendor/angular/loading-bar.min.js"></script>
......
...@@ -9,7 +9,7 @@ var directive_module = angular.module('apollo.directive', ['app.service', 'app.u ...@@ -9,7 +9,7 @@ var directive_module = angular.module('apollo.directive', ['app.service', 'app.u
/** page module 定义*/ /** page module 定义*/
// 首页 // 首页
var index_module = angular.module('index', ['toastr', 'app.service', 'app.util', 'angular-loading-bar']); var index_module = angular.module('index', ['toastr', 'app.service', 'apollo.directive', 'app.util', 'angular-loading-bar']);
//项目主页 //项目主页
var application_module = angular.module('application', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr']); var application_module = angular.module('application', ['app.service', 'apollo.directive', 'app.util', 'toastr', 'angular-loading-bar', 'valdr']);
//创建项目页面 //创建项目页面
......
index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppService', 'AppUtil', 'EnvService', index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppUtil', 'AppService',
function ($scope, $window, toastr, AppService, AppUtil, EnvService) { 'UserService', 'FavoriteService',
IndexController]);
$scope.envs = [];
$scope.selectedEnv = ''; function IndexController($scope, $window, toastr, AppUtil, AppService, UserService, FavoriteService) {
EnvService.find_all_envs().then(function (result) {
$scope.envs = result; $scope.userId = '';
//default select first env
$scope.switchEnv($scope.envs[0]); $scope.getUserCreatedApps = getUserCreatedApps;
}, function (result) { $scope.getUserFavorites = getUserFavorites;
toastr.error(AppUtil.errorMsg(result), "load env error");
}); $scope.goToAppHomePage = goToAppHomePage;
$scope.goToCreateAppPage = goToCreateAppPage;
$scope.toggleOperationBtn = toggleOperationBtn;
$scope.toTop = toTop;
$scope.switchEnv = function (env) { $scope.deleteFavorite = deleteFavorite;
$scope.selectedEnv = env;
loadApps(env); UserService.load_user().then(function (result) {
}; $scope.userId = result.userId;
var sourceApps = []; $scope.createdAppPage = 0;
$scope.createdApps = [];
function loadApps(env){ $scope.hasMoreCreatedApps = true;
AppService.find_all_app(env).then(function (result) { $scope.favoritesPage = 0;
sourceApps = sortApps(result); $scope.favorites = [];
$scope.apps = sourceApps; $scope.hasMoreFavorites = true;
$scope.appsCount = sourceApps.length; $scope.visitedApps = [];
$scope.selectedEnv = env;
}, function (result) { getUserCreatedApps();
toastr.error(AppUtil.errorMsg(result), "load apps error");
}); getUserFavorites();
}
initUserVisitedApps();
var VISITED_APPS_STORAGE_KEY = "VisitedApps"; });
//访问过的App放在列表最前面,方便用户选择
function sortApps(sourceApps) { function getUserCreatedApps() {
var visitedApps = JSON.parse(localStorage.getItem(VISITED_APPS_STORAGE_KEY)); var size = 10;
if (!visitedApps){ AppService.find_app_by_owner($scope.userId, $scope.createdAppPage, size)
return sourceApps; .then(function (result) {
$scope.createdAppPage += 1;
$scope.hasMoreCreatedApps = result.length == size;
if (!result || result.length == 0) {
return;
} }
var existedVisitedAppsMap = {}; result.forEach(function (app) {
visitedApps.forEach(function (app) { $scope.createdApps.push(app);
existedVisitedAppsMap[app] = true;
}); });
var sortedApps = []; })
sourceApps.forEach(function (app) { }
if (existedVisitedAppsMap[app.appId]){
sortedApps.push(app); function getUserFavorites() {
} var size = 11;
}); FavoriteService.findFavorites($scope.userId, '', $scope.favoritesPage, size)
sourceApps.forEach(function (app) { .then(function (result) {
if (!existedVisitedAppsMap[app.appId]){ $scope.favoritesPage += 1;
sortedApps.push(app); $scope.hasMoreFavorites = result.length == size;
}
if (!result || result.length == 0) {
return;
}
var appIds = [];
result.forEach(function (favorite) {
appIds.push(favorite.appId);
}); });
return sortedApps;
} AppService.find_apps(appIds.join(","))
.then(function (apps) {
$scope.search = function () { //sort
var key = $scope.searchKey.toLocaleLowerCase(); var appIdMapApp = {};
if (key == '') { apps.forEach(function (app) {
$scope.apps = sourceApps; appIdMapApp[app.appId] = app;
return; });
} result.forEach(function (favorite) {
var result = []; var app = appIdMapApp[favorite.appId];
sourceApps.forEach(function (item) { app.favoriteId = favorite.id;
if (item.appId.toLocaleLowerCase().indexOf(key) >= 0 || $scope.favorites.push(app);
item.name.toLocaleLowerCase().indexOf(key) >= 0) { });
result.push(item); });
} })
}
function initUserVisitedApps() {
var VISITED_APPS_STORAGE_KEY = "VisitedAppsV2";
var visitedAppsObject = JSON.parse(localStorage.getItem(VISITED_APPS_STORAGE_KEY));
if (!visitedAppsObject) {
visitedAppsObject = {};
}
var userVisitedApps = visitedAppsObject[$scope.userId];
if (userVisitedApps && userVisitedApps.length > 0) {
AppService.find_apps(userVisitedApps.join(","))
.then(function (apps) {
apps.forEach(function (app) {
$scope.visitedApps.push(app);
}); });
});
}
}
function goToCreateAppPage() {
$window.location.href = "/app.html";
}
function goToAppHomePage(appId) {
$window.location.href = "/config.html?#/appid=" + appId;
}
function toggleOperationBtn(app) {
app.showOperationBtn = !app.showOperationBtn;
}
function toTop(favoriteId) {
FavoriteService.toTop(favoriteId).then(function () {
toastr.success("置顶成功");
reload();
})
}
function deleteFavorite(favoriteId) {
FavoriteService.deleteFavorite(favoriteId).then(function () {
toastr.success("取消收藏成功");
reload();
})
}
function reload() {
setTimeout(function () {
$window.location.reload();
}, 500);
$scope.apps = result; }
};
}]); }
application_module.controller("ConfigBaseInfoController", application_module.controller("ConfigBaseInfoController",
['$rootScope', '$scope', '$location', 'toastr', 'AppService', 'PermissionService', ['$rootScope', '$scope', '$location', 'toastr', 'UserService', 'AppService',
'FavoriteService',
'PermissionService',
'AppUtil', ConfigBaseInfoController]); 'AppUtil', ConfigBaseInfoController]);
function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppService, PermissionService, function ConfigBaseInfoController($rootScope, $scope, $location, toastr, UserService, AppService, FavoriteService,
AppUtil) { PermissionService,
AppUtil) {
var appId = AppUtil.parseParams($location.$$url).appid; var appId = AppUtil.parseParams($location.$$url).appid;
$rootScope.hideTip = JSON.parse(localStorage.getItem("hideTip")); initPage();
//save user recent visited apps function initPage() {
var VISITED_APPS_STORAGE_KEY = "VisitedApps"; $rootScope.hideTip = JSON.parse(localStorage.getItem("hideTip"));
var visitedApps = JSON.parse(localStorage.getItem(VISITED_APPS_STORAGE_KEY));
var hasSaved = false; //load session storage to recovery scene
if (visitedApps) { var scene = JSON.parse(sessionStorage.getItem(appId));
visitedApps.forEach(function (app) { $rootScope.pageContext = {
if (app == appId) { appId: appId,
hasSaved = true; env: scene ? scene.env : '',
return; clusterName: scene ? scene.cluster : 'default'
} };
UserService.load_user().then(function (result) {
$rootScope.pageContext.userId = result.userId;
handleFavorite();
recordVisitApp();
}); });
} else {
visitedApps = []; loadAppInfo();
handlePermission();
} }
if (!hasSaved) {
visitedApps.push(appId);
localStorage.setItem(VISITED_APPS_STORAGE_KEY, function recordVisitApp() {
JSON.stringify(visitedApps)); //save user recent visited apps
var VISITED_APPS_STORAGE_KEY = "VisitedAppsV2";
var visitedAppsObject = JSON.parse(localStorage.getItem(VISITED_APPS_STORAGE_KEY));
var hasSaved = false;
if (visitedAppsObject) {
var visitedApps = visitedAppsObject[$rootScope.pageContext.userId];
if (visitedApps && visitedApps.length > 0){
visitedApps.forEach(function (app) {
if (app == appId) {
hasSaved = true;
return;
}
});
}
} else {
visitedAppsObject = {};
visitedAppsObject[$rootScope.pageContext.userId] = [];
}
var currentUserVisitedApps = visitedAppsObject[$rootScope.pageContext.userId];
if (!hasSaved) {
//if queue's length bigger than 6 will remove oldest app
if (currentUserVisitedApps.length >= 6){
currentUserVisitedApps.splice(0, 1);
}
visitedAppsObject[$rootScope.pageContext.userId].push($rootScope.pageContext.appId);
localStorage.setItem(VISITED_APPS_STORAGE_KEY,
JSON.stringify(visitedAppsObject));
}
} }
//load session storage to recovery scene function loadAppInfo() {
var scene = JSON.parse(sessionStorage.getItem(appId)); $scope.notFoundApp = true;
AppService.load($rootScope.pageContext.appId).then(function (result) {
$scope.notFoundApp = false;
var pageContext = { $scope.appBaseInfo = result;
appId: appId, $scope.appBaseInfo.orgInfo = result.orgName + '(' + result.orgId + ')';
env: scene ? scene.env : '',
clusterName: scene ? scene.cluster : 'default'
};
$rootScope.pageContext = pageContext; loadNavTree();
$scope.notFoundApp = true; $(".J_appFound").removeClass("hidden");
////// app info ////// }, function (result) {
AppService.load($rootScope.pageContext.appId).then(function (result) { $(".J_appNotFound").removeClass("hidden");
$scope.notFoundApp = false; });
$scope.appBaseInfo = result; ////// 补缺失的环境 //////
$scope.appBaseInfo.orgInfo = result.orgName + '(' + result.orgId + ')'; $scope.missEnvs = [];
AppService.find_miss_envs($rootScope.pageContext.appId).then(function (result) {
$scope.missEnvs = AppUtil.collectData(result);
}, function (result) {
loadNavTree(); });
$(".J_appFound").removeClass("hidden"); $scope.createAppInMissEnv = function () {
}, function (result) { var count = 0;
$(".J_appNotFound").removeClass("hidden"); $scope.missEnvs.forEach(function (env) {
}); AppService.create_remote(env, $scope.appBaseInfo).then(function (result) {
toastr.success(env, '创建成功');
count++;
if (count == $scope.missEnvs.length) {
location.reload(true);
}
}, function (result) {
toastr.error(AppUtil.errorMsg(result), '创建失败:' + env);
count++;
if (count == $scope.missEnvs.length) {
location.reload(true);
}
});
});
};
}
function loadNavTree() { function loadNavTree() {
AppService.load_nav_tree($rootScope.pageContext.appId).then(function (result) { AppService.load_nav_tree($rootScope.pageContext.appId).then(function (result) {
...@@ -66,12 +122,12 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ ...@@ -66,12 +122,12 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ
return; return;
} }
//default first env if session storage is empty //default first env if session storage is empty
if (!pageContext.env) { if (!$rootScope.pageContext.env) {
pageContext.env = nodes[0].env; $rootScope.pageContext.env = nodes[0].env;
} }
$rootScope.refreshNamespaces(); $rootScope.refreshNamespaces();
nodes.forEach(function (env, envIdx) { nodes.forEach(function (env) {
if (!env.clusters || env.clusters.length == 0) { if (!env.clusters || env.clusters.length == 0) {
return; return;
} }
...@@ -82,7 +138,7 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ ...@@ -82,7 +138,7 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ
//如果env下面只有一个default集群则不显示集群列表 //如果env下面只有一个default集群则不显示集群列表
if (env.clusters && env.clusters.length == 1 && env.clusters[0].name if (env.clusters && env.clusters.length == 1 && env.clusters[0].name
== 'default') { == 'default') {
if (pageContext.env == env.env) { if ($rootScope.pageContext.env == env.env) {
node.state = {}; node.state = {};
node.state.selected = true; node.state.selected = true;
} }
...@@ -90,12 +146,12 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ ...@@ -90,12 +146,12 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ
} else { } else {
node.selectable = false; node.selectable = false;
//cluster list //cluster list
env.clusters.forEach(function (cluster, clusterIdx) { env.clusters.forEach(function (cluster) {
var clusterNode = {}, var clusterNode = {},
parentNode = []; parentNode = [];
//default selection from session storage or first env & first cluster //default selection from session storage or first env & first cluster
if (pageContext.env == env.env && pageContext.clusterName if ($rootScope.pageContext.env == env.env && $rootScope.pageContext.clusterName
== cluster.name) { == cluster.name) {
clusterNode.state = {}; clusterNode.state = {};
clusterNode.state.selected = true; clusterNode.state.selected = true;
...@@ -168,54 +224,66 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ ...@@ -168,54 +224,66 @@ function ConfigBaseInfoController($rootScope, $scope, $location, toastr, AppServ
}); });
} }
////// 补缺失的环境 ////// function handleFavorite() {
$scope.missEnvs = [];
AppService.find_miss_envs($rootScope.pageContext.appId).then(function (result) { FavoriteService.findFavorites($rootScope.pageContext.userId,
$scope.missEnvs = AppUtil.collectData(result); $rootScope.pageContext.appId)
}, function (result) { .then(function (result) {
if (result && result.length) {
}); $scope.favoriteId = result[0].id;
$scope.createAppInMissEnv = function () {
var count = 0;
$scope.missEnvs.forEach(function (env) {
AppService.create_remote(env, $scope.appBaseInfo).then(function (result) {
toastr.success(env, '创建成功');
count++;
if (count == $scope.missEnvs.length) {
location.reload(true);
}
}, function (result) {
toastr.error(AppUtil.errorMsg(result), '创建失败:' + env);
count++;
if (count == $scope.missEnvs.length) {
location.reload(true);
} }
}); });
});
};
//permission $scope.addFavorite = function () {
PermissionService.has_create_namespace_permission(appId).then(function (result) { var favorite = {
$scope.hasCreateNamespacePermission = result.hasPermission; userId: $rootScope.pageContext.userId,
}, function (result) { appId: $rootScope.pageContext.appId
};
FavoriteService.addFavorite(favorite)
.then(function (result) {
$scope.favoriteId = result.id;
toastr.success("收藏成功");
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "收藏失败");
})
};
$scope.deleteFavorite = function () {
FavoriteService.deleteFavorite($scope.favoriteId)
.then(function (result) {
$scope.favoriteId = 0;
toastr.success("取消收藏成功");
}, function (result) {
toastr.error(AppUtil.errorMsg(result), "取消收藏失败");
})
};
}
function handlePermission() {
//permission
PermissionService.has_create_namespace_permission(appId).then(function (result) {
$scope.hasCreateNamespacePermission = result.hasPermission;
}, function (result) {
}); });
PermissionService.has_create_cluster_permission(appId).then(function (result) { PermissionService.has_create_cluster_permission(appId).then(function (result) {
$scope.hasCreateClusterPermission = result.hasPermission; $scope.hasCreateClusterPermission = result.hasPermission;
}, function (result) { }, function (result) {
}); });
PermissionService.has_assign_user_permission(appId).then(function (result) { PermissionService.has_assign_user_permission(appId).then(function (result) {
$scope.hasAssignUserPermission = result.hasPermission; $scope.hasAssignUserPermission = result.hasPermission;
}, function (result) { }, function (result) {
}); });
$scope.showMasterPermissionTips = function () { $scope.showMasterPermissionTips = function () {
$("#masterNoPermissionDialog").modal('show'); $("#masterNoPermissionDialog").modal('show');
};
} }
} }
......
...@@ -10,7 +10,7 @@ directive_module.directive('apollonav', function ($compile, $window, toastr, App ...@@ -10,7 +10,7 @@ directive_module.directive('apollonav', function ($compile, $window, toastr, App
scope.sourceApps = []; scope.sourceApps = [];
scope.copyedApps = []; scope.copyedApps = [];
AppService.find_all_app().then(function (result) { AppService.find_apps().then(function (result) {
result.forEach(function (app) { result.forEach(function (app) {
app.selected = false; app.selected = false;
scope.sourceApps.push(app); scope.sourceApps.push(app);
......
appService.service('AppService', ['$resource', '$q', function ($resource, $q) { appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
var app_resource = $resource('/apps/:appId', {}, { var app_resource = $resource('/apps/:appId', {}, {
find_all_app:{ find_apps: {
method: 'GET', method: 'GET',
isArray: true, isArray: true,
url:'/apps' url: '/apps'
},
find_app_by_owner: {
method: 'GET',
isArray: true,
url: '/apps/by-owner'
}, },
load_navtree:{ load_navtree: {
methode: 'GET', methode: 'GET',
isArray:false, isArray: false,
url:'/apps/:appId/navtree' url: '/apps/:appId/navtree'
}, },
load_app: { load_app: {
method: 'GET', method: 'GET',
...@@ -28,24 +33,38 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { ...@@ -28,24 +33,38 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
} }
}); });
return { return {
find_all_app: function () { find_apps: function (appIds) {
if (!appIds) {
appIds = '';
}
var d = $q.defer(); var d = $q.defer();
app_resource.find_all_app({ app_resource.find_apps({appIds: appIds}, function (result) {
}, function (result) {
d.resolve(result); d.resolve(result);
}, function (result) { }, function (result) {
d.reject(result); d.reject(result);
}); });
return d.promise; return d.promise;
}, },
load_nav_tree: function (appId){ find_app_by_owner: function (owner, page, size) {
var d = $q.defer();
app_resource.find_app_by_owner({
owner: owner,
page: page,
size: size
}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
load_nav_tree: function (appId) {
var d = $q.defer(); var d = $q.defer();
app_resource.load_navtree({ app_resource.load_navtree({
appId: appId appId: appId
}, function(result){ }, function (result) {
d.resolve(result); d.resolve(result);
}, function(result){ }, function (result) {
d.reject(result); d.reject(result);
}); });
return d.promise; return d.promise;
...@@ -61,7 +80,7 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { ...@@ -61,7 +80,7 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
}, },
create_remote: function (env, app) { create_remote: function (env, app) {
var d = $q.defer(); var d = $q.defer();
app_resource.create_app_remote({env:env}, app, function (result) { app_resource.create_app_remote({env: env}, app, function (result) {
d.resolve(result); d.resolve(result);
}, function (result) { }, function (result) {
d.reject(result); d.reject(result);
...@@ -71,8 +90,8 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { ...@@ -71,8 +90,8 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
load: function (appId) { load: function (appId) {
var d = $q.defer(); var d = $q.defer();
app_resource.load_app({ app_resource.load_app({
appId: appId appId: appId
}, function (result) { }, function (result) {
d.resolve(result); d.resolve(result);
}, function (result) { }, function (result) {
d.reject(result); d.reject(result);
...@@ -82,7 +101,7 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { ...@@ -82,7 +101,7 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
find_miss_envs: function (appId) { find_miss_envs: function (appId) {
var d = $q.defer(); var d = $q.defer();
app_resource.find_miss_envs({ app_resource.find_miss_envs({
appId: appId appId: appId
}, function (result) { }, function (result) {
d.resolve(result); d.resolve(result);
}, function (result) { }, function (result) {
......
appService.service('FavoriteService', ['$resource', '$q', function ($resource, $q) {
var resource = $resource('', {}, {
find_favorites: {
method: 'GET',
url: '/favorites',
isArray: true
},
add_favorite: {
method: 'POST',
url: '/favorites'
},
delete_favorite: {
method: 'DELETE',
url: '/favorites/:favoriteId'
},
to_top: {
method: 'PUT',
url: '/favorites/:favoriteId'
}
});
return {
findFavorites: function (userId, appId, page, size) {
var d = $q.defer();
resource.find_favorites({
userId: userId,
appId: appId,
page: page,
size: size
}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
addFavorite: function (favorite) {
var d = $q.defer();
resource.add_favorite({}, favorite, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
deleteFavorite: function (favoriteId) {
var d = $q.defer();
resource.delete_favorite({
favoriteId: favoriteId
}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
},
toTop: function (favoriteId) {
var d = $q.defer();
resource.to_top({
favoriteId: favoriteId
}, {}, function (result) {
d.resolve(result);
}, function (result) {
d.reject(result);
});
return d.promise;
}
}
}]);
...@@ -67,7 +67,6 @@ ...@@ -67,7 +67,6 @@
<!--angular--> <!--angular-->
<script src="vendor/angular/angular.min.js"></script> <script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular/angular-route.min.js"></script>
<script src="vendor/angular/angular-resource.min.js"></script> <script src="vendor/angular/angular-resource.min.js"></script>
<script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script> <script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="vendor/angular/loading-bar.min.js"></script> <script src="vendor/angular/loading-bar.min.js"></script>
......
...@@ -25,23 +25,27 @@ p, td, span { ...@@ -25,23 +25,27 @@ p, td, span {
word-break: break-all; word-break: break-all;
} }
.no-radius { .no-radius {
border-radius: 0; border-radius: 0;
} }
.cursor-pointer{ .no-margin {
margin: 0;
}
.cursor-pointer {
cursor: pointer; cursor: pointer;
} }
pre { pre {
white-space: pre-wrap; /* Since CSS 2.1 */ white-space: pre-wrap; /* Since CSS 2.1 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */ white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */ white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */ word-wrap: break-word; /* Internet Explorer 5.5+ */
} }
.hover:hover{ .hover:hover {
background: #f5f5f5; background: #f5f5f5;
cursor: pointer cursor: pointer
} }
...@@ -75,7 +79,7 @@ pre { ...@@ -75,7 +79,7 @@ pre {
width: 15px; width: 15px;
} }
.badge{ .badge {
padding: 1px 4px; padding: 1px 4px;
} }
...@@ -89,7 +93,7 @@ pre { ...@@ -89,7 +93,7 @@ pre {
color: #0f0f0f; color: #0f0f0f;
} }
.panel-default > .panel-heading .badge{ .panel-default > .panel-heading .badge {
} }
...@@ -210,6 +214,14 @@ table th { ...@@ -210,6 +214,14 @@ table th {
min-width: 405px; min-width: 405px;
} }
#treeview .list-group{
margin: 0;
}
#treeview .list-group .list-group-item{
border: 0;
border-top: 1px solid #eff2f7;
}
.project-info th { .project-info th {
text-align: right; text-align: right;
padding: 4px 6px; padding: 4px 6px;
...@@ -225,11 +237,11 @@ table th { ...@@ -225,11 +237,11 @@ table th {
min-height: 500px; min-height: 500px;
} }
#itemModal .modal-dialog{ #itemModal .modal-dialog {
width: 860px; width: 860px;
} }
#itemModal .modal-body{ #itemModal .modal-body {
padding-bottom: 0; padding-bottom: 0;
} }
...@@ -350,12 +362,12 @@ table th { ...@@ -350,12 +362,12 @@ table th {
} }
.instance-view .btn-primary .badge{ .instance-view .btn-primary .badge {
color: #337ab7; color: #337ab7;
background-color: #fff; background-color: #fff;
} }
.instance-view .btn-default .badge{ .instance-view .btn-default .badge {
background: #777; background: #777;
color: #fff; color: #fff;
} }
...@@ -546,3 +558,64 @@ table th { ...@@ -546,3 +558,64 @@ table th {
font-size: 18px; font-size: 18px;
} }
/*index page*/
#app-list .media-body {
padding-top: 15px;
}
#app-list .media {
background: #fff;
display: table;
}
#app-list .media-left {
width: 1000px;
color: #fff;
display: table-cell;
vertical-align: middle;
}
#app-list .more-img {
width: 30px;
height: 30px;
}
#app-list .app-panel {
position: relative;
}
#app-list .operate-panel {
position: absolute;
top: 5px;
right: 20px;
}
.create-app-list .media-left {
background: #a9d96c;
}
.create-app-list .create-btn {
background: #a9d96c;
color: #fff
}
.create-app-list .create-btn:hover {
background: #81AB56;
}
.create-app-list .create-btn img {
width: 26px;
height: 26px
}
.favorites-app-list .media-left {
background: #57c8f2;
}
.favorites-app-list .no-favorites{
padding-bottom: 15px;
}
.visit-app-list .media-left {
background: #41cac0;
}
package com.ctrip.framework.apollo.portal.service;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.portal.AbstractIntegrationTest;
import com.ctrip.framework.apollo.portal.entity.po.Favorite;
import com.ctrip.framework.apollo.portal.repository.FavoriteRepository;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.jdbc.Sql;
import java.util.List;
public class FavoriteServiceTest extends AbstractIntegrationTest {
@Autowired
private FavoriteService favoriteService;
@Autowired
private FavoriteRepository favoriteRepository;
private String testUser = "apollo";
@Test
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testAddNormalFavorite() {
String testApp = "testApp";
Favorite favorite = instanceOfFavorite(testUser, testApp);
favoriteService.addFavorite(favorite);
List<Favorite> createdFavorites = favoriteService.search(testUser, testApp, new PageRequest(0, 10));
Assert.assertEquals(1, createdFavorites.size());
Assert.assertEquals(FavoriteService.POSITION_DEFAULT, createdFavorites.get(0).getPosition());
Assert.assertEquals(testUser, createdFavorites.get(0).getUserId());
Assert.assertEquals(testApp, createdFavorites.get(0).getAppId());
}
@Test(expected = BadRequestException.class)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testAddFavoriteErrorUser() {
String testApp = "testApp";
Favorite favorite = instanceOfFavorite("errorUser", testApp);
favoriteService.addFavorite(favorite);
}
@Test
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testSearchByUserId() {
List<Favorite> favorites = favoriteService.search(testUser, null, new PageRequest(0, 10));
Assert.assertEquals(4, favorites.size());
}
@Test
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testSearchByAppId() {
List<Favorite> favorites = favoriteService.search(null, "test0621-04", new PageRequest(0, 10));
Assert.assertEquals(3, favorites.size());
}
@Test
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testSearchByAppIdAndUserId() {
List<Favorite> favorites = favoriteService.search(testUser, "test0621-04", new PageRequest(0, 10));
Assert.assertEquals(1, favorites.size());
}
@Test(expected = BadRequestException.class)
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testSearchWithErrorParams() {
favoriteService.search(null, null, new PageRequest(0, 10));
}
@Test
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testDeleteFavorite() {
long legalFavoriteId = 21L;
favoriteService.deleteFavorite(legalFavoriteId);
Assert.assertNull(favoriteRepository.findOne(legalFavoriteId));
}
@Test(expected = BadRequestException.class)
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testDeleteFavoriteFail() {
long anotherPersonFavoriteId = 23L;
favoriteService.deleteFavorite(anotherPersonFavoriteId);
Assert.assertNull(favoriteRepository.findOne(anotherPersonFavoriteId));
}
@Test(expected = BadRequestException.class)
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testAdjustFavoriteError() {
long anotherPersonFavoriteId = 23;
favoriteService.adjustFavoriteToFirst(anotherPersonFavoriteId);
}
@Test
@Sql(scripts = "/sql/favorites/favorites.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testAdjustFavorite() {
long toAdjustFavoriteId = 20;
favoriteService.adjustFavoriteToFirst(toAdjustFavoriteId);
List<Favorite> favorites = favoriteService.search(testUser, null, new PageRequest(0, 10));
Favorite firstFavorite = favorites.get(0);
Favorite secondFavorite = favorites.get(1);
Assert.assertEquals(toAdjustFavoriteId, firstFavorite.getId());
Assert.assertEquals(firstFavorite.getPosition() + 1, secondFavorite.getPosition());
}
private Favorite instanceOfFavorite(String userId, String appId) {
Favorite favorite = new Favorite();
favorite.setAppId(appId);
favorite.setUserId(userId);
favorite.setDataChangeCreatedBy(userId);
favorite.setDataChangeLastModifiedBy(userId);
return favorite;
}
}
...@@ -3,4 +3,3 @@ spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy ...@@ -3,4 +3,3 @@ spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.show_sql=true
spring.h2.console.enabled = true spring.h2.console.enabled = true
spring.h2.console.settings.web-allow-others=true spring.h2.console.settings.web-allow-others=true
...@@ -3,3 +3,4 @@ delete from Role; ...@@ -3,3 +3,4 @@ delete from Role;
delete from RolePermission; delete from RolePermission;
delete from UserRole; delete from UserRole;
delete from AppNamespace; delete from AppNamespace;
DELETE FROM Favorite;
INSERT INTO `favorite` (`Id`, `UserId`, `AppId`, `Position`, `IsDeleted`, `DataChange_CreatedBy`, `DataChange_CreatedTime`, `DataChange_LastModifiedBy`, `DataChange_LastTime`)
VALUES
(18, 'apollo', 'test0621-03', 10000, 0, 'apollo', '2016-10-10 17:45:30', 'apollo', '2016-10-10 17:45:30'),
(19, 'apollo', '100003173', 9999, 0, 'apollo', '2016-10-10 17:45:42', 'apollo', '2016-10-10 17:51:12'),
(20, 'apollo', 'test0621-01', 10000, 00000000, 'apollo', '2016-10-10 17:50:57', 'apollo', '2016-10-10 17:50:57'),
(21, 'apollo', 'test0621-04', 10000, 00000000, 'apollo', '2016-10-10 17:55:03', 'apollo', '2016-10-10 17:55:03'),
(22, 'apollo2', 'test0621-04', 10000, 00000000, 'apollo', '2016-10-10 17:55:21', 'apollo', '2016-10-10 17:55:21'),
(23, 'apollo3', 'test0621-04', 10000, 00000000, 'apollo', '2016-10-10 17:55:21', 'apollo', '2016-10-10 17:55:21');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment