Commit c5a67f5d authored by Yiming Liu's avatar Yiming Liu

Merge pull request #145 from lepdou/lepdou_master

add miss envs
parents 536eb044 6698804e
...@@ -27,5 +27,4 @@ public class API { ...@@ -27,5 +27,4 @@ public class API {
public String getAdminServiceHost(Env env) { public String getAdminServiceHost(Env env) {
return serviceLocator.getAdminService(env).getHomepageUrl(); return serviceLocator.getAdminService(env).getHomepageUrl();
} }
} }
...@@ -12,6 +12,7 @@ import com.ctrip.apollo.core.dto.AppDTO; ...@@ -12,6 +12,7 @@ import com.ctrip.apollo.core.dto.AppDTO;
import com.ctrip.apollo.core.enums.Env; import com.ctrip.apollo.core.enums.Env;
import com.ctrip.apollo.core.exception.BadRequestException; import com.ctrip.apollo.core.exception.BadRequestException;
import com.ctrip.apollo.core.utils.StringUtils; import com.ctrip.apollo.core.utils.StringUtils;
import com.ctrip.apollo.portal.entity.AppInfoVO;
import com.ctrip.apollo.portal.entity.ClusterNavTree; import com.ctrip.apollo.portal.entity.ClusterNavTree;
import com.ctrip.apollo.portal.service.AppService; import com.ctrip.apollo.portal.service.AppService;
...@@ -25,7 +26,7 @@ public class AppController { ...@@ -25,7 +26,7 @@ public class AppController {
private AppService appService; private AppService appService;
@RequestMapping("/env/{env}") @RequestMapping("/envs/{env}")
public List<AppDTO> findAllApp(@PathVariable String env){ public List<AppDTO> findAllApp(@PathVariable String env){
if (StringUtils.isEmpty(env)){ if (StringUtils.isEmpty(env)){
throw new BadRequestException("env can not be empty"); throw new BadRequestException("env can not be empty");
...@@ -42,17 +43,21 @@ public class AppController { ...@@ -42,17 +43,21 @@ public class AppController {
return appService.buildClusterNavTree(appId); return appService.buildClusterNavTree(appId);
} }
@RequestMapping(value = "", method = RequestMethod.POST, consumes = {"application/json"}) @RequestMapping(value = "/envs/{env}", method = RequestMethod.POST, consumes = {"application/json"})
public ResponseEntity<Void> create(@RequestBody AppDTO app) { public ResponseEntity<Void> create(@PathVariable String env, @RequestBody AppDTO app) {
if (isInvalidApp(app)){ if (isInvalidApp(app)){
throw new BadRequestException("request payload contains empty"); throw new BadRequestException("request payload contains empty");
} }
appService.save(app); if ("ALL".equals(env)){
appService.save(app);
} else {
appService.save(Env.valueOf(env), app);
}
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@RequestMapping(value = "/{appId}", method = RequestMethod.GET) @RequestMapping(value = "/{appId}", method = RequestMethod.GET)
public AppDTO load(@PathVariable String appId){ public AppInfoVO load(@PathVariable String appId){
if (StringUtils.isEmpty(appId)){ if (StringUtils.isEmpty(appId)){
throw new BadRequestException("app id can not be empty."); throw new BadRequestException("app id can not be empty.");
} }
......
package com.ctrip.apollo.portal.entity;
import com.ctrip.apollo.core.dto.AppDTO;
import com.ctrip.apollo.core.enums.Env;
import java.util.List;
public class AppInfoVO {
private AppDTO app;
/**
* 在创建app的时候可能在某些环境下创建失败
*/
private List<Env> missEnvs;
public AppDTO getApp() {
return app;
}
public void setApp(AppDTO app) {
this.app = app;
}
public List<Env> getMissEnvs() {
return missEnvs;
}
public void setMissEnvs(List<Env> missEnvs) {
this.missEnvs = missEnvs;
}
}
package com.ctrip.apollo.portal.service; package com.ctrip.apollo.portal.service;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -17,6 +19,7 @@ import com.ctrip.apollo.core.exception.BadRequestException; ...@@ -17,6 +19,7 @@ import com.ctrip.apollo.core.exception.BadRequestException;
import com.ctrip.apollo.core.exception.ServiceException; import com.ctrip.apollo.core.exception.ServiceException;
import com.ctrip.apollo.portal.PortalSettings; import com.ctrip.apollo.portal.PortalSettings;
import com.ctrip.apollo.portal.api.AdminServiceAPI; import com.ctrip.apollo.portal.api.AdminServiceAPI;
import com.ctrip.apollo.portal.entity.AppInfoVO;
import com.ctrip.apollo.portal.entity.ClusterNavTree; import com.ctrip.apollo.portal.entity.ClusterNavTree;
@Service @Service
...@@ -37,16 +40,19 @@ public class AppService { ...@@ -37,16 +40,19 @@ public class AppService {
return appAPI.findApps(env); return appAPI.findApps(env);
} }
public AppDTO load(String appId) { public AppInfoVO load(String appId) {
//轮询环境直到能找到此app的信息 //轮询环境直到能找到此app的信息
AppDTO app = null; AppDTO app = null;
List<Env> missEnvs = new LinkedList<>();
for (Env env : portalSettings.getEnvs()) { for (Env env : portalSettings.getEnvs()) {
try { try {
app = appAPI.loadApp(env, appId); app = appAPI.loadApp(env, appId);
break;
} catch (HttpClientErrorException e) { } catch (HttpClientErrorException e) {
//not exist maybe because create app fail. //not exist maybe because create app fail.
if (e.getStatusCode() == HttpStatus.NOT_FOUND) { if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
missEnvs.add(env);
logger.warn("app:{} in {} not exist", appId, env); logger.warn("app:{} in {} not exist", appId, env);
} else { } else {
logger.error("load app info({}) from env:{} error.", appId, env); logger.error("load app info({}) from env:{} error.", appId, env);
...@@ -54,11 +60,15 @@ public class AppService { ...@@ -54,11 +60,15 @@ public class AppService {
} }
} }
} }
if (app == null){ if (app == null) {
throw new BadRequestException(String.format("invalid app id %s", appId)); throw new BadRequestException(String.format("invalid app id %s", appId));
} }
return app; AppInfoVO appInfo = new AppInfoVO();
appInfo.setApp(app);
appInfo.setMissEnvs(missEnvs);
return appInfo;
} }
...@@ -86,4 +96,13 @@ public class AppService { ...@@ -86,4 +96,13 @@ public class AppService {
} }
} }
public void save(Env env, AppDTO app) {
try {
appAPI.save(env, app);
} catch (HttpStatusCodeException e) {
logger.error(ExceptionUtils.toString(e));
throw e;
}
}
} }
...@@ -79,6 +79,7 @@ ...@@ -79,6 +79,7 @@
<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/AppUtils.js"></script>
<script type="application/javascript" src="scripts/controller/IndexController.js"></script> <script type="application/javascript" src="scripts/controller/IndexController.js"></script>
</body> </body>
</html> </html>
appUtil.service('AppUtil', [function () {
return {
errorMsg: function (response) {
var msg = "Code:" + response.status;
if (response.data.message != null){
msg += " Msg:" + response.data.message;
}
return msg;
}
}
}]);
/**service module 定义*/ /**service module 定义*/
var appService = angular.module('app.service', ['ngResource']); var appService = angular.module('app.service', ['ngResource']);
/**utils*/
var appUtil = angular.module('app.util', []);
/** page module 定义*/ /** page module 定义*/
// 首页 // 首页
var index_module = angular.module('index', ['toastr', 'app.service', 'angular-loading-bar']); var index_module = angular.module('index', ['toastr', 'app.service', 'app.util', 'angular-loading-bar']);
//项目主页 //项目主页
var application_module = angular.module('application', ['app.service', 'toastr', 'angular-loading-bar']); var application_module = angular.module('application', ['app.service', 'app.util', 'toastr', 'angular-loading-bar']);
//创建项目页面 //创建项目页面
var create_app_module = angular.module('create_app', ['ngResource', 'toastr', 'app.service', 'angular-loading-bar']); var create_app_module = angular.module('create_app', ['ngResource', 'toastr', 'app.service', 'app.util', 'angular-loading-bar']);
......
create_app_module.controller('CreateAppController', ['$scope', '$window', 'toastr', 'AppService', create_app_module.controller('CreateAppController', ['$scope', '$window', 'toastr', 'AppService', 'AppUtil',
function ($scope, $window, toastr, AppService) { function ($scope, $window, toastr, AppService, AppUtil) {
$scope.save = function () { $scope.create = function () {
AppService.add($scope.app).then(function (result) { AppService.create('ALL', $scope.app).then(function (result) {
toastr.success('添加成功!'); toastr.success('添加成功!');
setInterval(function () { setInterval(function () {
$window.location.href = '/views/app.html?#appid=' + result.appId; $window.location.href = '/views/app.html?#appid=' + result.appId;
}, 1000); }, 1000);
}, function (result) { }, function (result) {
toastr.error(result.status + result.data.message, '添加失败!'); toastr.error(AppUtil.errorMsg(result), '添加失败!');
}); });
}; };
......
index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppService', 'EnvService', index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppService', 'AppUtil', 'EnvService',
function ($scope, $window, toastr, AppService, EnvService) { function ($scope, $window, toastr, AppService, AppUtil, EnvService) {
$scope.envs = []; $scope.envs = [];
$scope.selectedEnv = ''; $scope.selectedEnv = '';
...@@ -8,7 +8,7 @@ index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppS ...@@ -8,7 +8,7 @@ index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppS
//default select first env //default select first env
$scope.switchEnv($scope.envs[0]); $scope.switchEnv($scope.envs[0]);
}, function (result) { }, function (result) {
toastr.error(result.status + result.data.message, "load env error"); toastr.error(AppUtil.errorMsg(result), "load env error");
}); });
var apps = []; var apps = [];
...@@ -25,7 +25,7 @@ index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppS ...@@ -25,7 +25,7 @@ index_module.controller('IndexController', ['$scope', '$window', 'toastr', 'AppS
$scope.appsCount = apps.length; $scope.appsCount = apps.length;
$scope.selectedEnv = env; $scope.selectedEnv = env;
}, function (result) { }, function (result) {
toastr.error(result.status + result.data.message, "load apps error"); toastr.error(AppUtil.errorMsg(result), "load apps error");
}); });
}; };
......
application_module.controller("AppConfigController", application_module.controller("AppConfigController",
['$scope', '$location', 'toastr', 'AppService', 'ConfigService', ['$scope', '$location', 'toastr', 'AppService', 'AppUtil', 'ConfigService',
function ($scope, $location, toastr, AppService, ConfigService) { function ($scope, $location, toastr, AppService, AppUtil, ConfigService) {
var appId = $location.$$url.split("=")[1]; var appId = $location.$$url.split("=")[1];
var currentUser = 'test_user'; var currentUser = 'test_user';
...@@ -12,7 +12,7 @@ application_module.controller("AppConfigController", ...@@ -12,7 +12,7 @@ application_module.controller("AppConfigController",
$scope.pageContext = pageContext; $scope.pageContext = pageContext;
///////////// load cluster nav tree ///////// ////// load cluster nav tree //////
AppService.load_nav_tree($scope.pageContext.appId).then(function (result) { AppService.load_nav_tree($scope.pageContext.appId).then(function (result) {
var navTree = []; var navTree = [];
...@@ -58,18 +58,20 @@ application_module.controller("AppConfigController", ...@@ -58,18 +58,20 @@ application_module.controller("AppConfigController",
} }
}); });
}, function (result) { }, function (result) {
toastr.error(result.status + result.data.message, "加载导航出错"); toastr.error(AppUtil.errorMsg(result), "加载导航出错");
}); });
/////////// app info //////////// ////// app info //////
AppService.load($scope.pageContext.appId).then(function (result) { AppService.load($scope.pageContext.appId).then(function (result) {
$scope.appInfo = result; $scope.appBaseInfo = result.app;
$scope.missEnvs = result.missEnvs;
$scope.selectedEnvs = angular.copy($scope.missEnvs);
},function (result) { },function (result) {
toastr.error(result.status + result.data.message, "加载App信息出错"); toastr.error(AppUtil.errorMsg(result), "加载App信息出错");
}); });
/////////// namespace //////////// ////// namespace //////
var namespace_view_type = { var namespace_view_type = {
TEXT:'text', TEXT:'text',
...@@ -103,11 +105,11 @@ application_module.controller("AppConfigController", ...@@ -103,11 +105,11 @@ application_module.controller("AppConfigController",
} }
}, function (result) { }, function (result) {
toastr.error(result.status + result.data.message, "加载配置信息出错"); toastr.error(AppUtil.errorMsg(result), "加载配置信息出错");
}); });
} }
////////////global view oper ///////////// ////// global view oper //////
$scope.switchView = function (namespace, viewType) { $scope.switchView = function (namespace, viewType) {
...@@ -138,7 +140,7 @@ application_module.controller("AppConfigController", ...@@ -138,7 +140,7 @@ application_module.controller("AppConfigController",
return result; return result;
} }
////////// text view oper ///////// ////// text view oper //////
$scope.draft = {}; $scope.draft = {};
//保存草稿 //保存草稿
...@@ -161,7 +163,7 @@ application_module.controller("AppConfigController", ...@@ -161,7 +163,7 @@ application_module.controller("AppConfigController",
$scope.toggleTextEditStatus($scope.draft); $scope.toggleTextEditStatus($scope.draft);
}, function (result) { }, function (result) {
toastr.error(result.status + result.data.message, "更新失败"); toastr.error(AppUtil.errorMsg(result), "更新失败");
} }
); );
...@@ -169,6 +171,7 @@ application_module.controller("AppConfigController", ...@@ -169,6 +171,7 @@ application_module.controller("AppConfigController",
$scope.isItemsViewOpened = true; $scope.isItemsViewOpened = true;
$scope.toggleItemView = function (isOpened) { $scope.toggleItemView = function (isOpened) {
$scope.isItemsViewOpened = isOpened; $scope.isItemsViewOpened = isOpened;
}; };
...@@ -185,7 +188,7 @@ application_module.controller("AppConfigController", ...@@ -185,7 +188,7 @@ application_module.controller("AppConfigController",
} }
}; };
////////// table view oper ///////// ////// table view oper //////
//查看旧值 //查看旧值
$scope.queryOldValue = function (key, oldValue) { $scope.queryOldValue = function (key, oldValue) {
...@@ -215,11 +218,47 @@ application_module.controller("AppConfigController", ...@@ -215,11 +218,47 @@ application_module.controller("AppConfigController",
refreshNamespaces(); refreshNamespaces();
}, function (result) { }, function (result) {
toastr.error(result.status + result.data.message, "发布失败"); toastr.error(AppUtil.errorMsg(result), "发布失败");
} }
); );
} }
////// create env //////
$scope.toggleSelection = function toggleSelection(env) {
var idx = $scope.selectedEnvs.indexOf(env);
// is currently selected
if (idx > -1) {
$scope.selectedEnvs.splice(idx, 1);
}
// is newly selected
else {
$scope.selectedEnvs.push(env);
}
};
$scope.createEnvs = function () {
var count = 0;
$scope.selectedEnvs.forEach(function (env) {
AppService.create(env, $scope.appBaseInfo).then(function (result) {
toastr.success(env, '创建成功');
count ++;
if (count == $scope.selectedEnvs){
$route.reload();
}
}, function (result) {
toastr.error(AppUtil.errorMsg(result), '创建失败:' + env);
count ++;
if (count == $scope.selectedEnvs){
$route.reload();
}
});
});
};
}]); }]);
...@@ -3,7 +3,7 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { ...@@ -3,7 +3,7 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
find_all_app:{ find_all_app:{
method: 'GET', method: 'GET',
isArray: true, isArray: true,
url:'/apps/env/:env' url:'/apps/envs/:env'
}, },
load_navtree:{ load_navtree:{
methode: 'GET', methode: 'GET',
...@@ -14,9 +14,9 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { ...@@ -14,9 +14,9 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
method: 'GET', method: 'GET',
isArray: false isArray: false
}, },
add_app: { create_app: {
method: 'POST', method: 'POST',
url: '/apps' url: '/apps/envs/:env'
} }
}); });
return { return {
...@@ -42,9 +42,9 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) { ...@@ -42,9 +42,9 @@ appService.service('AppService', ['$resource', '$q', function ($resource, $q) {
}); });
return d.promise; return d.promise;
}, },
add: function (app) { create: function (env, app) {
var d = $q.defer(); var d = $q.defer();
app_resource.add_app({}, app, function (result) { app_resource.create_app({env:env}, app, function (result) {
d.resolve(result); d.resolve(result);
}, function (result) { }, function (result) {
d.reject(result); d.reject(result);
......
...@@ -16,6 +16,21 @@ a { ...@@ -16,6 +16,21 @@ a {
cursor: pointer; cursor: pointer;
} }
.i-20{
height: 20px;
width: 20px;
}
.i-25-20{
height: 20px;
width: 25px;
}
.i-15{
height: 15px;
width: 15px;
}
.apollo-container { .apollo-container {
min-height: 90%; min-height: 90%;
} }
...@@ -122,6 +137,12 @@ table th { ...@@ -122,6 +137,12 @@ table th {
font-weight: 300; font-weight: 300;
} }
.project-info th {
text-align: right;
padding: 4px 6px;
white-space: nowrap;
}
.project-info td { .project-info td {
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
......
...@@ -28,35 +28,71 @@ ...@@ -28,35 +28,71 @@
<!--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"/> 应用信息
<span class="tools pull-right"> <span class="tools pull-right">
<a href="javascript:;" class="icon-chevron-down"></a> <a href="javascript:;" class="icon-chevron-down"></a>
</span> </span>
</header> </header>
<div class="panel-body"> <div class="panel-body">
<table class="project-info"> <table class="project-info">
<tbody> <tbody>
<tr> <tr>
<th>应用ID:</th> <th>应用ID:</th>
<td>{{appInfo.appId}}</td> <td>{{appBaseInfo.appId}}</td>
</tr> </tr>
<tr> <tr>
<th>应用名:</th> <th>应用名:</th>
<td>{{appInfo.name}}</td> <td>{{appBaseInfo.name}}</td>
</tr> </tr>
<tr> <tr>
<th>Owner:</th> <th>Owner:</th>
<td>{{appInfo.ownerName}}</td> <td>{{appBaseInfo.ownerName}}</td>
</tr> </tr>
<tr> <tr>
<th>Owner Email:</th> <th>Owner Email:</th>
<td>{{appInfo.ownerEmail}}</td> <td>{{appBaseInfo.ownerEmail}}</td>
</tr>
<tr ng-show="missEnvs.length > 0">
<th>缺失的环境:</th>
<td>
<font ng-repeat="env in missEnvs">
{{env}}
</font>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</section> </section>
<a class="list-group-item" data-toggle="modal" data-target="#createEnvModal" ng-show="missEnvs.length > 0">
<div class="row">
<div class="col-md-2"><img src="../img/plus.png" class="i-20"></div>
<div class="col-md-7 hidden-xs">
<p class="apps-description">添加环境</p>
</div>
</div>
</a>
<a class="list-group-item" target="_blank" href="/views/app.html?#/appid={{app.appId}}">
<div class="row">
<div class="col-md-2"><img src="../img/plus.png" class="i-20"></div>
<div class="col-md-7 hidden-xs">
<p class="apps-description">添加集群</p>
</div>
</div>
</a>
<a class="list-group-item" target="_blank" href="/views/app.html?#/appid={{app.appId}}">
<div class="row">
<div class="col-md-2"><img src="../img/plus.png" class="i-20"></div>
<div class="col-md-7 hidden-xs">
<p class="apps-description">添加Namespace</p>
</div>
</div>
</a>
</section>
</div> </div>
<div class="col-md-9 config-item-container"> <div class="col-md-9 config-item-container">
...@@ -65,12 +101,14 @@ ...@@ -65,12 +101,14 @@
<div class="panel"> <div class="panel">
<header class="panel-heading"> <header class="panel-heading">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-3">
<img src="../img/close.png" class="i-15" ng-show="!isItemsViewOpened"/>
<img src="../img/open.png" class="i-15" ng-show="isItemsViewOpened"/>
<b>{{namespace.namespace.namespaceName}}</b> <b>{{namespace.namespace.namespaceName}}</b>
<span class="label label-info" ng-show="namespace.itemModifiedCnt > 0">有修改,可发布 <span class="label label-info" ng-show="namespace.itemModifiedCnt > 0">有修改,可发布
<span class="badge">{{namespace.itemModifiedCnt}}</span></span> <span class="badge">{{namespace.itemModifiedCnt}}</span></span>
</div> </div>
<div class="col-md-7"> <div class="col-md-8">
<div class="btn-toolbar" role="toolbar" aria-label="..."> <div class="btn-toolbar" role="toolbar" aria-label="...">
<div class="btn-group" role="group" aria-label="..."> <div class="btn-group" role="group" aria-label="...">
<button type="button" data-toggle="modal" data-target="#releaseModal" <button type="button" data-toggle="modal" data-target="#releaseModal"
...@@ -120,7 +158,7 @@ ...@@ -120,7 +158,7 @@
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</a> </a>
<a data-toggle="tooltip" data-placement="top" title="修改配置" <a data-toggle="tooltip" data-placement="top" title="修改配置"
ng-show="!namespace.isTextEditing && namespace.viewType == 'text'" ng-show="!namespace.isTextEditing && namespace.viewType == 'text' && isItemsViewOpened"
ng-click="toggleTextEditStatus(namespace)"> ng-click="toggleTextEditStatus(namespace)">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
</a> </a>
...@@ -134,7 +172,8 @@ ...@@ -134,7 +172,8 @@
</header> </header>
<!--text view--> <!--text view-->
<textarea class="form-control" rows="30" ng-show="isItemsViewOpened && namespace.viewType == 'text'" <textarea class="form-control" rows="30"
ng-show="isItemsViewOpened && namespace.viewType == 'text'"
ng-disabled="!namespace.isTextEditing" ng-model="namespace.text"> ng-disabled="!namespace.isTextEditing" ng-model="namespace.text">
{{namespace.text}} {{namespace.text}}
</textarea> </textarea>
...@@ -145,7 +184,7 @@ ...@@ -145,7 +184,7 @@
ng-show="isItemsViewOpened && namespace.viewType == 'table'"> ng-show="isItemsViewOpened && namespace.viewType == 'table'">
<thead> <thead>
<tr> <tr>
<th > <th>
Key Key
</th> </th>
<th> <th>
...@@ -164,7 +203,8 @@ ...@@ -164,7 +203,8 @@
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="config in namespace.items" ng-class="{warning:config.modified}" ng-if="config.item.key"> <tr ng-repeat="config in namespace.items" ng-class="{warning:config.modified}"
ng-if="config.item.key">
<td width="25%"> <td width="25%">
{{config.item.key}} {{config.item.key}}
</td> </td>
...@@ -175,7 +215,7 @@ ...@@ -175,7 +215,7 @@
ng-show="config.modified" ng-show="config.modified"
ng-click="queryOldValue(config.item.key, config.oldValue)"></button> ng-click="queryOldValue(config.item.key, config.oldValue)"></button>
{{config.item.value}} {{config.item.value}}
</td > </td>
<td width="20%"> <td width="20%">
{{config.item.comment}} {{config.item.comment}}
</td> </td>
...@@ -192,7 +232,8 @@ ...@@ -192,7 +232,8 @@
</div> </div>
<!--历史修改视图--> <!--历史修改视图-->
<div class="J_historyview history-view" ng-show="isItemsViewOpened && namespace.viewType == 'history'"> <div class="J_historyview history-view"
ng-show="isItemsViewOpened && namespace.viewType == 'history'">
<div class="row"> <div class="row">
<div class="col-md-11 col-md-offset-1 list" style=""> <div class="col-md-11 col-md-offset-1 list" style="">
<div class="media"> <div class="media">
...@@ -244,39 +285,40 @@ ...@@ -244,39 +285,40 @@
</div> </div>
<!-- view old value Modal --> <!-- view old value Modal -->
<div class="modal fade " id="oldValueModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal fade " id="oldValueModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm" role="document"> <div class="modal-dialog modal-sm" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header panel-primary"> <div class="modal-header panel-primary">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">旧值</h4> <h4 class="modal-title">旧值</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
{{OldValue}} {{OldValue}}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- commit modify config modal--> <!-- commit modify config modal-->
<div class="modal fade" id="commitModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel2"> <div class="modal fade" id="commitModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header panel-primary"> <div class="modal-header panel-primary">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel2">Commit changes</h4> <h4 class="modal-title">Commit changes</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<textarea rows="4" class="form-control" style="width:570px;" placeholder="input change log...." <textarea rows="4" class="form-control" style="width:570px;" placeholder="input change log...."
ng-model="commitComment"></textarea> ng-model="commitComment"></textarea>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="commitChange()"> <button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="commitChange()">
提交 提交
</button> </button>
...@@ -285,26 +327,57 @@ ...@@ -285,26 +327,57 @@
</div> </div>
</div> </div>
<!--createRelease modal--> <!--create release modal-->
<div class="modal fade" id="releaseModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel3"> <div class="modal fade" id="releaseModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header panel-primary"> <div class="modal-header panel-primary">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button> aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel3">发布</h4> <h4 class="modal-title">发布</h4>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<textarea rows="4" class="form-control" style="width:570px;" ng-model="releaseComment" <textarea rows="4" class="form-control" style="width:570px;" ng-model="releaseComment"
placeholder="input release log...."></textarea> placeholder="input release log...."></textarea>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="release()">提交 <button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="release()">提交
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!--create env modal-->
<div class="modal fade" id="createEnvModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header panel-primary">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title">添加环境</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label>请选择环境:</label>
<div class="checkbox" ng-repeat="env in missEnvs">
<label>
<input type="checkbox" name="selectedEnvs[]" value="{{env}}"
ng-checked="selectedEnvs.indexOf(env) > -1" ng-click="toggleSelection(env)">{{env}}
</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="createEnvs()">添加
</button>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
...@@ -339,6 +412,7 @@ ...@@ -339,6 +412,7 @@
<!--service--> <!--service-->
<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/ConfigService.js"></script> <script type="application/javascript" src="../scripts/services/ConfigService.js"></script>
<script type="application/javascript" src="../scripts/AppUtils.js"></script>
<!--controller--> <!--controller-->
<script type="application/javascript" src="../scripts/controller/app/AppConfigController.js"></script> <script type="application/javascript" src="../scripts/controller/app/AppConfigController.js"></script>
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
</header> </header>
<div class="panel-body"> <div class="panel-body">
<form class="form-horizontal" ng-controller="CreateAppController" ng-submit="save()"> <form class="form-horizontal" ng-controller="CreateAppController" ng-submit="create()">
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label"><font style="color: red">*</font> 应用ID</label> <label class="col-sm-2 control-label"><font style="color: red">*</font> 应用ID</label>
<div class="col-sm-3"> <div class="col-sm-3">
...@@ -81,6 +81,8 @@ ...@@ -81,6 +81,8 @@
<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/AppUtils.js"></script>
<script type="application/javascript" src="../scripts/controller/CreateAppController.js"></script> <script type="application/javascript" src="../scripts/controller/CreateAppController.js"></script>
</body> </body>
</html> </html>
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